以最小的延迟从Icecast解码HTTP音频流

时间:2019-01-11 13:15:56

标签: javascript icecast web-audio-api internet-radio whatwg-streams-api

我正在使用Icecast传输来自内部麦克风的实时音频,并希望收听者的延迟尽可能短。

幼稚的解决方案是仅访问http://myhostname:8000/my_mountpoint来获取流,但是<audio>标签在播放之前进行内部缓冲并导致相当高的延迟。

当前解决方案:我使用ReadableStreams API进行解码(使用Web Audio API的decodeAudioData)并通过将解码后的数据路由到音频上下文目标来播放数据块(内部发言人)。这样可以有效地降低延迟。

问题::此流API在实验性的情况下,应在最新的Chrome,Safari,Opera和FF上technically work(设置特定标志后)。但是,除Chrome和Opera外,所有其他浏览器中的decodeAudioData都存在问题。我认为FF和Safari无法解码部分MP3数据,因为当我开始流式传输时,我通常会听到扬声器的短暂激活。在Safari上,永远不会调用成功的decodeAudioData上的回调,而FF只会说EncodingError: The given encoding is not supported.

如果我至少想让它在Safari和FF上运行,是否有任何解决方法? decodeAudioData的实现在Chrome和Safari上是否实际上有所不同,以至于一种只能在部分MP3上运行,而另一种则不能?

3 个答案:

答案 0 :(得分:1)

正如@Brad提到的,Opus具有出色的低延迟性。我编写了可与Streams一起使用的低延迟WASM Opus解码器,并启动了另一个演示,演示了如何使用decodeAudioData()播放部分文件:

答案 1 :(得分:0)

如果您需要亚秒级的延迟,请不要使用Icecast!

如果您需要不到10秒的延迟并且对整个软件和网络链没有完全控制,请不要使用Icecast!

是的,这是一个答案,而不是评论。 Icecast不适用于此类用例。它设计用于以非同步方式通过HTTP进行1-to-n批量数据广播。

您正在解释的内容听起来像您确实应该考虑设计为低延迟的内容,例如web-RTC。

如果您认为您确实应该使用Icecast,请解释原因。因为您的问题不然。我全都想更多地使用Icecast,毕竟我是维护者,但是它的应用应该有意义。

答案 2 :(得分:0)

  

我正在使用Icecast传输来自内部麦克风的实时音频,希望收听者的延迟尽可能短。

您的设置存在一些问题,这些问题可能导致最低的延迟:

  • HTTP渐进式(Icecast等使用的流式传输类型)在TCP(一种可靠的传输)上运行。如果数据包丢失,则在将数据重新传输到客户端之前会有一定的滞后时间,然后才将数据传输到浏览器。这样可以确保按顺序听到音频的每一比特,但是会引起延迟。对于低延迟,通常使用UDP数据包,这样任何丢失的数据包都可以跳过而不是等待,从而导致故障,但是客户端可以降低延迟。

  • MP3并不是低延迟的出色编解码器。有更好的编解码器,例如Opus,它们效率更高,并且可以生成更小的段。

  • 如您所见,默认情况下,通过HTTP流式传输时,客户端将缓冲更多缓冲区。

但是,在理想情况下,我使用自定义服务器通过HTTP Progressive在Chrome中的流传输少于250ms。我敢打赌,如果您关闭服务器端缓冲并使用其他编解码器,则可以从Icecast中获得类似的性能。

  

但是,我在除Chrome和Opera之外的所有其他浏览器中的解码音频数据存在问题。我相信FF和Safari无法解码部分MP3数据

是的,decodeAudioData()用于解码整个文件。您将很难以样本准确的方式解码任意分割的块。

幸运的是,有一种方法可以做您想要的... MediaSource扩展。

https://developer.mozilla.org/en-US/docs/Web/API/Media_Source_Extensions_API

基本上,您可以使用完全相同的ReadableStream接口并将数据推送到SourceBuffer,以最终播放出正常的<audio>标签。只要您已解决任何跨域问题,此即可与Icecast和类似服务器上的普通MP3音频一起使用。