9

我正在将连续的实时流录制到高比特率 HLS 流中。然后我想将其异步转码为不同的格式/比特率。我主要有这个工作,除了音频伪影出现在每个片段之间(间隙和爆裂声)。

这是一个示例 ffmpeg 命令行:

ffmpeg -threads 1 -nostdin -loglevel verbose \
   -nostdin -y -i input.ts -c:a libfdk_aac \
   -ac 2 -b:a 64k -y -metadata -vn output.ts

检查示例声音文件显示音频末尾有一个间隙:

结尾

并且文件的开头看起来很可疑(尽管这可能不是问题):

开始

我怀疑这些人工制品正在发生,因为转码是在没有整个流的上下文的情况下发生的。

关于如何说服 FFMPEG 产生适合 HLS 流的音频的任何想法?

** 更新 1 **

这是原始片段的开始/结束。如您所见,开始看起来仍然相同,但结束在 30 秒处干净利落地结束。我希望有损编码有一定程度的填充,但我有一些 HLS 设法进行无间隙播放的方法(这与带有自定义元数据的 iTunes 方法有关吗?)

原始开始 原始结束

** 更新 2 **

因此,我将原始文件(MPEG2 TS 中的 128k aac)和转码文件(aac/adts 容器中的 64k aac)都转换为 WAV 并将两者并排放置。这是结果:

并排开始 并排结束

我不确定这是否代表客户端将如何播放它,但解码转码后会在开始时引入间隙并使片段更长似乎有点奇怪。鉴于它们都是有损编码,我希望填充在两者中同样存在(如果有的话)。

** 更新 3 **

根据http://en.wikipedia.org/wiki/Gapless_playback - 只有少数编码器支持无缝 - 对于 MP3,我已经切换到 ffmpeg 中的 lame,到目前为止,问题似乎已经消失。

对于 AAC(参见http://en.wikipedia.org/wiki/FAAC),我尝试过 libfaac(与 libfdk_aac 相对),它似乎也能产生无缝音频。但是,后者的质量不是很好,我宁愿使用 libfdk_aac 是可能的。

4

1 回答 1

0

这更像是一个概念性的答案,而不是包含要使用的明确工具,抱歉,但它在任何情况下都可能有用 - 它消除了引入音频伪影的问题,但代价是在处理层中引入了更多复杂性。

我的建议是根本不拆分未压缩的输入音频,而只生成一个连续的压缩流,将其通过管道传输到音频代理,例如 icecast2 服务器(或类似的,如果 icecast 不支持 AAC),然后进行拆分/recombine 在代理的客户端使用压缩音频块。

因此,这里的方法是定期(例如,每 60 秒?)连接到代理并收集比您正在轮询的时间段(例如,75 秒?)稍大的音频块 - 这需要设置最多可以并行运行,因为在某些时候会有两个客户端在运行 - 如果需要,它甚至可以从 cron 运行,或者从 shell 脚本后台运行......

一旦这样工作,您将拥有一系列重叠一点的音频块 - 然后您需要做一些处理工作来比较这些并隔离中间的音频部分,这对于每个块都是唯一的......

显然这是一种简化,但假设代理不添加任何元数据信息(即 ICY 数据或提示),那么以这种方式拆分音频应该允许连接处理过的块而没有任何音频伪影,因为只有一组原始音频输入的输出和比较它们将是一件轻而易举的事,因为你实际上并不关心格式,它只是那个时候的字节。

这样做的好处是您已将音频编码器与客户端断开连接,因此,如果您想并行运行一些其他进程以转码为不同的格式或比特率,或者为其他消费者更积极地分块流,那么这不会更改代理编码器端的任何内容 - 您只需使用与上述类似的工具链将另一个客户端添加到代理。

于 2013-05-27T05:32:00.917 回答