【发布时间】:2016-12-31 02:10:09
【问题描述】:
是否有任何快速、尽可能轻量级的方法将CIFilter 应用于视频?在提到它之前,我已经查看了 GPUImage - 它看起来像非常强大的 magic 代码,但对于我正在尝试做的事情来说,它确实有点矫枉过正。
基本上,我想
- 拍摄一个视频文件,比如存储在
/tmp/myVideoFile.mp4 - 为此视频文件应用
CIFilter - 将视频文件保存到不同(或相同)的位置,例如
/tmp/anotherVideoFile.mp4
我已经能够使用 AVPlayerItemVideoOutput 将 CIFilter 应用于播放极其轻松快速的视频
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
}
}
}
这很好用,但我在找出如何对已保存的视频文件应用过滤器时遇到了很多的小问题。可以选择基本上只是做我上面所做的,使用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"))
有什么方法可以快速(同样,不涉及 GPUImage,最好在 iOS 7 中工作)将过滤器应用于视频文件然后保存?例如,这将获取一个保存的视频,将其加载到AVAsset,应用CIFilter,然后将新视频保存到不同的位置。
【问题讨论】:
-
我能够让它工作,代码is now available on GitHub
标签: ios swift cifilter avasset