"众所周知,视频可以p”,今天我们来学习怎么给视频添加滤镜。
在iOS中,对视频进行图像处理一般有两种方式:<代码> GPUImage 代码>和<代码> AVFoundation> 代码。
在之前的文章中,我们对GPUImage已经有了一定的了解。之前一般使用它对摄像头采集的图像数据进行处理,然而,它对本地视频的处理也一样方便。
直接看代码:
//电影 NSString *路径=[[NSBundle mainBundle] pathForResource: @减低:“sample”@“mp4”); NSURL * url=[NSURL fileURLWithPath路径):; GPUImageMovie *电影=[[GPUImageMovie alloc] initWithURL: url];//过滤 GPUImageSmoothToonFilter *过滤器=[[GPUImageSmoothToonFilter alloc] init);//视图 GPUImageView * imageView=[[GPUImageView alloc] initWithFrame: CGRectMake (0 80 self.view.frame.size.width self.view.frame.size.width)]; (自我。视图addSubview imageView):;//链 (电影addTarget:过滤器); [过滤addTarget: imageView];//处理 (电影startProcessing); >之前核心代码一共就几行。GPUImageMovie负责视频文件的读取,GPUImageSmoothToonFilter负责滤镜效果处理,GPUImageView负责最终图像的展示。
通过滤镜链将三者串起来,然后调用GPUImageMovie的startProcessing方法开始处理。
虽然GPUImage在使用上简单,但是存在着没有声音,在非主线程调用UI,导出文件麻烦,无法进行播放控制等诸多缺点。
小结:GPUImage虽然使用很方便,但是存在诸多缺点,不满足生产环境需要。
<强> 1,AVPlayer的使用强>
首先来复习一下AVPlayer最简单的使用方式:
NSURL * url=[[NSBundle mainBundle] URLForResource: @“样本”withExtension: @“mp4”); AVURLAsset *资产=[AVURLAsset assetWithURL: url]; AVPlayerItem * playerItem=[[AVPlayerItem alloc] initWithAsset:资产); AVPlayer *玩家=[[AVPlayer alloc] initWithPlayerItem playerItem):; AVPlayerLayer * playerLayer=[AVPlayerLayer playerLayerWithPlayer球员):; >之前第一步先构建AVPlayerItem,然后通过AVPlayerItem创建AVPlayer,最后通过AVPlayer创建AVPlayerLayer。
AVPlayerLayer是CALayer的子类,可以把它添加到任意的层上。当AVPlayer调用玩的方法时,AVPlayerLayer上就能将图像渲染出来。
AVPlayer的使用方式十分简单。但是,按照上面的方式,最终只能在AVPlayerLayer上渲染出最原始的图像。如果我们希望在播放的同时,对原始图像进行处理,则需要修改AVPlayer的渲染过程。
<强> 2,修改AVPlayer的渲染过程强>
修改AVPlayer的渲染过程,要从AVPlayerItem下手,主要分为四步:
<强>第一步:自定义AVVideoCompositing类
强>AVVideoCompositing是一个协议,我们的自定义类要实现这个协议。在这个自定义类中,可以获取到每一帧的原始图像,进行处理并输出。
在这个协议中,最关键是startVideoCompositionRequest方法的实现:
//CustomVideoCompositing.m - (void) startVideoCompositionRequest: (AVAsynchronousVideoCompositionRequest *) asyncVideoCompositionRequest { 设置(自我。renderingQueue ^ { @autoreleasepool { 如果(self.shouldCancelAllRequests) { [asyncVideoCompositionRequest finishCancelledRequest]; 其他}{ CVPixelBufferRef resultPixels=(自我newRenderdPixelBufferForRequest: asyncVideoCompositionRequest); 如果(resultPixels) { [asyncVideoCompositionRequest finishWithComposedVideoFrame resultPixels):; CVPixelBufferRelease (resultPixels); 其他}{//打印错误 } } } }); } >之前通过newRenderdPixelBufferForRequest方法从AVAsynchronousVideoCompositionRequest中获取到处理后的CVPixelBufferRef后输出,看下这个方法的实现:
//CustomVideoCompositing.m ——(CVPixelBufferRef) newRenderdPixelBufferForRequest:请求(AVAsynchronousVideoCompositionRequest *) { request.videoCompositionInstruction CustomVideoCompositionInstruction * videoCompositionInstruction=(CustomVideoCompositionInstruction *); NSArray在iOS中给视频添加滤镜的方法示例