简体   繁体   English

MPMusicPlayerController 无法从 Apple Music 播放

[英]MPMusicPlayerController fails to play from Apple Music

I'm trying to play songs from Apple Music and it is failing with the following logs:我正在尝试播放 Apple Music 中的歌曲,但失败并显示以下日志:

2019-09-26 00:15:57.790999+0200 [1886:463973] [core] "Error returned from daemon: Error Domain=com.apple.accounts Code=9 "(null)""
2019-09-26 00:15:57.791129+0200 [1886:463973] SSAccountStore: Failed to fetch the backing accounts. error = Error Domain=com.apple.accounts Code=9 "(null)"
2019-09-26 00:15:57.792655+0200 [1886:464074] [core] "Error returned from daemon: Error Domain=com.apple.accounts Code=9 "(null)""
2019-09-26 00:15:57.792770+0200 [1886:464074] SSAccountStore: Failed to fetch the backing accounts. error = Error Domain=com.apple.accounts Code=9 "(null)"
2019-09-26 00:15:57.794124+0200 [1886:464074] SSAccountStore: Unable to get the local account. error = Error Domain=SSErrorDomain Code=100 "Cannot connect to iTunes Store" UserInfo={NSLocalizedDescription=Cannot connect to iTunes Store}
2019-09-26 00:15:59.670842+0200 [1886:463973] [SDKPlayback] -[MPMusicPlayerController prependQueueDescriptor] completed id=applicationMusicPlayer error: Error Domain=MPCPlayerRequestErrorDomain Code=1 "No commands provided." UserInfo={NSDebugDescription=No commands provided.}
2019-09-26 00:15:59.671051+0200 [1886:463973] [SDKPlayback] -[MPMusicPlayerController prepareToPlay] completed id=applicationMusicPlayer error: Error Domain=MPMusicPlayerControllerErrorDomain Code=1 "prepareToPlay without a queue" UserInfo={NSDebugDescription=prepareToPlay without a queue}
2019-09-26 00:15:59.681627+0200 [1886:464074] [MediaRemote] MRC <MPCPlayerPath: route=<MPAVEndpointRoute: 0x282930a80 name=iPhone uid=LOCAL> origin=Nastasia's iPhone-1280262988 bundleID=com.apple.MediaPlayer.RemotePlayerService playerID=MPMusicPlayerApplicationController>: Undo optimistic state [failed] command=Play error=Error Domain=MPCPlayerRequestErrorDomain Code=1000 "Failed to send command 0 (MRMediaRemoteCommandHandlerStatus = 1)" UserInfo={NSDebugDescription=Failed to send command 0 (MRMediaRemoteCommandHandlerStatus = 1), MPCPlayerErrorKeyMediaRemoteCommandHandlerStatus=1}
2019-09-26 00:15:59.681787+0200 [1886:464074] [SDKPlayback] -[MPMusicPlayerController play] completed id=applicationMusicPlayer error: Error Domain=MPCPlayerRequestErrorDomain Code=1000 "Failed to send command 0" UserInfo={NSDebugDescription=Failed to send command 0, NSUnderlyingError=0x281319230 {Error Domain=MPCPlayerRequestErrorDomain Code=1000 "Failed to send command 0 (MRMediaRemoteCommandHandlerStatus = 1)" UserInfo={NSDebugDescription=Failed to send command 0 (MRMediaRemoteCommandHandlerStatus = 1), MPCPlayerErrorKeyMediaRemoteCommandHandlerStatus=1}}}
2019-09-26 00:16:03.596320+0200 [1886:464071] [core] "Error returned from daemon: Error Domain=com.apple.accounts Code=9 "(null)""
2019-09-26 00:16:03.596374+0200 [1886:464071] SSAccountStore: Failed to fetch the backing accounts. error = Error Domain=com.apple.accounts Code=9 "(null)"
2019-09-26 00:16:03.597965+0200 1886:464051] [core] "Error returned from daemon: Error Domain=com.apple.accounts Code=9 "(null)""
2019-09-26 00:16:03.598079+0200 [1886:464051] SSAccountStore: Failed to fetch the backing accounts. error = Error Domain=com.apple.accounts Code=9 "(null)"
2019-09-26 00:16:03.599416+0200 [1886:464074] [core] "Error returned from daemon: Error Domain=com.apple.accounts Code=9 "(null)""
2019-09-26 00:16:03.599456+0200 [1886:464074] SSAccountStore: Failed to fetch the backing accounts. error = Error Domain=com.apple.accounts Code=9 "(null)"
2019-09-26 00:16:03.599542+0200 [1886:464074] SSAccountStore: Unable to get the local account. error = Error Domain=SSErrorDomain Code=100 "Cannot connect to iTunes Store" UserInfo={NSLocalizedDescription=Cannot connect to iTunes Store}

I also tried the official sample code project from Apple called Adding-Content-to-Apple-Music , and got similar results:我还尝试了来自 Apple 的名为Adding-Content-to-Apple-Music的官方示例代码项目,并得到了类似的结果:


2019-09-25 23:20:37.268162+0200 [1738:432623] [RemoteControl] userIdentityForMediaRemoteOptions -❗️No user identity data. Using active account.
2019-09-25 23:20:37.333703+0200 [1738:432751] [SDKPlayback] -[MPMusicPlayerController prepareToPlayWithCompletionHandler:] completed id=applicationMusicPlayer error: Error Domain=MPCPlayerRequestErrorDomain Code=1000 "Failed to send command 122" UserInfo={NSDebugDescription=Failed to send command 122, NSUnderlyingError=0x282eacff0 {Error Domain=MPCPlayerRequestErrorDomain Code=1000 "Failed to send command 122 (MRMediaRemoteCommandHandlerStatus = 2)" UserInfo={NSDebugDescription=Failed to send command 122 (MRMediaRemoteCommandHandlerStatus = 2), MPCPlayerErrorKeyMediaRemoteCommandHandlerStatus=2}}}
2019-09-25 23:20:37.333721+0200 [1738:432562] [SDKPlayback] -[MPMusicPlayerController prepareToPlay] completed id=applicationMusicPlayer error: Error Domain=MPCPlayerRequestErrorDomain Code=1000 "Failed to send command 122" UserInfo={NSDebugDescription=Failed to send command 122, NSUnderlyingError=0x282eacff0 {Error Domain=MPCPlayerRequestErrorDomain Code=1000 "Failed to send command 122 (MRMediaRemoteCommandHandlerStatus = 2)" UserInfo={NSDebugDescription=Failed to send command 122 (MRMediaRemoteCommandHandlerStatus = 2), MPCPlayerErrorKeyMediaRemoteCommandHandlerStatus=2}}}
2019-09-25 23:20:37.337138+0200 [1738:432546] [MediaRemote] MRC <MPCPlayerPath: route=<MPAVEndpointRoute: 0x281498a80 name=iPhone uid=LOCAL> origin=Nastasia's iPhone-1280262988 bundleID=com.apple.MediaPlayer.RemotePlayerService playerID=MPMusicPlayerApplicationController>: Undo optimistic state [failed] command=Play error=Error Domain=MPCPlayerRequestErrorDomain Code=1000 "Failed to send command 0 (MRMediaRemoteCommandHandlerStatus = 1)" UserInfo={NSDebugDescription=Failed to send command 0 (MRMediaRemoteCommandHandlerStatus = 1), MPCPlayerErrorKeyMediaRemoteCommandHandlerStatus=1}
2019-09-25 23:20:37.337529+0200 [1738:432562] [SDKPlayback] -[MPMusicPlayerController play] completed id=applicationMusicPlayer error: Error Domain=MPCPlayerRequestErrorDomain Code=1000 "Failed to send command 0" UserInfo={NSDebugDescription=Failed to send command 0, NSUnderlyingError=0x282ead260 {Error Domain=MPCPlayerRequestErrorDomain Code=1000 "Failed to send command 0 (MRMediaRemoteCommandHandlerStatus = 1)" UserInfo={NSDebugDescription=Failed to send command 0 (MRMediaRemoteCommandHandlerStatus = 1), MPCPlayerErrorKeyMediaRemoteCommandHandlerStatus=1}}}
2019-09-25 23:20:37.342424+0200 [1738:432623] [Middleware] INVALIDATE: 0x2813842d0: Invalidated before returning a response. Re-requesting items.
2019-09-25 23:20:38.144321+0200 [1738:432323] [SDKPlayback] Failed validators id=applicationMusicPlayer: {(
    play
)}
2019-09-25 23:20:38.944291+0200 [1738:432323] [SDKPlayback] Failed to get a valid response. Resetting expectations id=applicationMusicPlayer

The issue is sometimes randomly fixed by playing around with apps, going to Apple Music app, playing something there, killing it, coming back, and so on...这个问题有时会通过玩应用程序、转到 Apple Music 应用程序、在那里播放一些东西、杀死它、回来等等来随机解决......

If someone has experienced similar issues then please let me know how to fix it.如果有人遇到过类似的问题,请告诉我如何解决。

Happens on iOS 12 & 13, iPhone 6s and iPhone 11, Apple Music account is in 3 months trial currently.发生在 iOS 12 和 13、iPhone 6s 和 iPhone 11 上,Apple Music 帐户目前处于 3 个月的试用期。 All the music capabilities are present, being able to successfully get the developer token and music user token, both work fine with Apple Music API requests.所有音乐功能都存在,能够成功获取开发者令牌和音乐用户令牌,两者都可以与 Apple Music API 请求一起正常工作。

Seems like one of the reasons can be that I use musicPlayerController.prepend() function instead of setQueue() .似乎原因之一可能是我使用musicPlayerController.prepend() function 而不是setQueue() Unfortunately, I was forced to use prepend() because of music player limitations.不幸的是,由于音乐播放器的限制,我被迫使用prepend()

Here is a short description of what my app needs to do:以下是我的应用需要做什么的简短描述:

  • The user starts playing a list of songs.用户开始播放歌曲列表。
  • During the playback the app fetches a new list of songs from backend every 5-10 seconds and sets it as the new song queue.在播放期间,应用程序每 5-10 秒从后端获取新的歌曲列表,并将其设置为新歌曲队列。 That means it is quite dynamic by means of what plays next.这意味着接下来播放的内容非常动态。

Now when it comes to setting a new queue during playback, setQueue() is really bad at it.现在在播放期间设置新队列时, setQueue()真的很糟糕。 If I just call setQueue() then nothing will happen, the old queue will stay.如果我只是调用setQueue()那么什么都不会发生,旧队列将保留。 However, if I call play() or prepareToPlay() after setQueue() then current playback will be stopped and the first song of the new queue will start playing.但是,如果我在 setQueue() 之后调用play()prepareToPlay() setQueue()则当前播放将停止,新队列的第一首歌曲将开始播放。 That's not what I want, I need to change the queue "behind the scenes" so that when the user hits "skip to next" in the app or iOS lock screen, then the new songs are playing.这不是我想要的,我需要在“幕后”更改队列,以便当用户在应用程序或 iOS 锁定屏幕中点击“跳到下一个”时,新歌曲正在播放。 That's why I used prepend() - it works just fine, the current playback is not interrupted.这就是我使用prepend()的原因 - 它工作得很好,当前播放不会中断。 The alternative - calling perform() on applicationQueuePlayer crashes with message "it takes too long" - deleting the old queue of 30 songs manually item-by-item is not that optimal, I guess.另一种选择——在 applicationQueuePlayer 上调用perform()时会崩溃并显示“它需要很长时间”的消息——我猜,手动逐项删除 30 首歌曲的旧队列并不是最优的。

So currently I see only one option - manually store a state which will tell if this is the first run or not.所以目前我只看到一个选项 - 手动存储 state 它将判断这是否是第一次运行。 If yes, then call setQueue() , otherwise call prepend() .如果是,则调用setQueue() ,否则调用prepend() There is also no way to get the current queue to check myself if it is empty or not.也没有办法让当前队列检查自己是否为空。

And regarding play() - it comes out to be not as simple function, as it seems.而关于play() - 它并不像看起来那样简单 function。 As I already mentioned above, play() triggers the new queue playback if I ever called setQueue() before.正如我上面已经提到的,如果我之前调用过setQueue()play()会触发新的队列播放。 It was bringing me more problems because when I was calling setQueue() without play() , it was not doing anything, however each time I pressed pause/play - the player was jumping to the next song thanks to the earlier "silent" setQueue() .它给我带来了更多问题,因为当我在没有play() ) 的情况下调用setQueue() ) 时,它什么也没做,但是每次我按下暂停/播放时 - 由于早期的“静音” setQueue() ,播放器正在跳转到下一首歌曲setQueue() I had to implement another workaround of calling player.currentPlaybackRate = 1 instead of player.play() , which doesn't look nice.我不得不实现另一种调用player.currentPlaybackRate = 1而不是player.play()的解决方法,这看起来不太好。 It would be great, if all this was somehow documented.如果所有这些都以某种方式记录下来,那就太好了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM