播放/暂停和已用时间未在iOS命令中心正确更新 [英] Play/Pause and Elapsed Time not updating in iOS command center properly

查看:606
本文介绍了播放/暂停和已用时间未在iOS命令中心正确更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个可以从iOS命令中心和锁定屏幕播放的视频播放器。当我在我的应用程序中切换播放/暂停按钮时,它应该通过更新 nowPlayingInfo更新命令中心中的播放/暂停按钮( MPRemoteCommandCenter MPNowPlayingInfoCenter )。我不确定为什么它没有更新。

I have a video player that can play from the iOS command center and lock screen. When I toggle a play/pause button in my app, it should update the play/pause button in the command center (MPRemoteCommandCenter) by updating the nowPlayingInfo (MPNowPlayingInfoCenter). I'm not sure why it's not updating.

例如,如果我在我的应用程序中使用自定义按钮暂停视频,则命令中心仍会显示暂停按钮(意味着视频仍在播放,这是错误的。 )

For example, if I pause the video with a custom button in my app, the command center still shows the pause button (meaning the video is still playing which is wrong.)

这是我更新<$的方式c $ c> nowPlayingInfo :

func updateMPNowPlayingInforCenterMetadata() {
    guard video != nil else {
        nowPlayingInfoCenter.nowPlayingInfo = nil
        return
    }

    var nowPlayingInfo = nowPlayingInfoCenter.nowPlayingInfo ?? [String: Any]()

    let image: UIImage
    if let placeholderLocalURL = video.placeholderLocalURL, let placeholderImage = UIImage(contentsOfFile: placeholderLocalURL.path) {
        image = placeholderImage
    } else {
        image = UIImage()
    }

    let artwork = MPMediaItemArtwork(boundsSize: image.size, requestHandler: { _ -> UIImage in
        return image
    })

    nowPlayingInfo[MPMediaItemPropertyTitle] = video.title
    nowPlayingInfo[MPMediaItemPropertyAlbumTitle] = video.creator?.name ?? " "
    nowPlayingInfo[MPMediaItemPropertyArtwork] = artwork

    nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = Float(video.duration)
    nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = Float(currentTime) // CMTimeGetSeconds(player.currentItem!.currentTime())
    nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = player.rate
    nowPlayingInfo[MPNowPlayingInfoPropertyDefaultPlaybackRate] = player.rate

    nowPlayingInfoCenter.nowPlayingInfo = nowPlayingInfo

    if player.rate == 0.0 {
        state = .paused
    } else {
        state = .playing
    }
}

使用KVO,当玩家的汇率发生变化时,我会调用此函数:

With KVO, when the player's rate changes, I call this function:

// MARK: - Key-Value Observing Method

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    guard context == &assetPlaybackManagerKVOContext else {
        super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
        return
    }

    } else if keyPath == #keyPath(AVPlayer.rate) {
        updateMPNowPlayingInforCenterMetadata()
    }
}

有什么想法?

I虽然找到了解决方案但在我的情况下并不完美。所以在我的应用程序中我有2个视图控制器。我们称之为 FeedVC PlayerVC 。所以 FeedVC AVPlayer ,它们总是在播放但是静音。如果单击其中一个,则会创建 PlayerVC 并播放完整视频。 如果我在 FeedVC 中暂停 AVPlayer 之后再转到 PlayerVC 然后NowPlayingInfoCenter中的播放/暂停按钮完美运行!

I found a solution though but not perfect in my case. So in my app I have 2 view controller's. Let's call them FeedVC and PlayerVC. So FeedVC has AVPlayer's that are always playing but are muted. If you click on one of them, then the PlayerVC is created and plays the full video. If I pause the AVPlayer's in FeedVC before going to PlayerVC then the "play/pause" button in the NowPlayingInfoCenter works perfectly!

有没有办法让这项工作无需暂停 FeedVC 中的视频?

Is there a way to make this work without having to pause the videos in the FeedVC?

另一个问题是已用时间如果我不暂停 FeedVC 中的玩家,则会继续计算。似乎如果正在播放多个玩家,则播放/暂停按钮和已用时间不正确。

Another issue is that the elapsed time keeps counting if I don't pause the players in the FeedVC. It seems that if multiple players are playing, the play/pause button and elapsed time are incorrect.

推荐答案

您为 nowPlayingInfo 设置字典时,您需要适当地设置 MPNowPlayingInfoPropertyPlaybackRate 值。 MPNowPlayingInfoCenter 预计 1.0 (正在播放)或 0.0 (不播放)包含在 NSNumber 对象中的 Double 值。下面你会找到我在项目中如何设置 nowPlayingInfo 的代码。

When you setting the dictionary for nowPlayingInfo you will want to set the MPNowPlayingInfoPropertyPlaybackRate value appropriately. The MPNowPlayingInfoCenter is expecting either a 1.0 (playing) or 0.0 (not playing) value as a Double wrapped in a NSNumber object. Below you will find the code for how I'm setting the nowPlayingInfo in my project.

func setNowPlayingMediaWith(song: SUSong, currentTime: Double?) {

    var playingInfo:[String: Any] = [:]

    if let title = song.title {
        playingInfo[MPMediaItemPropertyTitle] = title
    }

    if let songID = song.id {
        playingInfo[MPMediaItemPropertyPersistentID] = songID
    }
    if let artist = song.artist, let artistName = artist.name {
        playingInfo[MPMediaItemPropertyArtist] = artistName
    }

    if let album = song.album, let albumTitle = album.title {
        var artwork:MPMediaItemArtwork? = nil
        if let album = song.album, let artworkData = album.artwork {
            artwork = MPMediaItemArtwork(boundsSize: Constants.Library.Albums.thumbSize, requestHandler: { (size) -> UIImage in
                return UIImage(data: artworkData as Data)!
            })
        }
        if artwork != nil {
            playingInfo[MPMediaItemPropertyArtwork] = artwork!
        }
        playingInfo[MPMediaItemPropertyAlbumTitle] = albumTitle
    }

    var rate:Double = 0.0
    if let time = currentTime {
        playingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = time
        playingInfo[MPMediaItemPropertyPlaybackDuration] = song.duration
        rate = 1.0
    }
    playingInfo[MPNowPlayingInfoPropertyPlaybackRate] = NSNumber(value: rate)
    playingInfo[MPNowPlayingInfoPropertyMediaType] = NSNumber(value: MPNowPlayingInfoMediaType.audio.rawValue)
    MPNowPlayingInfoCenter.default().nowPlayingInfo = playingInfo
}

在这个方法中,我传递了我的播放器当前加载的歌曲。每当用户选择播放或暂停时,我都会调用 setNowPlayingMediaWith(song:currentTime:)来更新设备的控制台。

In this method I am passing the song that my player is has currently loaded. Whenever the user chooses to play or pause I call setNowPlayingMediaWith(song:currentTime:) to update the device's control console.

我跟踪 currentTime Double )作为我的球员的财产。如果传入 currentTime ,则表示我们打算播放,所以将 MPNowPlayingInfoPropertyPlaybackRate 设置为 1.0 并将 MPNowPlayingInfoPropertyElapsedPlaybackTime 设置为 currentTime 。这将设置当前开始在设备控制台中自动播放的时间。

I keep track of the currentTime (Double) as a property of my player. If there is a currentTime passed in that means we are meant to be playing, so set the MPNowPlayingInfoPropertyPlaybackRate to 1.0 and set the MPNowPlayingInfoPropertyElapsedPlaybackTime to currentTime. This will set the current time to start automatically playing in the device's control console.

同样,如果没有传递 currentTime ,那么我们已经停止或暂停了。在这种情况下,我们将 MPNowPlayingInfoPropertyPlaybackRate 0.0 ,我们不包括 MPNowPlayingInfoPropertyElapsedPlaybackTime

Likewise, if there is no currentTime passed then we have stopped or paused. In this case we set the MPNowPlayingInfoPropertyPlaybackRate to 0.0 and we do not include the MPNowPlayingInfoPropertyElapsedPlaybackTime.

下载我的应用程序以查看此操作。

Download my app to see this in action.

编辑(回复评论)

有没有办法让这项工作无需暂停FeedVC中的视频

没有看到你的代码很难给你一个明确的答案。在启动 PlayerVC 的媒体之前暂停任何正在进行的媒体是有意义的。

Without seeing your code it is difficult to give you a definite answer. It would make sense though to pause any ongoing media before starting your PlayerVC's media.

经过的时间不断计算

经过的时间将根据<$ c倒计时经过的时间$ c> NSTimer NowPlayingInfoCenter 上的属性。该定时器将停止,只有当定时器的值已经达到了您在 MPMediaItemPropertyPlaybackDuration 设置,或值在更新 MPNowPlayingInfoPropertyElapsedPlaybackTime

The elapsed time will countdown the elapsed time based on an NSTimer property on NowPlayingInfoCenter. This timer will stop only when the timers value has reached the value you set in MPMediaItemPropertyPlaybackDuration, or when you update the MPNowPlayingInfoPropertyElapsedPlaybackTime.

我的建议是写一个清除 NowPlayingInfoCenter 的方法。此方法应设置将所有键值分别设置为0.0或nil。每次在 PlayerVC 中播放媒体之前,请调用此清除方法。然后一旦你从 PlayerVC 玩游戏,设置 NowPlayingInfoCenter 键值,就像我在答案中粘贴的方法一样设置新播放媒体的新值。

My suggestion is to write a method that "clears out" the NowPlayingInfoCenter. This method should set the will set all of key values to either 0.0 or nil respectively. Call this "clear out" method each time before you play your media in PlayerVC. Then once you play from PlayerVC, set the NowPlayingInfoCenter key values like you would in the method I pasted in my answer to set the new values for the new playing media.

这篇关于播放/暂停和已用时间未在iOS命令中心正确更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆