我正在尝试将CIFilter应用于AVAsset,然后在应用过滤器的情况下保存它.我这样做的方法是使用AVAssetExportSession
with videoComposition
set设置为AVMutableVideoComposition
具有自定义AVVideoCompositing
类的对象.
我还将instructions
我的AVMutableVideoComposition
对象设置为自定义组合指令类(符合AVMutableVideoCompositionInstruction
).这个类传递了一个跟踪ID,以及一些其他不重要的变量.
不幸的是,我遇到了一个问题 - startVideoCompositionRequest:
我的自定义视频合成器类(符合AVVideoCompositing
)中的函数没有被正确调用.
当我将passthroughTrackID
自定义指令类的变量设置为轨道ID时,startVideoCompositionRequest(request)
我的函数AVVideoCompositing
不会被调用.
然而,当我没有设置passthroughTrackID
我的自定义指令类的变量,将startVideoCompositionRequest(request)
被调用,但没有正确-打印request.sourceTrackIDs
结果空数组,并request.sourceFrameByTrackID(trackID)
导致零值.
我发现有趣的是,cancelAllPendingVideoCompositionRequests:
在尝试使用过滤器导出视频时,该函数总是被调用两次.startVideoCompositionRequest:
在startVideoCompositionRequest:
未调用的情况下,它要么被调用一次,要么被调用一次,或者连续两次被调用.
我创建了三个用于导出带过滤器的视频的类.这是实用程序类,它基本上只包含一个export
函数并调用所有必需的代码
class VideoFilterExport{
let asset: AVAsset
init(asset: AVAsset){
self.asset = asset
}
func export(toURL url: NSURL, callback: (url: NSURL?) -> Void){
guard let track: AVAssetTrack = self.asset.tracksWithMediaType(AVMediaTypeVideo).first else{callback(url: nil); return}
let composition …
Run Code Online (Sandbox Code Playgroud) ios avcomposition avvideocomposition avassetexportsession 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
,播放视频,并在播放时从每一帧获取像素缓冲区,但这不适用于后台视频处理.我不认为用户会喜欢等待他们的视频用于过滤器的应用. …