Macos 如何从AVPlayer获得平滑的高速播放?
Macos 如何从AVPlayer获得平滑的高速播放?,macos,cocoa,avfoundation,avplayer,appkit,Macos,Cocoa,Avfoundation,Avplayer,Appkit,AVPlayer有一个名为rate的属性,用于控制播放速率1.0为正常速度,而2.0或5.0等值应分别以2倍和5倍的速度播放 每当我将播放速率值设置为高于1.0(比如10.0)时,播放会非常不平稳,而且由于播放器无法跟上,看起来大量帧被丢弃 但是,QuickTime Player中的相同值(使用相同的电影)会以2x、5x、10x、30x和60x的速率平滑播放(正如QuickTime Player所报告的那样) 我创建了一个测试OSX应用程序,它只包含一个AVPlayerView和两个用于设置播放
AVPlayer
有一个名为rate
的属性,用于控制播放速率1.0
为正常速度,而2.0
或5.0
等值应分别以2倍和5倍的速度播放
每当我将播放速率值设置为高于1.0
(比如10.0
)时,播放会非常不平稳,而且由于播放器无法跟上,看起来大量帧被丢弃
但是,QuickTime Player中的相同值(使用相同的电影)会以2x、5x、10x、30x和60x的速率平滑播放(正如QuickTime Player所报告的那样)
我创建了一个测试OSX应用程序,它只包含一个AVPlayerView
和两个用于设置播放速率的按钮。1.0
的速率按预期工作,但10.0
的速率会产生非常不稳定的播放
然而,AVPlayerView
有一个奇怪的怪癖,如果你用鼠标点击播放时间线来寻找另一个位置(当它以10倍的速度播放时),那么AVPlayerView
将“修复”播放,电影将以10倍的速度平稳播放。只需点击播放时间线
有人知道如何在1x以外的速率下实现平滑播放吗?这显然不是硬件问题或文件大小问题,因为QuickTime Player和AVPlayerView都可以做到这一点
尝试
这表明这可能是一个音频问题(事实上,QuickTime Player和AVPlayerView在转发时都会禁用音频),但我所有禁用所有音频曲目、禁用所有曲目或更改音频基音算法的尝试似乎都没有什么不同。即使没有音频,播放仍然是断断续续的
我还尝试停止播放,然后用新的速率调用prerollAtRate:completionHandler
,但这也没有什么区别
QuickTime Player和AVPlayerView正在做什么,以10倍、30倍甚至60倍的速度平滑播放电影?这只是一个解决办法
当播放速率从0.0更改为较大值时,如果这是自上次调用AVPlayer.replaceCurrentItem
以来播放速率的第一次从零到非零的转换,则播放会平滑(并且音频会自动静音)。这是第一次这样的转换:仅将速率先设置为0.0,然后再设置为所需速率是不起作用的
因此,例如,这将在高速下产生平滑播放:
func setPlayerRate(player: AVPlayer, rate: Float) {
// AVFoundation wants us to do most things on the main queue.
DispatchQueue.main.async {
if (rate == player.rate) {
return
}
if (rate > 2.0 || rate < -2.0) {
let playerItem = player.currentItem
player.replaceCurrentItem(with: nil)
player.replaceCurrentItem(with: playerItem)
player.rate = rate
} else {
// No problems "out of the box" with rates in the range [-2.0,2.0].
player.rate = rate
}
}
}
func setPlayerRate(播放器:AVPlayer,速率:Float){
//AVFoundation希望我们在主队列上完成大部分工作。
DispatchQueue.main.async{
如果(速率==玩家速率){
返回
}
如果(速率>2.0 | |速率<-2.0){
让playerItem=player.currentItem
player.replaceCurrentItem(带:nil)
player.replaceCurrentItem(带:playerItem)
player.rate=速率
}否则{
//“开箱即用”的费率在[-2.0,2.0]范围内没有问题。
player.rate=速率
}
}
}
您找到这个问题的解决方案了吗?如果是,那是什么?不,对不起。我最终不得不构建自己的解决方案,但它没有我想要的那么好。从长远来看,我认为最好的播放体验需要更深入的挖掘,并在使用AVPlayer之外处理帧解码。在macos 10.12.3/Xcode 8.2.1下,我已经证实了上述一些:速度高达2.0不会出现问题,但设置AVPlayer。速率大于2.0会导致播放不平稳;使用AVPlayerView更改播放速率可使所有速度的播放都平滑;首先将速率设置为0.0,然后调用prerollatate(atRate:,completionHandler:)
并在完成处理程序中设置较高的速率,但这并不能解决问题;仅使用视频曲目创建AVMutableComposition无法解决问题;禁用音轨并不能解决问题。同样值得注意的是,这显然是AVFoundation的一个黑暗角落,即使对于苹果的文档编制人员来说也是如此:AVSimplePlayerOSX示例代码提供了一个显示此问题的快进按钮。可能重复交换AVPlayerItem,或者在AVComposition中对媒体曲目进行重新计时,这两种方法都是有效的,即使不是很费力,也能使播放更加流畅。但是,如果您希望允许用户在实时播放过程中更改播放速率,那么它们并不是很好的解决方案。这种行为在具有“点动”拨号的视频应用程序中很常见。QuickTime Player的自省表明(尽管尚未确认),对于某些播放速率,它会重复调用seekTime…
,很可能是摆脱了一个自定义的时基,可能是为了更好的性能做了一些解码/缓存的技巧……而轻松地改变播放速度确实是我希望能够做到的事情!既然你提到了这一点,我还构建了一个东西,它可以像Final Cut Pro X一样显示电影预览,当你将鼠标放在它们上面时,缩略图中的单元格会显示视频。我感到沮丧的是,它工作得如此之好,即使在扔鼠标的时候,但事实并非如此。我只是不够聪明,没有想到用这种方式应用seekTime。谢谢我要试试这个。这也将避免在高速播放时丢失某些通知的错误。对于用户只需在其上移动鼠标即可通过的小视频缩略图,通过播放您寻求的时间和允许的公差,您可能会获得足够的性能。如果你寻找一个“关键帧”,而不是一个任意的时间,解码几乎是瞬间的。因为定时精度在一个系统中并不重要