アプリで再生されるオーディオ トラックを変更し、新しいトラックをAVPlayer
設定するメソッドがあります。MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo
func setTrackNumber(trackNum: Int) {
self.trackNum = trackNum
player.replaceCurrentItemWithPlayerItem(tracks[trackNum])
var nowPlayingInfo: [String: AnyObject] = [ : ]
nowPlayingInfo[MPMediaItemPropertyAlbumTitle] = tracks[trackNum].albumTitle
nowPlayingInfo[MPMediaItemPropertyTitle] = "Track \(trackNum)"
...
MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo = nowPlayingInfo
print("Now playing local: \(nowPlayingInfo)")
print("Now playing lock screen: \(MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo)")
}
ユーザーがアルバムまたはトラックを明示的に選択したとき、およびトラックが終了して次のトラックが自動的に開始されたときに、このメソッドを呼び出します。ユーザーがアルバムまたはトラックを設定すると、ロック画面にトラックのメタデータが正しく表示されますが、トラックが終了して次のトラックが自動的に設定されると表示されません。
nowPlayingInfo
ディクショナリに正しく入力していることを確認するために、print ステートメントを追加しました。予想どおり、ユーザーが開始したアルバムまたはトラックの変更に対してこのメソッドが呼び出されると、2 つの print ステートメントは同じ辞書コンテンツを出力します。ただし、自動トラック変更後にメソッドが呼び出された場合、ローカルnowPlayingInfo
変数は新しいものをtrackNum
示しMPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo
、以前のものを示しますtrackNum
。
Now playing local: ["title": Track 9, "albumTitle": Test Album, ...]
Now playing set: Optional(["title": Track 8, "albumTitle": Test Album, ...]
に設定されている行にブレークポイントを設定MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo
するとnowPlayingInfo
、ロック画面でトラック番号が正しく更新されることがわかりました。sleep(1)
その行の直後に追加すると、ロック画面のトラックが正しく更新されます。
nowPlayingInfo
常にメイン キューから設定されることを確認しました。このコードをメイン キューまたは別のキューで明示的に実行しようとしましたが、動作は変わりません。
への変更を妨げているのは何MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo
ですか? MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo
設定によって常にロック画面情報が更新されるようにするにはどうすればよいですか?
編集
「並行性」を考えてN回目のコードを調べた後、犯人を見つけました。なぜ私はこれについて以前に疑わなかったのかわかりません:
func playerTimeJumped() {
let currentTime = currentItem().currentTime()
dispatch_async(dispatch_get_main_queue()) {
MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo?[MPNowPlayingInfoPropertyElapsedPlaybackTime] = CMTimeGetSeconds(currentTime)
}
}
NSNotificationCenter.defaultCenter().addObserver(
self,
selector: "playerTimeJumped",
name: AVPlayerItemTimeJumpedNotification,
object: nil)
このコードは、ユーザーがスクラブまたは前後にスキップしたときに経過したロック画面の時間を更新します。コメントアウトすると、nowPlayingInfo
からの更新はsetTrackNumber
どのような条件下でも期待どおりに機能します。
改訂された質問: これら 2 つのコードは、両方ともメイン キューで実行されている場合、どのように相互作用しますか? の呼び出しがあるときにジャンプが発生することを考えると、nowPlayingInfo
更新を行う方法はありますか?AVPlayerItemTimeJumpedNotification
setTrackNumber