iOS GPUImage研究四:為視訊檔案新增濾鏡
阿新 • • 發佈:2019-02-04
本文介紹,在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];
}