AVQueuePlayer过早开始下一个项目

时间:2013-05-25 10:23:35

标签: iphone ios objective-c avfoundation avqueueplayer

我有一个AVQueuePlayer,在特定的情况下,它会在上一首曲目完成之前开始播放下一曲目。它不会同时播放它们,只是提前删除第一首曲目并开始下一首曲目。当两个轨道都是http流时,肯定会发生这种情况,我在本地播放文件时尝试而不是。而且,每次跟踪都不会发生这种情况。只有特定的两个曲目放在一起时才会导致问题。大多数曲目都没有这个问题,但是很多都有。其他媒体播放器在送入这些曲目时不会出现这些症状。显示症状的曲目是AAC编码的,我在播放MP3版本时没有这样的问题。 AAC文件使用libfaac,VBR 90%进行编码。编码轨道的确切命令行:

ffmpeg -loglevel error -probesize 10000000 -i "$input" -strict -2 -acodec libfaac -q:a 90 -vn "$output.m4a"

我认为问题是相关AVQueuePlayer积极尝试无缝地播放曲目,因为我知道AAC中包含的一些元数据允许按顺序播放两首曲目没有间隙(在电子混音中特别有用) - 这些文件虽然不应该包含这些元数据,但是当播放两个不相关的曲目时,它肯定不会导致AVQueuePlayer惊慌失措?编辑:确定不是原因,见下文。

如果您想自己重现问题,只需要极少量的代码,只需创建一个基本项目,包含AVFoundation,然后执行以下操作:

self.queuePlayer = [AVQueuePlayer queuePlayerWithItems: @[[AVPlayerItem playerItemWithURL: [NSURL URLWithString: @"https://eqbeats.org/track/4875/aac"]], [AVPlayerItem playerItemWithURL: [NSURL URLWithString: @"https://eqbeats.org/track/4499/aac"]]]];
[self.queuePlayer play];

让第一首曲目几乎完成(它将持续约100秒左右),你会听到它突然结束,第二首曲目将会开启。

我认为有一些解决方法,例如在下一首曲目开始时截取消息并检查上一首曲目的播放状态,或者只在前一次启动后将下一个项目添加到队列中...但我担心可靠性这样的方法,特别是当应用程序背景时。如果没有针对此客户端的修复,我可以调查是否有办法剥离此元数据服务器端(假设 问题)或者只是让自己辞职使用更大,更糟糕的情况 - 听起来MP3版本。

AVFoundation只是一场骚乱 - 我敢肯定,任何与之合作的人都会同意。我正在讨论是否将此作为Apple的一个错误提出来,但由于它在两个主要的iOS更新中幸存下来,我觉得这些东西与AVQueuePlayer一样常规。从我对这个问题的研究来看,我显然不是唯一一个在这个框架上挣扎的人:

完全披露:我的应用程序实际上是用RubyMotion编写的,但是我已经能够用更少的代码重现Objective-C中的问题(所以可能的失败点很少),所以我很确定RubyMotion或我对AVFoundation的使用并不是罪魁祸首。

编辑:刚刚使用file://链接使用本地文件对其进行了测试,问题仍然存在,因此对于流引擎或网络服务器来说绝对不是问题。

编辑2:我已经研究了MP4规范以及iTunes和AVFoundation如何确定MP4中的无间隙。在moov.udta.meta.ilst.---原子中,应该有三个原子,meannamedata,它们告诉解码器various bits needed to recreate gapless。导致问题的文件没有这些原子所以它绝对不是无间隙播放的结果。我决定通过CoreAudio的AAC编码器运行原始文件(一个是FLAC,另一个是MP3),结果文件通过AVQueuePlayer完全正常(即使我用{{3}删除所有无间隙标签后也是如此在处理非Apple AAC比特流时,它看起来像libfaac的输出或AVFoundation的解码器中的错误。

1 个答案:

答案 0 :(得分:5)

请勿将libfaac与AVFoundation一起使用。它不喜欢它。我们现在正在使用libfdk并且它不会吮吸。

ffmpeg -loglevel error -probesize 10000000 -i "$input" -acodec libfdk_aac -vbr 3 -vn "$output.m4a"