Pen*_*ise 5 synchronization ios avplayer swift metal
我有一个项目,用户可以在其中拍摄视频,然后向其中添加过滤器或更改亮度和对比度等基本设置。为此,我使用BBMetalImage,它基本上返回MTKView 中的视频(BBMetalView
在项目中命名为 a )。
一切正常 - 我可以播放视频,添加过滤器和所需的效果,但没有音频。我就此问过作者,他建议为此使用AVPlayer
(或AVAudioPlayer
)。所以我做了。但是,视频和音频不同步。可能首先是因为比特率不同,库的作者也提到帧率会因为过滤过程而不同(这消耗的时间是可变的):
渲染视图 FPS 与实际速率并不完全相同。因为视频源输出帧经过过滤器处理,过滤器处理时间是可变的。
首先,我将视频裁剪为所需的纵横比 (4:5)。我将此文件 (480x600) 保存在本地,使用AVVideoProfileLevelH264HighAutoLevel
as AVVideoProfileLevelKey
. 我的音频配置使用NextLevelSessionExporter,具有以下设置:AVEncoderBitRateKey: 128000
、AVNumberOfChannelsKey: 2
、AVSampleRateKey: 44100
。
然后,BBMetalImage 库获取这个保存的音频文件并提供一个 MTKView (BBMetalView) 来显示视频,允许我实时添加过滤器和效果。设置类型如下所示:
self.metalView = BBMetalView(frame: CGRect(x: 0, y: self.view.center.y - ((UIScreen.main.bounds.width * 1.25) / 2), width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.width * 1.25))
self.view.addSubview(self.metalView)
self.videoSource = BBMetalVideoSource(url: outputURL)
self.videoSource.playWithVideoRate = true
self.videoSource.audioConsumer = self.metalAudio
self.videoSource.add(consumer: self.metalView)
self.videoSource.add(consumer: self.videoWriter)
self.audioItem = AVPlayerItem(url: outputURL)
self.audioPlayer = AVPlayer(playerItem: self.audioItem)
self.playerLayer = AVPlayerLayer(player: self.audioPlayer)
self.videoPreview.layer.addSublayer(self.playerLayer!)
self.playerLayer?.frame = CGRect(x: 0, y: 0, width: 0, height: 0)
self.playerLayer?.backgroundColor = UIColor.black.cgColor
self.startVideo()
Run Code Online (Sandbox Code Playgroud)
并且startVideo()
是这样的:
audioPlayer.seek(to: .zero)
audioPlayer.play()
videoSource.start(progress: { (frameTime) in
print(frameTime)
}) { [weak self] (finish) in
guard let self = self else { return }
self.startVideo()
}
Run Code Online (Sandbox Code Playgroud)
由于外部库/库,这可能非常模糊。但是,我的问题很简单:有什么方法可以让MTKView
我的AVPlayer
? 这对我有很大帮助,我相信Silence-GitHub
也会将此功能实现到库中以帮助很多其他用户。欢迎任何有关如何解决此问题的想法!
小智 1
我按如下方式自定义 BBMetalVideoSource 然后它就起作用了:
在 func 中private func processAsset(progress:, completion:)
,我将此代码块替换if useVideoRate { //... }
为:
if useVideoRate {
if let playerTime = delegate.getAudioPlayerCurrentTime() {
let diff = CMTimeGetSeconds(sampleFrameTime) - playerTime
if diff > 0.0 {
sleepTime = diff
if sleepTime > 1.0 {
sleepTime = 0.0
}
usleep(UInt32(1000000 * sleepTime))
} else {
sleepTime = 0
}
}
}
Run Code Online (Sandbox Code Playgroud)这段代码帮助我们解决了这两个问题:1.预览视频效果时没有音频,2.音频与视频同步。
归档时间: |
|
查看次数: |
1050 次 |
最近记录: |