Есть ли какой-нибудь быстрый и максимально легкий способ применить CIFilter
к видео? Перед тем как это упомянуть, я просмотрел GPUImage - он выглядит очень мощным < s> magic, но это действительно излишне для того, что я пытаюсь сделать.
По сути, я бы хотел
- Возьмите видеофайл, скажем, хранящийся в
/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
}
}
}
Это отлично работает, но у меня много возникали лишь крошечные проблемы с поиском того, как применить фильтр к уже сохраненному видеофайлу. Есть возможность просто делать то, что я сделал выше, используя 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
, а затем сохранить новое видео в другом месте.