fix(ios): metadata update race (#4033)

* fix metadata update race

* merge nowPlayingInfo instead of overriding it

* update method name

* fix code style
This commit is contained in:
Błażej Lewandowski 2024-08-02 10:49:52 +02:00 committed by GitHub
parent 2348c5e42c
commit 08a57a3ba3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 9 additions and 30 deletions

View File

@ -72,7 +72,7 @@ class NowPlayingInfoCenterManager {
if currentPlayer == player { if currentPlayer == player {
currentPlayer = nil currentPlayer = nil
updateMetadata() updateNowPlayingInfo()
} }
if players.allObjects.isEmpty { if players.allObjects.isEmpty {
@ -106,14 +106,12 @@ class NowPlayingInfoCenterManager {
currentPlayer = player currentPlayer = player
registerCommandTargets() registerCommandTargets()
updateMetadata() updateNowPlayingInfo()
// one second observer
playbackObserver = player.addPeriodicTimeObserver( playbackObserver = player.addPeriodicTimeObserver(
forInterval: CMTime(value: 1, timescale: 4), forInterval: CMTime(value: 1, timescale: 4),
queue: .global(), queue: .global(),
using: { [weak self] _ in using: { [weak self] _ in
self?.updatePlaybackInfo() self?.updateNowPlayingInfo()
} }
) )
} }
@ -186,7 +184,7 @@ class NowPlayingInfoCenterManager {
remoteCommandCenter.changePlaybackPositionCommand.removeTarget(playbackPositionTarget) remoteCommandCenter.changePlaybackPositionCommand.removeTarget(playbackPositionTarget)
} }
public func updateMetadata() { public func updateNowPlayingInfo() {
guard let player = currentPlayer, let currentItem = player.currentItem else { guard let player = currentPlayer, let currentItem = player.currentItem else {
invalidateCommandTargets() invalidateCommandTargets()
MPNowPlayingInfoCenter.default().nowPlayingInfo = [:] MPNowPlayingInfoCenter.default().nowPlayingInfo = [:]
@ -206,7 +204,7 @@ class NowPlayingInfoCenterManager {
let image = imgData.flatMap { UIImage(data: $0) } ?? UIImage() let image = imgData.flatMap { UIImage(data: $0) } ?? UIImage()
let artworkItem = MPMediaItemArtwork(boundsSize: image.size) { _ in image } let artworkItem = MPMediaItemArtwork(boundsSize: image.size) { _ in image }
let nowPlayingInfo: [String: Any] = [ let newNowPlayingInfo: [String: Any] = [
MPMediaItemPropertyTitle: titleItem, MPMediaItemPropertyTitle: titleItem,
MPMediaItemPropertyArtist: artistItem, MPMediaItemPropertyArtist: artistItem,
MPMediaItemPropertyArtwork: artworkItem, MPMediaItemPropertyArtwork: artworkItem,
@ -215,28 +213,9 @@ class NowPlayingInfoCenterManager {
MPNowPlayingInfoPropertyPlaybackRate: player.rate, MPNowPlayingInfoPropertyPlaybackRate: player.rate,
MPNowPlayingInfoPropertyIsLiveStream: CMTIME_IS_INDEFINITE(currentItem.asset.duration), MPNowPlayingInfoPropertyIsLiveStream: CMTIME_IS_INDEFINITE(currentItem.asset.duration),
] ]
let currentNowPlayingInfo = MPNowPlayingInfoCenter.default().nowPlayingInfo ?? [:]
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo MPNowPlayingInfoCenter.default().nowPlayingInfo = currentNowPlayingInfo.merging(newNowPlayingInfo) { _, new in new }
}
private func updatePlaybackInfo() {
guard let player = currentPlayer, let currentItem = player.currentItem else {
return
}
// We dont want to update playback if we did not set metadata yet
if var nowPlayingInfo = MPNowPlayingInfoCenter.default().nowPlayingInfo {
let newNowPlayingInfo: [String: Any] = [
MPMediaItemPropertyPlaybackDuration: currentItem.duration.seconds,
MPNowPlayingInfoPropertyElapsedPlaybackTime: currentItem.currentTime().seconds.rounded(),
MPNowPlayingInfoPropertyPlaybackRate: player.rate,
MPNowPlayingInfoPropertyIsLiveStream: CMTIME_IS_INDEFINITE(currentItem.asset.duration),
]
nowPlayingInfo.merge(newNowPlayingInfo) { _, v in v }
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
}
} }
private func findNewCurrentPlayer() { private func findNewCurrentPlayer() {

View File

@ -490,8 +490,8 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
} else { } else {
_player?.replaceCurrentItem(with: playerItem) _player?.replaceCurrentItem(with: playerItem)
// later we can just call "updateMetadata: // later we can just call "updateNowPlayingInfo:
NowPlayingInfoCenterManager.shared.updateMetadata() NowPlayingInfoCenterManager.shared.updateNowPlayingInfo()
} }
_playerObserver.player = _player _playerObserver.player = _player