AVPlayer 的 addPeriodicTimeObserverForInterval 中的 CMTime:回调永远不会达到项目的持续时间
Posted
技术标签:
【中文标题】AVPlayer 的 addPeriodicTimeObserverForInterval 中的 CMTime:回调永远不会达到项目的持续时间【英文标题】:CMTime in AVPlayer's addPeriodicTimeObserverForInterval: callback never reaches item's duration 【发布时间】:2016-06-22 19:12:36 【问题描述】:我使用 AVPlayer 的 -(id)addPeriodicTimeObserverForInterval: queue: usingBlock:
方法将 UI 更新到播放进度。但是,我的进度条永远不会结束。
CMTime duration = self.player.currentItem.asset.duration;
float totalSeconds = (Float64)(duration.value * 1000) / (Float64)(duration.timescale);
NSLog(@"duration: %.2f", totalSeconds);
__weak __typeof(self) welf = self;
_mTimeObserver = [self.player addPeriodicTimeObserverForInterval:CMTimeMake(10, 1000)
queue:NULL // main queue
usingBlock:^(CMTime time)
float totalSeconds = (Float64)(time.value * 1000) / (Float64)(time.timescale);
NSLog(@"progress %f", totalSeconds);
];
日志:
App[2373:792179] duration: 3968.00
点击播放按钮
App[2373:792179] progress 0011.176
App[2373:792179] progress 0021.175
...
App[2373:792179] progress 3701.319
App[2373:792179] progress 3704.000
我不应该期望最后一个数字是3968.0
吗?
音频从服务器流式传输。
编辑
最后的进度编号是 ALWAYS duration - 0.264 sec
无论实际持续时间长度是多少。
这太奇怪了,我希望我们可以在 SO 上使用表情符号。
【问题讨论】:
【参考方案1】:好问题。尝试使用CMTimeGetSeconds(time)
而不是自己计算总秒数。
另外,尝试使用CMTimeMakeWithSeconds(10.0, NSEC_PER_SEC)
为周期性时间观察器创建时间。
这篇文章帮助我理解了 CMTime 的谜团:https://warrenmoore.net/understanding-cmtime
【讨论】:
相同的东西(其他声音):duration:4.736 maxProgress:4.472
。可能是什么原因?编辑:刚刚看到你更新的答案,我会尝试其他选项
@kerd 这很有趣。您还可以使用CMTimeGetSeconds
打印持续时间吗?还有一件事:尝试更细粒度的回调值。尝试1.0/30.0
,而不是 10 秒。
在第一条评论中,我写了来自CMTimeGetSeconds
的结果。抱歉,如果不清楚。此外,我尝试过的 CMTimeMakeWithSeconds(10.0, NSEC_PER_SEC)
是最好的颗粒——它花了 10 纳秒,而不是我在原始帖子中使用的 0.01 秒。
试试CMTimeMakeWithSeconds(1.0/30.0, NSEC_PER_SEC)
。在您的第一条评论中,maxProgress 低于持续时间。问题是 高于 比持续时间。所以可能是回调没有触发,因为它不够细粒度。
@kerd 实际上检查CMTimeGetSeconds(self.player.currentTime)
比使用传入的time
更准确,因为这实际上是调用块的时间。【参考方案2】:
文档明确指出:
只要您希望播放器调用时间观察器,就必须保留返回的值。
【讨论】:
抱歉,您能否协助进一步了解这些信息如何提供帮助?顺便说一句,观察者不是已经被调用了吗? 他的意思是你需要持有对观察者对象的强引用,否则它将被释放。例如,您的 UIViewController 可能有一个名为 playerTimeObserver 的属性。以上是关于AVPlayer 的 addPeriodicTimeObserverForInterval 中的 CMTime:回调永远不会达到项目的持续时间的主要内容,如果未能解决你的问题,请参考以下文章
带有 AVPlayer 的 AVAudioSession:当 AVPlayer 播放器正在播放时,状态菜单中的“播放”图标不显示