我正在使用MPMusicPlayerController,因此我的应用可以播放用户通过iTunes购买的音乐。当我选择一首歌并开始播放时,声音开始前会有一段时间。我假设这首歌是从云缓存的。
问题是我还没有办法知道缓冲完成的时间和音频实际开始的时间。
播放我使用的歌曲:
_mediaController = [MPMusicPlayerController applicationMusicPlayer];
[_mediaController setQueueWithItemCollection:collection];
[_mediaController beginGeneratingPlaybackNotifications];
[_mediaController play];
一旦我打电话"播放",就会调用播放状态改变通知,播放状态为" MPMusicPlaybackStatePlaying"即使用户听不到任何音乐。我注意到即使mediaController在"播放"播放状态,_mediaController.currentPlaybackTime始终等于0,直到听到音乐,此时currentPlaybackTime正确地跟踪音乐。
我以为我可以使用[_mediaController prepareToPlay]方法预加载音频文件,但是当我使用它时,永远不会调用MPMediaPlaybackIsPreparedToPlayDidChangeNotification通知。所以mediaController从未被标记为"准备好了#34;。
说了这么多,我还没有找到使用MPMusicPlayerController预缓冲歌曲的方法。我知道这个问题已经存在了一段时间,因为几年前有old question基本相同的问题,但没有答案。有谁知道如何使这项工作?
答案 0 :(得分:0)
MPMediaPlaybackIsPreparedToPlayDidChangeNotification看起来已过时。
MPMediaPlayerController的获取器和通知是一种垃圾,在设置值的方式上根本不“一致”,并且期望再次获取该值时会返回相同的值。
我通过首先“缓冲”歌曲来解决此问题,因为我的应用经常会在歌曲中间开始播放。所以我的缓冲算法是-我将播放歌曲,然后等待播放状态更改的通知,然后再次暂停它并等待另一个通知。毫无疑问,此过程将触发MPMusicPlayerControllerNowPlayingItemDidChangeNotification,然后最终可以播放或更改歌曲(设置currentTime或Rate)。这似乎工作得很好。
prepareToPlay完成处理程序也是垃圾。在歌曲实际准备好播放之前似乎已经触发,并且该方法实际上似乎开始播放:(,这比它导致的结果还多。这在Apple dev论坛中通常被报告为“错误”。 / p>
在prepareToPlay回调中,设置currentPlaybackTime或Rate实际上不会使播放器发生变化-您需要在歌曲首次播放开始后的某个时间等待附加的MPMusicPlayerControllerNowPlayingItemDidChangeNotification,然后才能进行任何使任何变化的运气。播放器属性。
currentPlaybackRate和Time也不太可靠,尽管实际上一旦开始播放它们就会更可靠。我将其缓存到用户设置的内容中,直到开始播放以解决一致性问题为止。这里有很多事情可以获取currentPlaybackRate或一致的时间,如果需要代码示例,请告诉我,因为获取这些属性进行读取将根据执行线程而产生不同的结果:(
不幸的是,检查回放状态也不可靠。我经常发现播放器在完全暂停而不播放时会报告MPMusicPlaybackStatePlaying-在某些情况下,它会无限期保持这种状态。我建议根据播放或暂停的调用以及随后的MPMusicPlayerControllerPlaybackStateDidChangeNotification后续操作(确认播放器已开始执行该操作),抽象出所有确定MPMediaPlayerController是否正在播放的确定。
我应该提到我在iOS 12.1.3上,因为随着时间的流逝,苹果似乎间歇性地修复了一个小错误或添加了更多的API漏洞。既然它已经被打破了,那么任何改进都可能破坏您构建的用于修复它的任何抽象层-因此,我正在测试每个iOS版本,以确保所有功能都可以正常运行。
希望这会有所帮助,这是一次真正的斗争。