以秒为单位播放 AVPlayerItem CurrentTime 返回不一致的值
Posted
技术标签:
【中文标题】以秒为单位播放 AVPlayerItem CurrentTime 返回不一致的值【英文标题】:Playing AVPlayerItem CurrentTime in Seconds Return Inconsistent Values 【发布时间】:2017-01-27 23:34:59 【问题描述】:我正在重组我的音频播放器应用程序以使用 AVQueuePlayer 而不是 AVAudioPlayer,因为我现在意识到我需要能够将音频文件排队以进行播放。由于 AVQueuePlayer 是 AVPlayer 的子类,它使用 CMTime 来跟踪 AVPlayerItem 时间属性(duration、currentTime 等),我不得不重新设计我的动画函数,以更新我的 AudioPlayer 视图的滑块和 UILabel。
我发现,既然我使用的是 CMTime 结构,而不是 TimeIntervals,我的 currentSeconds 变量会在音频文件播放时返回一些奇怪的、不一致的值。您可以在我包含的代码下方看到打印结果。
这也导致我的轨道滑块打嗝到不同的位置,并且持续时间标签跳到奇数值,包括播放中途的 00:00。
我对这里发生的很多事情都不熟悉,我试图改变 addTimeObserver 函数中的间隔值,我想,但它没有改变任何东西。这可能是我计划每 0.1 秒触发一次 animateFooterView() 的 Timer 对象的问题......但我不知道如何解决它。
func animateFooterView()
let track = audioQueuePlayer?.currentItem
let duration: CMTime = (track?.asset.duration)!
let durationSeconds: Float64 = CMTimeGetSeconds(duration)
let currentSeconds: Float64 = CMTimeGetSeconds(track!.currentTime())
audioQueuePlayer?.addPeriodicTimeObserver(forInterval: CMTimeMakeWithSeconds(1, 10), queue: DispatchQueue.main, using:
(CMTime) -> Void in
if track?.status == .readyToPlay
let trackProgress: Float = Float(currentSeconds / durationSeconds) //* (self.footerView.trackSlider.maximumValue)
print("Progress in seconds: " + String(currentSeconds))
self.footerView.trackSlider.value = trackProgress
let minutesProgress = Int(currentSeconds) / 60 % 60
let secondsProgress = Int(currentSeconds) % 60
let minutesDuration = Int(durationSeconds) / 60 % 60
let secondsDuration = Int(durationSeconds) % 60
self.footerView.durationLabel.text = String(format: "%02d:%02d | %02d:%02d", minutesProgress, secondsProgress, minutesDuration, secondsDuration)
)
currentSeconds 的 Print() 输出:
Progress in seconds: 0.959150266
Progress in seconds: 0.459939791
Progress in seconds: 0.739364115
Progress in seconds: 0.0
Progress in seconds: 0.0
Progress in seconds: 0.253904687
Progress in seconds: 0.0
Progress in seconds: 0.15722927
Progress in seconds: 0.346783126
Progress in seconds: 0.050562017
Progress in seconds: 1.158813019
Progress in seconds: 1.252108811
Progress in seconds: 1.356793865
Progress in seconds: 1.458337661
Progress in seconds: 1.554249846
Progress in seconds: 1.615820093
Progress in seconds: 0.0
Progress in seconds: 0.0
Progress in seconds: 0.0
Progress in seconds: 0.050562017
Progress in seconds: 0.15722927
Progress in seconds: 0.253904687
Progress in seconds: 0.346783126
Progress in seconds: 0.459939791
Progress in seconds: 0.558436703
Progress in seconds: 0.656613436
Progress in seconds: 0.739364115
Progress in seconds: 0.854647401
Progress in seconds: 0.959150266
Progress in seconds: 1.057932049
Progress in seconds: 1.158813019
这是我提到的计时器的一瞥,每当 footerView 播放时,它每 0.1 秒调用一次 animateFooterView。
func play()
...
timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(animateFooterView), userInfo: nil, repeats: true)
...
实际上,我想我刚刚意识到这里出了什么问题...由于计时器触发,我每 0.1 秒添加一个periodicTimeObserver。我想我只需要添加该观察者一次,然后一起取消计时器吗?
【问题讨论】:
【参考方案1】:我的假设是正确的,即不断向 AVPlayer 添加观察者的计时器会弄乱返回的当前时间。我删除了计时器,而是让观察者函数更新当前时间。现在完美运行。
【讨论】:
以上是关于以秒为单位播放 AVPlayerItem CurrentTime 返回不一致的值的主要内容,如果未能解决你的问题,请参考以下文章