1. 程式人生 > >iOS GPUImage研究四:為視訊檔案新增濾鏡

iOS GPUImage研究四:為視訊檔案新增濾鏡

本文介紹,在GPUImage中為新增視訊檔案使用GPUImageMovieWriter的方法。

這裡寫圖片描述

情況 內容
情況一 實時濾鏡處理
情況二 視訊檔案處理

情況一:實時濾鏡處理

上篇文章程式碼:

GPUImageVideoCamera*  videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack];
//濾鏡
GPUImageSepiaFilter *filter
= [[GPUImageSepiaFilter alloc] init]; //顯示view GPUImageView *filterView = (GPUImageView *)self.view; //組合 [videoCamera addTarget:filter]; [filter addTarget:filterView]; //相機開始執行 [videoCamera startCameraCapture];

再來看一下這個結構圖:

這裡寫圖片描述

視訊處理需要用到GPUImageMovieWriter這個類,初始化方式如下:

//movieURL 是指電影的寫入地址 是:NSURL
GPUImageMovieWriter* movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size
:CGSizeMake(480.0, 640.0)];

其實,GPUImageView和GPUImageMovieWriter是出於同一地位的,都是視訊輸出類,只不過一個是輸出到螢幕,一個是輸出到檔案。

那麼我們將:

//組合
[videoCamera addTarget:filter];
[filter addTarget:filterView];

換成:


//組合
[videoCamera addTarget:filter];
[filter addTarget:movieWriter];

就可以實現實時濾鏡視訊檔案輸出呢?

修改程式碼如下:

- (void)viewDidLoad
{
    [super
viewDidLoad]; videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack]; //輸出方向為豎屏 videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait; //濾鏡 filter = [[GPUImageSepiaFilter alloc] init]; //顯示view GPUImageView *filterView = (GPUImageView *)self.view; //組合 [videoCamera addTarget:filter]; [filter addTarget:filterView]; //相機開始執行 [videoCamera startCameraCapture]; //設定寫入地址 NSString *pathToMovie = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/LiveMovied.m4v"]; movieURL = [NSURL fileURLWithPath:pathToMovie]; movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(480.0, 640.0)]; //設定為liveVideo movieWriter.encodingLiveVideo = YES; [filter addTarget:movieWriter]; //設定聲音 videoCamera.audioEncodingTarget = movieWriter; //延遲2秒開始 [self performSelector:@selector(starWrite) withObject:nil afterDelay:2]; //延遲12秒結束 [self performSelector:@selector(stopWrite) withObject:nil afterDelay:12]; } - (void)starWrite{ dispatch_async(dispatch_get_main_queue(), ^{ [movieWriter startRecording]; }); } - (void)stopWrite{ dispatch_async(dispatch_get_main_queue(), ^{ videoCamera.audioEncodingTarget = nil; [filter removeTarget:movieWriter]; [movieWriter finishRecording]; ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:movieURL]) { [library writeVideoAtPathToSavedPhotosAlbum:movieURL completionBlock:^(NSURL *assetURL, NSError *error) { dispatch_async(dispatch_get_main_queue(), ^{ if (error) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Video Saving Failed" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; } else { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Video Saved" message:@"Saved To Photo Album" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; } }); }]; } }); }

然後執行、我們發現:

成功寫入並且相簿中有寫入的檔案:並且已經新增上了濾鏡。

大功告成,說明我們上面的猜測是正確的。

如果,你僅僅是處理視訊檔案,那麼不需要

[filter addTarget:filterView];

以及encodingLiveVideo不需要開啟:

movieWriter.encodingLiveVideo = YES;

這句話可能有疑問:

NSString *pathToMovie = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/LiveMovied.m4v"];

為什麼用m4v格式?

關於M4V格式:

M4V 是一個標準視訊檔案格式,由蘋果公司創造。此種格式為 iPod 、 iPhone 和 PlayStation Portable 所使用,同時此格式基於 MPEG-4 編碼第二版。M4V是一種應用於網路視訊點播網站和移動手持裝置的視訊格式,是MP4格式的一種特殊型別,其後綴常為.MP4或.M4V,其視訊編碼採用H264或H264/AVC,音訊編碼採用AAC

如果我們在寫入濾鏡的時候突然改變為其他濾鏡怎麼辦?

就像你想的那樣:

[self performSelector:@selector(changeFilter) withObject:nil afterDelay:6];
- (void)changeFilter{
    videoCamera.removeAllTargets;
    filter = [[GPUImageSobelEdgeDetectionFilter alloc]init];
    [videoCamera addTarget:filter];
    GPUImageView *filterView = (GPUImageView *)self.view;
    [filter addTarget:filterView];
    [filter addTarget:movieWriter];

}