MPNowPlayingInfoCenter停止更新进度条

8

我正在制作一个带有音乐播放器的应用程序。我已经有一段时间没有工作了,但上次我工作时nowPlayingInfo是可以使用的。现在,当我将其更新为Swift 3时,除了进度条之外,一切都正常。

我在这里看到了一些类似的问题,谈论了竞争条件以及被某些东西覆盖,但我似乎无法找出原因。如果有帮助的话,我正在使用AVQueuePlayer

跳过和上一个按钮可以正常工作,专辑封面、标题和艺术家也可以完美地更新,但已经流逝的时间却没有更新。当我进行调试时,来自MPNowPlayingInfoCenter.default().nowPlayingInfoMPNowPlayingInfoPropertyElapsedPlaybackTime显示了正确的数字,但实际的控制中心屏幕没有更新。通常情况下,进度条停留在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() 方法在哪个线程上被调用?是在主线程还是次要线程上? - Charles Srstka
@CharlesSrstka 主线程 - lagoon
2个回答

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

如果您有任何问题或仍然无法正常工作,请发布您的播放器的完整代码,以便我们能够帮助您。 - cwilliamsz
我不理解这段代码在做什么,或者应该做什么,也不了解其中的任何部分。 - user5306470

0

func setNowPlaying(_ dura: Float, timePlayed: Float) 应该由一个 Timer 调用。

func setNowPlaying(_ dura: Float, timePlayed: Float) 只是一个简单的方法,如果不调用它,它就不会更新。

你应该定期使用一个 Timer 来调用它,以更新当前播放时间。

通常情况下,播放器在运行时进度条也随之更新。你可以在相同的计时器方法中调用 func setNowPlaying(_ dura: Float, timePlayed: Float)


1
这是一个不好的想法。根据苹果文档:值是配置为双精度的NSNumber对象。经过系统自动计算,已经提供的流逝时间和播放速率确定了经过的时间。不要频繁更新此属性——这是不必要的。https://developer.apple.com/documentation/mediaplayer/mpnowplayinginfopropertyelapsedplaybacktime - Darkisa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接