我有一个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
. 从我对这个问题的研究来看,我显然不是唯一一个在这个框架上苦苦挣扎的人:
- AVQueuePlayer 挫折(缓冲区欠载处理)
- 由于间隙,AVPlayer 流在后台停止
- AVQueuePlayer 有时会移动到其项目队列中的下一个 AVPlayerItem 而不发送 AVPlayerItemDidPlayToEndTimeNotification
- AVQueuePlayer 在 iOS5 后台播放多个音轨
- 检测 AVQueuePlayer 中的当前项目并知道它何时更改?
全面披露:我的应用程序实际上是用 RubyMotion 编写的,但我已经能够用更少的代码在 Objective-C 中重现该问题(因此可能的故障点也更少),所以我相当肯定 RubyMotion 或我的使用 ofAVFoundation
不是这里的罪魁祸首。
编辑:刚刚使用链接使用本地文件对其进行了测试file://
,问题仍然存在,因此绝对不是流引擎或网络服务器的问题。
编辑 2:我研究了 MP4 规范以及 iTunes 和 AVFoundation 如何确定 MP4 中的无间隙。结果在moov.udta.meta.ilst.---
原子中应该有三个原子,mean
,name
和data
,它们告诉解码器需要重新创建 gapless 的各个位。但是,导致问题的文件没有这些原子,因此绝对不是无间隙播放的结果。我决定通过 CoreAudio 的 AAC 编码器运行原始文件(一个是 FLAC,另一个是 MP3),生成的文件可以完美播放AVQueuePlayer
(即使我用 去掉了所有无缝标签AtomicParsley
),所以它看起来像一个错误处理非 Apple AAC 比特流时libfaac
的输出或解码器。AVFoundation