2017-01-27 3 views
0

AVAudioPlayer 대신 AVQueuePlayer를 사용하도록 오디오 플레이어 응용 프로그램을 다시 제작했습니다. 재생을 위해 오디오 파일을 대기열에 추가 할 수 있어야합니다. AVQueuePlayer는 AVPlayer의 서브 클래스이므로 CMTime을 사용하여 AVPlayerItem 시간 속성 (duration, currentTime 등)을 추적합니다. 내 AudioPlayer 뷰의 슬라이더와 UILabels를 업데이트하는 애니메이션 기능을 재 작업해야했습니다.AVPlayerItem CurrentTime을 초 단위로 재생합니다. 일치하지 않는 값을 반환합니다.

나는 CMTime 구조체를 TimeIntervals 대신 사용하고 있기 때문에, my currentSeconds 변수는 오디오 파일이 재생 될 때 이상한 일관성없는 값을 반환한다는 것을 알게되었습니다. 내가 포함시킨 코드 아래에 인쇄 된 결과가 표시됩니다.

이렇게하면 내 트랙 슬라이더가 다른 지점으로 딸꾹질되고 재생 시간 표시가 홀수 값으로 점프됩니다 (재생 중 절반은 00:00 포함).

나는 여기에 무슨 일이 일어나고 있는지 새롭고 addTimeObserver 함수의 간격 값을 변경하려고 시도했지만 아무 것도 변경하지 않았습니다. 이것은 0.1 초마다 animateFooterView()를 실행하도록 예약 한 Timer 객체의 문제 일 수 있습니다. 그러나 어떻게 처리해야할지 모르겠습니다. currentSeconds의

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

인쇄() 출력 : 여기에

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를 호출 내가 언급 된 타이머에 등을 엿볼 수있는 footerView이 재생 될 때마다 매 0.1 초.

func play() { 

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

사실, 난 그냥 내가 periodicTimeObserver 타이머 발사로 인해 매 0.1 초를 추가 해요 ... 잘못 여기에 무슨 일이 일어나고 있는지 깨달았다 생각합니다. 나는 그 관측자를 한 번 더 추가해야하고 타이머를 모두 함께 제거해야한다고 생각한다.

답변

0

제 생각에 AVPlayer에 지속적으로 관찰자를 추가 한 타이머가 반환 된 현재 시간을 엉망으로 만들고 있다고 생각했습니다. 나는 타이머를 제거하고 대신 현재 시간을 업데이트하는 옵저버 함수를 가지고 있습니다. 이제 완벽하게 작동합니다.

관련 문제