2017-08-08 244 views
5

我正在製作一個包含音樂播放器的應用程序。我有一段時間沒有工作,但最後一次工作時,nowPlayingInfo 正在工作。現在,當我將它更新到Swift 3時,除了進度條之外,一切都可以使用。MPNowPlayingInfoCenter停止更新進度條

我在這裏看到過一些類似的問題,談到了競爭條件,它被某些東西覆蓋了,但我似乎無法弄清楚什麼。如果有幫助,我正在使用AVQueuePlayer

跳過和上一個按鈕正常工作,專輯封面,標題和藝術家完美更新,但經過的時間並未更新。當我調試時,從MPNowPlayingInfoCenter.default().nowPlayingInfo顯示正確的數字,但控制中心的實際屏幕不是。通常情況下,進度卡在0:01而不會移動。但是,如果我在我的應用程序中尋求使用滑塊並返回到控制中心,它會顯示我尋找的時間,但是停留在那個時間。

這裏是我的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 
} 

我用來設置MPNowPlayingInfoPropertyElapsedPlaybackTime到在傳遞給該方法的timePlayed變量,但由於它不工作我試圖player.currentTime()所推薦的其他問題和這可能是比我反正使用的更好的方法。

這裏是尋求代碼的情況下,它可以幫助:

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

出於某種原因,那就是將更新控制中心信息的唯一的事情。

+1

什麼線程setNowPlaying()被調用?它是在主線上還是次要的? –

+0

@CharlesSrstka主線程 – lagoon

回答

0

這對我有效,也許它會幫助你。

  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

如果您有任何問題或仍然無法正常工作,請張貼您的播放器的完整代碼,以便您可以爲您提供幫助。 – cwilliamsz