2017-01-27 15 views
0

Я обновляю приложение для аудио-плеера, чтобы использовать AVQueuePlayer вместо AVAudioPlayer, так как теперь я понимаю, что мне нужно иметь возможность очереди аудиофайлов для воспроизведения. Поскольку AVQueuePlayer является подклассом AVPlayer, который использует CMTime для отслеживания свойств времени AVPlayerItem (duration, currentTime и т. Д.), Мне пришлось переработать мою анимационную функцию, которая обновляет слайдер и UILabels моего представления AudioPlayer.Воспроизведение AVPlayerItem CurrentTime в секундах Возврат Непоследовательные значения

Я обнаружил, что теперь, когда я использую структуры CMTime, вместо TimeIntervals, переменная currentSeconds возвращает некоторые нечетные, непоследовательные значения, которые воспроизводятся аудиофайлы. Вы можете увидеть распечатанные результаты ниже кода, который я включил.

Это также приводит к тому, что мой слайдер трека икает в разные места, а ярлык длительности прыгает на нечетные значения, включая 00:00, в то время как на полпути через воспроизведение.

Я новичок в том, что происходит здесь, и я попытался изменить значения интервалов в функции addTimeObserver, думая об этом, но ничего не изменил. Это может быть проблемой с объектом Timer, который я запланировал запустить animateFooterView() каждые 0,1 секунды ... но я не уверен, как его решить.

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:

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 

Вот проблеск как у таймера я упоминая, который вызывает animateFooterView каждые 0,1 секунды всякий раз, когда footerView играет.

func play() { 

    ... 
    timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(animateFooterView), userInfo: nil, repeats: true)  
    ... 
} 

На самом деле, я думаю, я просто понял, что происходит здесь не так ... Я добавляю periodicTimeObserver каждые 0.1 секунды из-за стрельбы по таймеру. Я думаю, мне просто нужно добавить этого наблюдателя один раз, а затем покончить с таймером все вместе?

ответ

0

Я был прав в своем предположении, что таймер, постоянно добавляющий наблюдателя к AVPlayer, испортил возвращаемое текущее время. Я удалил таймер, и вместо этого функция наблюдателя обновила текущее время. Теперь он отлично работает.