在iOS中给视频添加滤镜的方法示例

  

"众所周知,视频可以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中给视频添加滤镜的方法示例