核心思路
通過GPUImageVideoCamera采集視頻和音頻的信息,音頻信息直接發送給GPUImageMovieWriter;視頻信息傳入響應鏈作為源頭,渲染后的視頻信息再寫入GPUImageMovieWriter,同時通過GPUImageView顯示在屏幕上。
具體細節
1、AV類
AVCaptureSession *_captureSession; 協調AV輸入設備到AVoutput的數據流
AVCaptureDevice *_inputCamera; 攝像頭設備
AVCaptureDevice *_microphone; 麥克風設備
AVCaptureDeviceInput *videoInput; 攝像頭輸入
AVCaptureVideoDataOutput *videoOutput; 攝像頭輸出
AVCaptureDeviceInput *audioInput; 麥克風輸入
AVCaptureAudioDataOutput *audioOutput; 麥克風輸出
AVAssetWriter *assetWriter; 把多媒體數據寫入文件的類
AVAssetWriterInput *assetWriterAudioInput; 音頻輸入
AVAssetWriterInput *assetWriterVideoInput; 視頻輸入
AVAssetWriterInputPixelBufferAdaptor sh*assetWriterPixelBufferInput; 視頻輸入適配器
2、流程圖
3、流程解析
1、找到物理設備攝像頭_inputCamera、麥克風_microphone,創建攝像頭輸入videoInput和麥克風輸入audioInput;
2、設置videoInput和audioInput為_captureSession的輸入,同時設置videoOutput和audioOutput為_captureSession的輸出,并且設置videoOutput和audioOutput的輸出delegate;
3、_captureSession調用startRunning,開始捕獲信號;
4、音頻數據到達,把數據轉發給之前設置的audioEncodingTarget,并通過調用assetWriterAudioInput的appendSampleBuffer方法寫入音頻數據;
5、視頻數據到達,視頻數據傳入響應鏈,經過處理后通過assetWriterPixelBufferInput的appendSampleBuffer方法寫入視頻數據;
6、選擇保存后,文件通過ALAssertLibrary寫入手機照片庫。
4、demo
- 初始化
// 攝像頭
_videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack];
_videoCamera.outputImageOrientation = [UIApplication sharedApplication].statusBarOrientation;
// 濾鏡
_filter = [[GPUImageSepiaFilter alloc] init];
_filterView = [[GPUImageView alloc] initWithFrame:self.view.frame];
self.view = _filterView;
// 響應鏈
[_videoCamera addTarget:_filter];
[_filter addTarget:_filterView];
[_videoCamera startCameraCapture];
- 開始錄制
unlink([pathToMovie UTF8String]); // 如果已經存在文件,AVAssetWriter會有異常,刪除舊文件
_movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(480.0, 640.0)];
_movieWriter.encodingLiveVideo = YES;
[_filter addTarget:_movieWriter];
_videoCamera.audioEncodingTarget = _movieWriter;
[_movieWriter startRecording];
- 結束錄制
[_filter removeTarget:_movieWriter];
_videoCamera.audioEncodingTarget = nil;
[_movieWriter finishRecording];
錄制后的視頻如下:
系統手機庫中的視頻:
思考
1、在流程圖的環節中,哪一步給視頻信息添加了濾鏡?
2、為何視頻的寫入類比音頻寫入類多了一個類?
總結
核心類是GPUImageMovieWriter,協調音頻和視頻信息的寫入。
- 思考題答案
1、GPUImageVideoCamera把攝像頭采集的YUV視頻幀,轉換為RGB視頻幀,同時作為響應鏈的起始點;GPUImageMovieWriter實現了GPUImageInput協議,可作為響應鏈的終點,接受濾鏡處理過的視頻信息。
2、AVAssetWriterInputPixelBufferAdaptor類提供了CVPixelBufferPool用來更快的分配緩存。