Joj*_*dmo 13 ios avasset cifilter swift
是否有任何快速,轻量级的方式应用于CIFilter
视频?在提到它之前,我已经看过GPUImage - 它看起来像是非常强大的魔法代码,但它对我正在尝试做的事情来说真的太过分了.
基本上,我想
/tmp/myVideoFile.mp4
CIFilter
视频文件应用于此视频文件/tmp/anotherVideoFile.mp4
我已经能够将CIFilter应用到一个非常容易和快速使用的视频中 AVPlayerItemVideoOutput
let player = AVPlayer(playerItem: AVPlayerItem(asset: video))
let output = AVPlayerItemVideoOutput(pixelBufferAttributes: nil)
player.currentItem?.addOutput(self.output)
player.play()
let displayLink = CADisplayLink(target: self, selector: #selector(self.displayLinkDidRefresh(_:)))
displayLink.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)
func displayLinkDidRefresh(link: CADisplayLink){
let itemTime = output.itemTimeForHostTime(CACurrentMediaTime())
if output.hasNewPixelBufferForItemTime(itemTime){
if let pixelBuffer = output.copyPixelBufferForItemTime(itemTime, itemTimeForDisplay: nil){
let image = CIImage(CVPixelBuffer: pixelBuffer)
// apply filters to image
// display image
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个伟大的工程,但我一直有很多只是麻烦哪怕一丁点找出如何将过滤器应用到已保存的视频文件.有一个选项,基本上只是做我上面做的,使用AVPlayer
,播放视频,并在播放时从每一帧获取像素缓冲区,但这不适用于后台视频处理.我不认为用户会喜欢等待他们的视频用于过滤器的应用.
在过度简化的代码中,我正在寻找这样的东西:
var newVideo = AVMutableAsset() // We'll just pretend like this is a thing
var originalVideo = AVAsset(url: NSURL(urlString: "/example/location.mp4"))
originalVideo.getAllFrames(){(pixelBuffer: CVPixelBuffer) -> Void in
let image = CIImage(CVPixelBuffer: pixelBuffer)
.imageByApplyingFilter("Filter", withInputParameters: [:])
newVideo.addFrame(image)
}
newVideo.exportTo(url: NSURL(urlString: "/this/isAnother/example.mp4"))
Run Code Online (Sandbox Code Playgroud)
有没有办法快速(再次,不涉及GPUImage,理想情况下在iOS 7中工作)的方式将过滤器应用于视频文件然后保存?例如,这将拍摄已保存的视频,将其加载到AVAsset
应用中CIFilter
,然后将新视频保存到其他位置.
ric*_*ter 24
在iOS 9/OS X 10.11/tvOS中,有一种将CIFilter
s应用于视频的便捷方法.它适用于AVVideoComposition
,因此您可以将它用于播放和文件到文件导入/导出.请参阅AVVideoComposition.init(asset:applyingCIFiltersWithHandler:)
方法文档.
Apple的核心图像编程指南中也有一个例子:
let filter = CIFilter(name: "CIGaussianBlur")!
let composition = AVVideoComposition(asset: asset, applyingCIFiltersWithHandler: { request in
// Clamp to avoid blurring transparent pixels at the image edges
let source = request.sourceImage.clampingToExtent()
filter.setValue(source, forKey: kCIInputImageKey)
// Vary filter parameters based on video timing
let seconds = CMTimeGetSeconds(request.compositionTime)
filter.setValue(seconds * 10.0, forKey: kCIInputRadiusKey)
// Crop the blurred output to the bounds of the original image
let output = filter.outputImage!.cropping(to: request.sourceImage.extent)
// Provide the filter output to the composition
request.finish(with: output, context: nil)
})
Run Code Online (Sandbox Code Playgroud)
那部分设定了构图.完成后,您可以通过将其分配给AVPlayer
或将其写入文件来播放它AVAssetExportSession
.既然你是在后者之后,这是一个例子:
let export = AVAssetExportSession(asset: asset, presetName: AVAssetExportPreset1920x1200)
export.outputFileType = AVFileTypeQuickTimeMovie
export.outputURL = outURL
export.videoComposition = composition
export.exportAsynchronouslyWithCompletionHandler(/*...*/)
Run Code Online (Sandbox Code Playgroud)
在核心图像的WWDC15会议上有更多关于这一点,大约20分钟开始.
如果你想要一个适用于早期操作系统的解决方案,那就有点复杂了.
旁白:想想你真正需要支持多久.截至2016年8月15日,87%的设备在iOS 9.0或更高版本上,97%在iOS 8.0或更高版本上.付出很多努力来支持您的潜在客户群的一小部分 - 当您完成项目并准备部署时,它将变得更小 - 可能不值得花费.
有几种方法可以解决这个问题.无论哪种方式,您将获得CVPixelBuffer
表示源帧,从中创建CIImage
s,应用过滤器以及渲染新CVPixelBuffer
s的方法.
使用AVAssetReader
和AVAssetWriter
读写像素缓冲区.有关如何执行此操作的示例(读取和写入部分;您仍需要在Apple的AVFoundation编程指南的导出章节中进行过滤).
使用AVVideoComposition
带有自定义合成类.您的自定义合成器具有AVAsynchronousVideoCompositionRequest
可以访问像素缓冲区的对象,以及提供处理像素缓冲区的方法.Apple有一个名为AVCustomEdit的示例代码项目,它显示了如何执行此操作(再次,只是获取和返回示例缓冲区部分;您希望使用Core Image处理而不是使用其GL渲染器).
在这两个中,AVVideoComposition
路径更灵活,因为您可以使用合成进行回放和导出.
归档时间: |
|
查看次数: |
6763 次 |
最近记录: |