2017-08-08 35 views
5

Tworzę aplikację, w której znajduje się odtwarzacz muzyki. Nie pracowałem nad tym od jakiegoś czasu, ale ostatni raz nad nim pracowałem pracował nowPlayingInfo . Teraz, gdy zaktualizowałem go do Swift 3, wszystko działa z wyjątkiem paska postępu.MPNowPlayingInfoCenter zatrzymał aktualizację paska postępu

Widziałem tutaj kilka podobnych pytań, które mówiły o warunkach wyścigu i zostały przeze mnie zastąpione, ale nie potrafię zrozumieć, przez co. Używam AVQueuePlayer, jeśli to pomaga.

Pominięte i poprzednie przyciski działają, grafika albumu, tytuł i artysta doskonale się aktualizują, ale czas, który upłynął, nie jest aktualizowany. Podczas debugowania MPNowPlayingInfoPropertyElapsedPlaybackTime z MPNowPlayingInfoCenter.default().nowPlayingInfo pokazuje poprawne liczby, ale rzeczywisty ekran w centrum sterowania nie jest. Zazwyczaj postęp utknął o 0:01 i po prostu się nie porusza. Jeśli jednak spróbuję użyć suwaka w mojej aplikacji i wrócić do centrum kontrolnego, pokazuje on czas, w którym starałam się, ale zostałam przy tym.

Oto mój kod setNowPlaying:

func setNowPlaying(_ dura: Float, timePlayed: Float) { 
    let s = songs[playbackInstance.currentSongIndex] 
    let albumArt = MPMediaItemArtwork.init(boundsSize: CGSize(width: 480, height: 360), requestHandler: { (size) -> UIImage in 
     return self.songImageView.image ?? #imageLiteral(resourceName: "WhiteMusic") 
    }) 
    let songInfo: [String: Any]? = [ 
     MPMediaItemPropertyTitle: s.name, 
     MPMediaItemPropertyArtist: s.artist, 
     MPMediaItemPropertyArtwork: albumArt, 
     MPMediaItemPropertyPlaybackDuration: dura, 
     MPNowPlayingInfoPropertyElapsedPlaybackTime: CMTimeGetSeconds(player.currentTime()) 
    ] 

    MPNowPlayingInfoCenter.default().nowPlayingInfo = songInfo 
} 

kiedyś ustawić MPNowPlayingInfoPropertyElapsedPlaybackTime do timePlayed zmiennej, która jest przekazywana do metody, ale ponieważ nie działa Próbowałem player.currentTime() zalecane przez innych pytań i jest to prawdopodobnie lepsza miara niż to, z czego i tak korzystałem.

Oto kod do poszukiwania w przypadku pomaga:

@IBAction func sliderChanged(_ sender: UISlider) { 
    if timer.isValid { 
     currentTimeLabel.text = secondsToText(sender.value) 
     player.seek(to: CMTimeMakeWithSeconds(Float64(sender.value), player.currentItem!.currentTime().timescale)) 
    } 
} 

Z jakiegoś powodu, że jest jedyną rzeczą, która zaktualizuje informacje o centrum sterowania.

+1

Jaki wątek jest ustawionyNowPlaying() jest wywoływane? Czy jest to główny wątek, czy wtórny? –

+0

@CharlesSrstka główny wątek – lagoon

Odpowiedz

0

To zadziałało dla mnie, może ci to pomoże.

  func setNowPlaying(_ dura: Float, timePlayed: Float) { 
      let s = songs[playbackInstance.currentSongIndex] 
      let albumArt = MPMediaItemArtwork.init(boundsSize: CGSize(width: 480, height: 360), requestHandler: { (size) -> UIImage in 
       return self.songImageView.image ?? #imageLiteral(resourceName: "WhiteMusic") 
      }) 

      MPNowPlayingInfoCenter.default().nowPlayingInfo = [ 
       MPMediaItemPropertyTitle: s.name, 
       MPMediaItemPropertyArtist: s.artist, 
       MPMediaItemPropertyArtwork: albumArt as Any, 
       MPMediaItemPropertyPlaybackDuration: dura, 
       MPNowPlayingInfoPropertyElapsedPlaybackTime : player.currentTime() 
      ] 
      UIApplication.shared.beginReceivingRemoteControlEvents() 
      becomeFirstResponder() 

     } 


     @IBAction func sliderAction(_ sender: Any) { 
       if player != nil { 
        Thread.cancelPreviousPerformRequests(withTarget: self) 
        self.perform(#selector(playAtSelectedTime) , with: nil, afterDelay: 0.2) 
       } 
      } 

     @objc func playAtSelectedTime(){ 
       let selectedTime = Double(progressSlider.value) 
       player.currentTime = selectedTime 
       convertTimingToTextLabel(selectedTime, label: self.runningLabel) 
       convertTimingToTextLabel(Double(player.duration-player.currentTime), label: self.durationLabel) 
       durationLabel.text = " -"+durationLabel.text! 
       updateSlider() 
      } 


     func updateSlider(){ 
       if timer != nil{ 
        timer.invalidate() 
       } 

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


     @objc func playingSong(){ 
       progressSlider.minimumValue = 0 
       progressSlider.maximumValue = Float(player.duration) 
       progressSlider.value = Float(player.currentTime) 

       convertTimingToTextLabel(Double(player.currentTime), label: self.runningLabel) 
       convertTimingToTextLabel(Double(player.duration-player.currentTime), label: self.durationLabel) 
       durationLabel.text = durationLabel.text! 
      } 



      func convertTimingToTextLabel(_ time: Double, label: UILabel) { 
        let minute = Int(time/60) 
        let seconds = Int(time - Double(minute * 60)) 
        setTimingSongForLabel(minute, seconds: seconds, label: label) 
       } 

      func setTimingSongForLabel(_ minute: Int, seconds: Int, label: UILabel) { 
        let mStr = minute > 9 ? "\(minute)":"0\(minute)" 
        let sStr = seconds > 9 ? "\(seconds)":"0\(seconds)" 
        label.text = "\(mStr):\(sStr)" 
       } 
+0

Jeśli masz jakieś pytania lub nadal nie działa, opublikuj pełny kod odtwarzacza, aby uzyskać pomoc. – cwilliamsz