GPUImage(六):GPUImageMovieWriter 保存濾鏡處理過(guò)的視頻

GPUImage保存濾鏡視頻.png

實(shí)現(xiàn)原理:

通過(guò)GPUImage濾鏡處理、錄制、保存的思路如圖。
視頻部分:經(jīng)過(guò)filter的視頻幀分兩步,一步用于在屏幕預(yù)覽GPUImageView上顯示,另一步用于寫入GPUImageMovieWriter。
音頻部分:從GPUImageVideoCamera分離的音頻直接寫入GPUImageMovieWriter。另外,如果需要對(duì)音頻進(jìn)行混響、變聲等處理,可以從這個(gè)節(jié)點(diǎn)分支處理寫入。

實(shí)現(xiàn)流程:

攝像頭

videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack];
videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
videoCamera.runBenchmark = YES;

濾鏡和預(yù)覽響應(yīng)鏈

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];

錄入本地和保存

//開(kāi)始
unlink([pathToMovie UTF8String]);
movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(480, 640)];
movieWriter.encodingLiveVideo = YES;

[filter addTarget:movieWriter];
videoCamera.audioEncodingTarget = movieWriter;

[movieWriter startRecording];

//結(jié)束
 [filter removeTarget:movieWriter];
videoCamera.audioEncodingTarget = nil;
[movieWriter finishRecording];

[self saveVideoToLibrary:pathToMovie];//存入相冊(cè)方法

核心類:GPUImageMovieWriter

GPUImageMovieWriter實(shí)現(xiàn)了GPUImageInput,一般作為響應(yīng)鏈終點(diǎn)。

init方法

最終調(diào)用

- (id)initWithMovieURL:(NSURL *)newMovieURL size:(CGSize)newSize fileType:(NSString *)newFileType outputSettings:(NSMutableDictionary *)outputSettings;

方法里重寫了void runSynchronouslyOnContextQueue(GPUImageContext *context, void (^block)(void))方法。

錄制方法

AVAssetWriter應(yīng)用原理.png
//私有方法
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,傳入一個(gè)本地存儲(chǔ)地址和文件格式。
assetWriter = [[AVAssetWriter alloc] initWithURL:movieURL fileType:fileType error:&error];

2-6的方法無(wú)甚可說(shuō),基本就是調(diào)用AVAssetWriter的三個(gè)方法:

  • startWriting
  • cancelWriting
  • finishWriting
    還有finishRecording方法中對(duì)音頻和視頻AVAssetWriterInput調(diào)用的方法markAsFinished

第七個(gè)方法
- (void)processAudioBuffer:(CMSampleBufferRef)audioBuffer;比較重要,在整個(gè)GPUImage中,只在兩種響應(yīng)鏈起點(diǎn)GPUImageMovie和GPUImageVideoCamera中作為audioEncodingTarget屬性調(diào)用過(guò),這一部分也可以進(jìn)行擴(kuò)展,進(jìn)行混音等操作。

幀渲染方法

//都是私有方法
- (void)createDataFBO;
- (void)destroyDataFBO;
- (void)setFilterFBO;
- (void)renderAtInternalSizeUsingFramebuffer:(GPUImageFramebuffer *)inputFramebufferToUse;

GPUImageInput協(xié)議方法

幾個(gè)存取方法

追加

** AVAssetWriterInputPixelBufferAdaptor**:
AVAssetWriterInputPixelBufferAdaptor負(fù)責(zé)將圖片轉(zhuǎn)成的緩存數(shù)據(jù)CVPixelBufferRef追加到AVAssetWriterInput中,(把CVPixelBufferRef視頻貞圖像拼接到視頻中)。

You use an AVAssetWriterInputPixelBufferAdaptor to append video samples packaged as CVPixelBuffer objects to a single AVAssetWriterInput object.//注意overview的部分

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容