【发布时间】:2020-01-19 07:26:03
【问题描述】:
我目前正在我的一个应用中开发一项功能,用户可以在其中将照片和视频添加到帖子中。他们有能力录制视频或拍照,但之后我想通过应用滤镜或更改亮度、对比度、曝光等方式让他们完全控制输出...
这对于照片来说相对容易。为了简化工作流程,我使用了一个名为 BBMetalImage 的第三方库。这很好用,我可以对照片和视频应用过滤器,但处理视频需要很长时间,我不希望我的用户这样做。应用过滤器时,处理一个 15 秒的剪辑可能需要 20 到 30 秒以上的时间。
我目前是这样做的:
var lookupFilterName: String! = "lookup_1"
let outputURL = URL(fileURLWithPath: "\(NSTemporaryDirectory())\(NSUUID().uuidString).mp4")
try? FileManager.default.removeItem(at: outputURL)
videoWriter = BBMetalVideoWriter(url: outputURL, frameSize: BBMetalIntSize(width: 480, height: 600))
videoSource = BBMetalVideoSource(url: currentVideoURL!)
videoSource.audioConsumer = videoWriter
if(filter != 0) {
lookupFilterName = "lookup_\(filter)"
}
let lookupFilter = BBMetalLookupFilter(lookupTable: UIImage(named: lookupFilterName)!.bb_metalTexture!)
videoSource.add(consumer: lookupFilter).add(consumer: videoWriter)
videoSource.audioConsumer = videoWriter
videoWriter.start()
videoSource.start { [weak self] (_) in
guard let self = self else { return }
self.videoWriter.finish {
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
if(self.currentVideoURL != nil) {
self.queuePlayer?.pause()
self.queuePlayer?.removeAllItems()
if let playerLayer = self.playerLayer {
playerLayer.removeFromSuperlayer()
}
self.currentFinalVideoURL = outputURL
let playerItem = AVPlayerItem(url: outputURL)
self.queuePlayer = AVQueuePlayer(items: [playerItem])
self.playerLayer = AVPlayerLayer(player: self.queuePlayer)
self.playerLooper = AVPlayerLooper(player: self.queuePlayer!, templateItem: playerItem)
self.videoPreview.layer.addSublayer(self.playerLayer!)
self.playerLayer?.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.width * 1.25)
self.playerLayer?.backgroundColor = UIColor.black.cgColor
self.queuePlayer?.play()
self.videoWriter = nil
self.videoSource = nil
} else {
self.videoWriter = nil
self.videoSource = nil
}
}
}
}
请不要误会我的意思。它完成了这项工作:它返回应用了过滤器的视频。基本上发生的事情是,它获取原始视频的源 URL,对其应用过滤器,将其写入另一个临时路径,然后将此视频显示给用户。
在我看来,这必须更快。我开始研究其他应用程序,尤其是 Instagram,当您应用过滤器时,它会立即更改(甚至不需要一秒钟)并继续播放视频而无需从第一帧重新开始。这才是我真正想要的。
我已经对此进行了一些研究,并认为我应该使用 CIFilter,因为 Core Image 提供了一种非常快速且可靠的方式来处理照片(和视频?)。
所以我的问题是:
- 我能否在使用 CIFilter 时应用定制的查找过滤器或 LUT,还是仅限于 Core Image 框架中提供的内置过滤器(例如 GaussianBlur 等)?
- 我应该如何“实时”更改视频,而不会对最终用户造成延迟?我在某处读到这是使用缓冲区完成的,之后视频的每一帧都以所需的效果进行操作并实时播放。关于如何实现这一目标的任何参考或示例?我不知道从哪里开始处理这个具体问题。我还希望能够在用户停止编辑时导出此视频(滤镜、亮度、对比度……)。
干杯!欢迎提供所有信息。
【问题讨论】:
标签: ios swift video-processing core-image cifilter