自定义 AVVideoCompositing
2017-08-30 本文已影响408人
9362d9acd9ef
通过 AVFoundation
实现给本地视频添加滤镜的的方案大致有三种
- build-in compositor
- custom compositor
- AVPlayerItemVideoOutput
Custom compositor & Build-in compositor
如果设置了 AVVideoComposition
的 customVideoCompositorClass
属性
那就是用的 custom compositor,反之用的就是 build-in compositor
方案一: build-in compositor
+ (AVVideoComposition *)videoCompositionWithAsset:(AVAsset *)asset applyingCIFiltersWithHandler:(void (^)(AVAsynchronousCIImageFilteringRequest *request))applier
Demo
[AVVideoComposition videoCompositionWithAsset:srcAsset applyingCIFiltersWithHandler: ^(AVAsynchronousCIImageFilteringRequest *request) {
NSError *err = nil;
CIImage *filtered = myRenderer(request, &err);
if (filtered)
[request finishWithImage:filtered context:nil];
else
[request finishWithError:err];
}];
优点:
- 自带的 AVVideoCompositionLayerInstruction 很好用,可以实现很多效果渐变、旋转、裁剪的操作
- 代码量少
缺点:
- 只能作用于单轨(没法做过场动画了)
- iOS 版本 9.0 以上才能使用
方案二: custom compositor
- (void)finishCompositionRequest:(AVAsynchronousVideoCompositionRequest *)request {
NSError *err = nil;
CVPixelBufferRef sourcePixels = [request sourceFrameByTrackID:trackID];
CIImage *sourceImage = [CIImage imageWithCVPixelBuffer:sourcePixels];
[filter setValue:sourceImage forKey:kCIInputImageKey];
sourceImage = filter.outputImage;
CVPixelBufferRef resultPixels = [_renderContext newPixelBuffer];
[_ciContext render:sourceImage toCVPixelBuffer: resultPixels];
if (resultPixels) {
[request finishWithComposedVideoFrame:resultPixels];
CVPixelBufferRelease(resultPixels);
} else {
[request finishWithError:err];
}
}
优点:
- AVPlayerItem, AVAssetExportSession, AVAssetImageGenerator, or AVAssetReaderVideoCompositionOutput 都可以支持使用 custom compositor,
写一个类,到处都可以用。 - 可定制化程度高,可以创建丰富的过场动画
缺点:
- 没办法使用 AVVideoCompositionLayerInstruction 对视频做 OpacityRamp 、 Transform 、Crop 等操作
- 需要实现的代码比较多