ios - 播放 AVPlayerItem CurrentTime(以秒为单位)返回不一致的值

标签 ios swift avqueueplayer avplayeritem cmtime

我正在重新设计我的音频播放器应用程序以使用 AVQueuePlayer 而不是 AVAudioPlayer,因为我现在意识到我需要能够对音频文件进行排队以便播放。由于 AVQueuePlayer 是 AVPlayer 的子类,它使用 CMTime 来跟踪 AVPlayerItem 时间属性(持续时间、当前时间等...),因此我必须重新设计动画函数,以更新 AudioPlayer View 的 slider 和 UILabels。

我发现,现在我使用 CMTime 结构而不是 TimeIntervals,我的 currentSeconds 变量在音频文件播放时返回一些奇怪的、不一致的值。您可以在我包含的代码下方看到打印结果。

这也会导致我的轨道 slider 打嗝到不同的位置,并且持续时间标签跳到奇数值,包括播放一半时的 00:00。

我对这里发生的很多事情都很陌生,我尝试更改 addTimeObserver 函数中的间隔值,认为但它没有改变任何东西。这可能是 Timer 对象的问题,我计划每 0.1 秒触发一次 animateFooterView()...但我不知道如何解决它。

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)
            }
        })
}

Print() currentSeconds 输出:

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 秒添加一个 periodicalTimeObserver。我想我只需要添加一次观察者,然后一起取消计时器?

最佳答案

我的假设是正确的,计时器不断向 AVPlayer 添加观察者会弄乱返回的当前时间。我删除了计时器,而是让观察者函数更新当前时间。现在可以完美运行了。

关于ios - 播放 AVPlayerItem CurrentTime(以秒为单位)返回不一致的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41904722/

相关文章:

ios - 如何在时间延迟后生成对象 swift 3 spritekit

objective-c - 删除 UITableView 单元格之前发出警报 - (UIAlertController) Swift 或 Objective-C

swift - 为什么我的应用内购买无法购买该产品?

swift - NSNotificationCenter 到 AVQueuePlayer swift

swift - 检测 AVPlayer 视频开始停止事件

javascript - jQuery 将 iframe 写入 XLS 导致 iPhone 上的沙箱访问冲突

javascript - Android OS/iOS/debian linux 中的事件(单击 Enter 键)

ios - NSMutableArray,int 值从 1 到 100

xCode UIView 与 UITableView

ios - 可以使用 AVQueuePlayer 在队列顶部插入项目吗?