實現原理:
通過GPUImage濾鏡處理、錄製、保存的思路如圖。
視頻部分:經過filter的視頻幀分兩步,一步用於在屏幕預覽GPUImageView上顯示,另一步用於寫入GPUImageMovieWriter。
音頻部分:從GPUImageVideoCamera分離的音頻直接寫入GPUImageMovieWriter。另外,如果需要對音頻進行混響、變聲等處理,可以從這個節點分支處理寫入。
實現流程:
攝像頭
videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack];
videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
videoCamera.runBenchmark = YES;
濾鏡和預覽響應鏈
filter = [[GPUImageSaturationFilter alloc] init];
previewView = [[GPUImageView alloc] initWithFrame:self.view.frame];
previewView.fillMode = kGPUImageFillModePreserveAspectRatio;
self.view = previewView;
[videoCamera addTarget:filter];
[filter addTarget:previewView];
[videoCamera startCameraCapture];
錄入本地和保存
//開始
unlink([pathToMovie UTF8String]);
movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(480, 640)];
movieWriter.encodingLiveVideo = YES;
[filter addTarget:movieWriter];
videoCamera.audioEncodingTarget = movieWriter;
[movieWriter startRecording];
//結束
[filter removeTarget:movieWriter];
videoCamera.audioEncodingTarget = nil;
[movieWriter finishRecording];
[self saveVideoToLibrary:pathToMovie];//存入相冊方法
核心類:GPUImageMovieWriter
GPUImageMovieWriter實現了GPUImageInput,一般作爲響應鏈終點。
init方法
最終調用
- (id)initWithMovieURL:(NSURL *)newMovieURL size:(CGSize)newSize fileType:(NSString *)newFileType outputSettings:(NSMutableDictionary *)outputSettings;
方法裏重寫了void runSynchronouslyOnContextQueue(GPUImageContext *context, void (^block)(void))
方法。
錄製方法
//私有方法
1 - (void)initializeMovieWithOutputSettings:(NSDictionary *)outputSettings;
//公共方法
2 - (void)startRecording;
3 - (void)startRecordingInOrientation:(CGAffineTransform)orientationTransform;
4 - (void)finishRecording;
5 - (void)finishRecordingWithCompletionHandler:(void (^)(void))handler;
6 - (void)cancelRecording;
7 - (void)processAudioBuffer:(CMSampleBufferRef)audioBuffer;
8 - (void)enableSynchronizationCallbacks;
在私有方法中初始化了AVAssetWriter,傳入一個本地存儲地址和文件格式。
assetWriter = [[AVAssetWriter alloc] initWithURL:movieURL fileType:fileType error:&error];
2-6的方法無甚可說,基本就是調用AVAssetWriter的三個方法:
- startWriting
- cancelWriting
- finishWriting
還有finishRecording方法中對音頻和視頻AVAssetWriterInput調用的方法markAsFinished
第七個方法
- (void)processAudioBuffer:(CMSampleBufferRef)audioBuffer;
比較重要,在整個GPUImage中,只在兩種響應鏈起點GPUImageMovie和GPUImageVideoCamera中作爲audioEncodingTarget屬性調用過,這一部分也可以進行擴展,進行混音等操作。
幀渲染方法
//都是私有方法
- (void)createDataFBO;
- (void)destroyDataFBO;
- (void)setFilterFBO;
- (void)renderAtInternalSizeUsingFramebuffer:(GPUImageFramebuffer *)inputFramebufferToUse;
GPUImageInput協議方法
幾個存取方法
追加
** AVAssetWriterInputPixelBufferAdaptor**:
AVAssetWriterInputPixelBufferAdaptor負責將圖片轉成的緩存數據CVPixelBufferRef追加到AVAssetWriterInput中,(把CVPixelBufferRef視頻貞圖像拼接到視頻中)。
You use an AVAssetWriterInputPixelBufferAdaptor to append video samples packaged as CVPixelBuffer objects to a single AVAssetWriterInput object.//注意overview的部分