本文介绍,在GPUImage中为添加视频文件使用GPUImageMovieWriter的方法。
处理的视频链接:
https://coding.net/u/Xoxo_x/p/IFlyDemo/git/blob/master/IMG_3554.m4v
Demo:
https://coding.net/u/Xoxo_x/p/videofilter/git/blob/master/GPUImagePrepare2.zip
情况 | 内容 |
---|---|
情况一 | 实时滤镜处理 |
情况二 | 视频文件处理 |
上篇文章我们已经介绍到实时滤镜显示的处理方法了。接下来我们就将经过滤镜显示的视频保存下来。
上篇文章链接 :http://blog.csdn.net/xoxo_x/article/details/58357978
上篇文章代码:
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];
}