refactor(ios): refactor NowPlayingInfoCenerManager.swift (#3968)

* refactor(ios): refactor NowPlayingInfoCenerManager

* fix(ios): fix lint error
This commit is contained in:
YangJH 2024-07-04 19:11:12 +09:00 committed by GitHub
parent 530686ca82
commit 76c6329110
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -19,6 +19,8 @@ class NowPlayingInfoCenterManager {
private var playbackPositionTarget: Any? private var playbackPositionTarget: Any?
private var seekTarget: Any? private var seekTarget: Any?
private let remoteCommandCenter = MPRemoteCommandCenter.shared()
private var receivingRemoveControlEvents = false { private var receivingRemoveControlEvents = false {
didSet { didSet {
if receivingRemoveControlEvents { if receivingRemoveControlEvents {
@ -86,8 +88,7 @@ class NowPlayingInfoCenterManager {
currentPlayer?.removeTimeObserver(playbackObserver) currentPlayer?.removeTimeObserver(playbackObserver)
} }
let commandCenter = MPRemoteCommandCenter.shared() invalidateCommandTargets()
invalidateTargets(commandCenter)
MPNowPlayingInfoCenter.default().nowPlayingInfo = [:] MPNowPlayingInfoCenter.default().nowPlayingInfo = [:]
receivingRemoveControlEvents = false receivingRemoveControlEvents = false
@ -103,7 +104,7 @@ class NowPlayingInfoCenterManager {
} }
currentPlayer = player currentPlayer = player
registerTargets() registerCommandTargets()
updateMetadata() updateMetadata()
@ -117,12 +118,10 @@ class NowPlayingInfoCenterManager {
) )
} }
private func registerTargets() { private func registerCommandTargets() {
let commandCenter = MPRemoteCommandCenter.shared() invalidateCommandTargets()
invalidateTargets(commandCenter) playTarget = remoteCommandCenter.playCommand.addTarget { [weak self] _ in
playTarget = commandCenter.playCommand.addTarget { [weak self] _ in
guard let self, let player = self.currentPlayer else { guard let self, let player = self.currentPlayer else {
return .commandFailed return .commandFailed
} }
@ -134,7 +133,7 @@ class NowPlayingInfoCenterManager {
return .success return .success
} }
pauseTarget = commandCenter.pauseCommand.addTarget { [weak self] _ in pauseTarget = remoteCommandCenter.pauseCommand.addTarget { [weak self] _ in
guard let self, let player = self.currentPlayer else { guard let self, let player = self.currentPlayer else {
return .commandFailed return .commandFailed
} }
@ -146,7 +145,7 @@ class NowPlayingInfoCenterManager {
return .success return .success
} }
skipBackwardTarget = commandCenter.skipBackwardCommand.addTarget { [weak self] _ in skipBackwardTarget = remoteCommandCenter.skipBackwardCommand.addTarget { [weak self] _ in
guard let self, let player = self.currentPlayer else { guard let self, let player = self.currentPlayer else {
return .commandFailed return .commandFailed
} }
@ -155,7 +154,7 @@ class NowPlayingInfoCenterManager {
return .success return .success
} }
skipForwardTarget = commandCenter.skipForwardCommand.addTarget { [weak self] _ in skipForwardTarget = remoteCommandCenter.skipForwardCommand.addTarget { [weak self] _ in
guard let self, let player = self.currentPlayer else { guard let self, let player = self.currentPlayer else {
return .commandFailed return .commandFailed
} }
@ -165,7 +164,7 @@ class NowPlayingInfoCenterManager {
return .success return .success
} }
playbackPositionTarget = commandCenter.changePlaybackPositionCommand.addTarget { [weak self] event in playbackPositionTarget = remoteCommandCenter.changePlaybackPositionCommand.addTarget { [weak self] event in
guard let self, let player = self.currentPlayer else { guard let self, let player = self.currentPlayer else {
return .commandFailed return .commandFailed
} }
@ -179,63 +178,43 @@ class NowPlayingInfoCenterManager {
} }
} }
private func invalidateTargets(_ commandCenter: MPRemoteCommandCenter) { private func invalidateCommandTargets() {
commandCenter.playCommand.removeTarget(playTarget) remoteCommandCenter.playCommand.removeTarget(playTarget)
commandCenter.pauseCommand.removeTarget(pauseTarget) remoteCommandCenter.pauseCommand.removeTarget(pauseTarget)
commandCenter.skipForwardCommand.removeTarget(skipForwardTarget) remoteCommandCenter.skipForwardCommand.removeTarget(skipForwardTarget)
commandCenter.skipBackwardCommand.removeTarget(skipBackwardTarget) remoteCommandCenter.skipBackwardCommand.removeTarget(skipBackwardTarget)
commandCenter.changePlaybackPositionCommand.removeTarget(playbackPositionTarget) remoteCommandCenter.changePlaybackPositionCommand.removeTarget(playbackPositionTarget)
} }
public func updateMetadata() { public func updateMetadata() {
guard let player = currentPlayer, let currentItem = player.currentItem else { guard let player = currentPlayer, let currentItem = player.currentItem else {
let commandCenter = MPRemoteCommandCenter.shared() invalidateCommandTargets()
invalidateTargets(commandCenter)
MPNowPlayingInfoCenter.default().nowPlayingInfo = [:] MPNowPlayingInfoCenter.default().nowPlayingInfo = [:]
return return
} }
// commonMetadata is metadata from asset, externalMetadata is custom metadata set by user // commonMetadata is metadata from asset, externalMetadata is custom metadata set by user
let metadata = currentItem.asset.commonMetadata + currentItem.externalMetadata let metadata = currentItem.asset.commonMetadata + currentItem.externalMetadata
var nowPlayingInfo: [String: Any] = [:]
if let titleItem = AVMetadataItem.metadataItems(from: metadata, filteredByIdentifier: .commonIdentifierTitle).first?.value { let titleItem = AVMetadataItem.metadataItems(from: metadata, filteredByIdentifier: .commonIdentifierTitle).first?.stringValue ?? ""
nowPlayingInfo[MPMediaItemPropertyTitle] = titleItem
} else {
nowPlayingInfo[MPMediaItemPropertyTitle] = ""
}
if let artistItem = AVMetadataItem.metadataItems(from: metadata, filteredByIdentifier: .commonIdentifierArtist).first?.value { let artistItem = AVMetadataItem.metadataItems(from: metadata, filteredByIdentifier: .commonIdentifierArtist).first?.stringValue ?? ""
nowPlayingInfo[MPMediaItemPropertyArtist] = artistItem
} else {
nowPlayingInfo[MPMediaItemPropertyArtist] = ""
}
// I have some issue with this - setting artworkItem when it not set dont return nil but also is crashing application // I have some issue with this - setting artworkItem when it not set dont return nil but also is crashing application
// this is very hacky workaround for it // this is very hacky workaround for it
if let artworkItem = AVMetadataItem.metadataItems(from: metadata, filteredByIdentifier: .commonIdentifierArtwork).first?.value as? Data { let imgData = AVMetadataItem.metadataItems(from: metadata, filteredByIdentifier: .commonIdentifierArtwork).first?.dataValue
if let image = UIImage(data: artworkItem) { let image = imgData.flatMap { UIImage(data: $0) } ?? UIImage()
nowPlayingInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: image.size, requestHandler: { _ in let artworkItem = MPMediaItemArtwork(boundsSize: image.size) { _ in image }
return image
})
}
} else {
nowPlayingInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: UIImage().size, requestHandler: { _ in
UIImage()
})
}
if CMTIME_IS_INDEFINITE(currentItem.asset.duration) { let nowPlayingInfo: [String: Any] = [
nowPlayingInfo[MPNowPlayingInfoPropertyIsLiveStream] = true MPMediaItemPropertyTitle: titleItem,
} else { MPMediaItemPropertyArtist: artistItem,
nowPlayingInfo[MPNowPlayingInfoPropertyIsLiveStream] = false MPMediaItemPropertyArtwork: artworkItem,
} MPMediaItemPropertyPlaybackDuration: currentItem.duration.seconds,
MPNowPlayingInfoPropertyElapsedPlaybackTime: currentItem.currentTime().seconds.rounded(),
nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = currentItem.duration.seconds MPNowPlayingInfoPropertyPlaybackRate: player.rate,
nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = currentItem.currentTime().seconds MPNowPlayingInfoPropertyIsLiveStream: CMTIME_IS_INDEFINITE(currentItem.asset.duration),
nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = player.rate ]
nowPlayingInfo[MPNowPlayingInfoPropertyMediaType] = MPNowPlayingInfoMediaType.video.rawValue
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
} }
@ -247,15 +226,15 @@ class NowPlayingInfoCenterManager {
// We dont want to update playback if we did not set metadata yet // We dont want to update playback if we did not set metadata yet
if var nowPlayingInfo = MPNowPlayingInfoCenter.default().nowPlayingInfo { if var nowPlayingInfo = MPNowPlayingInfoCenter.default().nowPlayingInfo {
nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = currentItem.duration.seconds let newNowPlayingInfo: [String: Any] = [
nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = currentItem.currentTime().seconds.rounded() MPMediaItemPropertyPlaybackDuration: currentItem.duration.seconds,
nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = player.rate MPNowPlayingInfoPropertyElapsedPlaybackTime: currentItem.currentTime().seconds.rounded(),
MPNowPlayingInfoPropertyPlaybackRate: player.rate,
MPNowPlayingInfoPropertyIsLiveStream: CMTIME_IS_INDEFINITE(currentItem.asset.duration),
]
nowPlayingInfo.merge(newNowPlayingInfo) { _, v in v }
if CMTIME_IS_INDEFINITE(currentItem.asset.duration) {
nowPlayingInfo[MPNowPlayingInfoPropertyIsLiveStream] = true
} else {
nowPlayingInfo[MPNowPlayingInfoPropertyIsLiveStream] = false
}
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
} }
} }