14

アプリで再生されるオーディオ トラックを変更し、新しいトラックを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更新を行う方法はありますか?AVPlayerItemTimeJumpedNotificationsetTrackNumber

4

6 に答える 6

1

このコードを試していただけますか?これは私の例ではうまくいきました...

override func viewDidLoad() {
super.viewDidLoad()

if NSClassFromString("MPNowPlayingInfoCenter") != nil {
    let albumArt = MPMediaItemArtwork(image: image) // any image
    var songInfo: NSMutableDictionary = [
        MPMediaItemPropertyTitle: "Whatever",
        MPMediaItemPropertyArtist: "Whatever",
        MPMediaItemPropertyArtwork: albumArt
    ]
    MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo = songInfo as [NSObject : AnyObject]
}
try! AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, withOptions: [])
   try! AVAudioSession.sharedInstance().setActive(true)
}

説明: MPNowPlayingInfo がバックグラウンドに移行するため、アクティブになっているかどうかを確認する必要があります。バックグラウンドにある場合は、次のコード行を実行するアクティブにする必要があります。

try! AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, withOptions: [])
       try! AVAudioSession.sharedInstance().setActive(true)

それがうまくいった場合は私に書いてください...

編集

これが機能しない場合は、このコードを試すこともできますが、上記のコードはより最新のソリューションです

if (AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, error: nil)) {
    println("Receiving remote control events")
    UIApplication.sharedApplication().beginReceivingRemoteControlEvents()
} else {
    println("Audio Session error.")
}

ここでも、上記と同じようにアクティブにしようとしています。これは動作しない可能性がある古いバージョンです...

于 2016-02-08T00:49:01.337 に答える
0

上記の回答についてコメントすることはできませんが、MPRemoteCommandCenter を使用する場合、リモート イベントを呼び出し-[UIApplication beginReceivingRemoteControlEvents]たり処理したりする必要はありません。-[UIResponder becomeFirstResponder]上記の回答は、推奨されなくなった古い実装を参照しています。

nowPlayingInfo ディクショナリにできるだけ多くのキーを設定することをお勧めします。MPMediaItemPropertyPlaybackDurationMPNowPlayingInfoPropertyPlaybackRate、およびMPNowPlayingInfoPropertyElapsedPlaybackTimeMPNowPlayingInfoCenter が更新されるかどうかに影響を与える可能性があります。

于 2016-02-07T22:09:19.100 に答える