目錄
- 一、前言
- 二、方案一:AVCaptureSession + AVCaptureMovieFileOutput
- 1.創建AVCaptureSession
- 2.設定音頻、視頻輸入
- 3.設定檔案輸出源
- 4.添加視頻預覽層
- 5. 開始采集
- 6. 開始錄制
- 7.停止錄制
- 8.停止采集
- 三、方案二:AVCaptureSession + AVAssetWriter
一、前言
AVCaptureSession 是 AVFoundation 的核心類,用于管理捕獲物件 AVCaptureInput 的視頻和音頻的輸入,協調捕獲的輸出 AVCaptureOutput,
AVCaptureOutput 的輸出有兩種方法:
- 一種是直接以 movieFileUrl 方式輸出;
- 一種是以原始資料流 data 的方式輸出
流程對比圖如下:

下面詳細講解兩種錄制視頻的方案:
二、方案一:AVCaptureSession + AVCaptureMovieFileOutput
1.創建AVCaptureSession
//匯入 AVFoundation.framework
#import <AVFoundation/AVFoundation.h>
//宣告屬性
@property (nonatomic, strong) AVCaptureSession *captureSession;
//懶加載 AVCapturesession
- (AVCaptureSession *)captureSession {
if (!_captureSession) {
_captureSession = [[AVCaptureSession alloc] init];
//設定解析度
if ([_captureSession canSetSessionPreset:AVCaptureSessionPresetHigh]) {
[_captureSession setSessionPreset:AVCaptureSessionPresetHigh];
}
}
return _captureSession;
}
注意:AVCaptureSession 的呼叫是會阻塞執行緒的,建議單獨開辟子執行緒處理,
2.設定音頻、視頻輸入
//宣告屬性
@property (nonatomic, strong) AVCaptureDeviceInput *videoInput;
@property (nonatomic, strong) AVCaptureDeviceInput *audioInput;
//設定視頻,音頻輸入源
- (void)setCaptureDeviceInput {
//1. 視頻輸入源
//獲取視頻輸入設備, 默認后置攝像頭
AVCaptureDevice *videoCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
self.videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoCaptureDevice error:&error];
if ([self.captureSession canAddInput:self.videoInput]) {
[self.captureSession addInput:self.videoInput];
}
//2. 音頻輸入源
AVCaptureDevice *audioCaptureDevice = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio] firstObject];
self.audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioCaptureDevice error:&error];
if ([self.captureSession canAddInput:self.audioInput]) {
[self.captureSession addInput:self.audioInput];
}
}
3.設定檔案輸出源
//宣告屬性
@property (nonatomic, strong) AVCaptureMovieFileOutput *movieFileOutput;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer;
//設定檔案輸出源
- (void)setDeviceFileOutput {
//初始化檔案輸出物件
self.movieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
//捕獲會話中特定捕獲輸入物件和捕獲輸出物件之間的連接
AVCaptureConnection *captureConnection = [self.movieFileOutput connectionWithMediaType:AVMediaTypeVideo];
//設定防抖
if ([captureConnection isVideoStabilizationSupported]) {
captureConnection.preferredVideoStabilizationMode = AVCaptureVideoStabilizationModeAuto;
}
//預覽圖層和視頻方向保持一致
captureConnection.videoOrientation = [self.previewLayer connection].videoOrientation;
//添加檔案輸出源
if ([self.captureSession canAddOutput:self.movieFileOutput]) {
[self.captureSession addOutput:self.movieFileOutput];
}
}
4.添加視頻預覽層
- (void)setVideoPreviewLayer {
self.previewLayer.frame = [UIScreen mainScreen].bounds;
[self.superView.layer addSubLayer:self.previewLayer];
}
- (AVCaptureVideoPreviewLayer *)previewLayer {
if (!_previewLayer) {
_previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
_previewLayer.masksToBounds = YES;
_previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;//填充模式
}
return _previewLayer;
}
5. 開始采集
//宣告屬性
@property (nonatomic, strong) dispatch_queue_t sessionQueue;
//開始采集
- (void)startCapture {
self.sessionQueue = dispatch_queue_create("com.capturesession.queue", DISPATCH_QUEUE_CONCURRENT);
if (![self.captureSession isRunning]) {
__weak __typeof(self) weakSelf = self;
dispatch_async(self.sessionQueue, ^{
[weakSelf.captureSession startRunning];
});
}
}
6. 開始錄制
//開始錄制
- (void)startRecord {
[self.movieFileOutput startRecordingToOutputFileURL:[self createVideoPath] recordingDelegate:self];
}
當實際的錄制開始或停止時,系統會有代理回呼,當開始錄制之后,這時可能還沒有真正寫入,真正開始寫入會回呼下面代理,停止錄制也是如此,所以如果你需要對錄制視頻起始點操作,建議通過系統的回呼代理:
//實作協議 <AVCaptureFileOutputRecordingDelegate>中的方法
#pragma mark _ AVCaptureFileOutputRecordingDelegate
//起始點 - 開始錄制
- (void)captureOutput:(AVCaptureFileOutput *)output didStartRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray<AVCaptureConnection *> *)connections {
}
//結束錄制
-(void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error
{
NSLog(@"視頻錄制完成. 檔案路徑:%@",[outputFileURL absoluteString]);
}
7.停止錄制
//停止錄制
- (void)stopRecord {
if ([self.movieFileOutput isRecording]) {
[self.movieFileOutput stopRecording];
}
}
8.停止采集
//停止采集
- (void)stopCapture {
if ([self.captureSession isRunning]) {
__weak __typeof(self) weakSelf = self;
dispatch_async(self.sessionQueue, ^{
[weakSelf.captureSession stopRunning];
weakSelf.captureSession = nil;
});
}
}
三、方案二:AVCaptureSession + AVAssetWriter
方案二及更多內容,請訪問: 基于AVFoundation實作視頻錄制的兩種方式
本文來自博客園,作者:reyzhang,轉載請注明原文鏈接:https://www.cnblogs.com/reyzhang/p/16646673.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/503445.html
標籤:其他
下一篇:蘋果的app上架被黑了怎么辦?
