3

我编写了一个小型 nodeJS 服务器,它将 Windows 上 ffmpeg 捕获的系统音频(使用 DirectShow)作为流式 MP3 文件输出到浏览器。音频需要尽可能实时,最小/无缓冲,并且音频中的“跳过”效果是完全可以接受的。

当我使用 HTML5 音频标签在 Chrome 中播放音频时,在低延迟 LAN 连接上会有大约 8-10 秒的延迟。我怀疑这是客户端缓冲区,并在客户端使用了 Flash MP3 播放器,这将延迟降低到 2-3 秒。

现在,缓冲似乎发生在服务器端。NodeJS 的 response.write 的文档提到数据是写入内核缓冲区。如何完全避免任何缓冲或至少绕过它,以便客户端始终获取最新的音频数据?处理“流失”事件以始终推送实时数据的策略?

在请求对象上,我使用了 setNoDelay(true)来避免使用 Nagle 算法。以下是生成的 ffmpeg 进程发出数据时如何写入数据的片段。

var clients = []; //List of client connections currently being served
ffmpeg.stdout.on('data', function(data) {
    for(var i = 0; i < clients.length; i++){
        clients[i].res.write(data);
    }
});
4

1 回答 1

1

有几个地方会发生延迟/缓冲:

  1. DirectShow 捕获(~100ms 左右)
  2. FFMPEG MPEG 编码缓冲区(1-10 秒,取决于配置)
  3. 网络写入和传输(在您的设置中接近 0)
  4. 客户端缓冲(如您所见,因客户端而异 - 大多数客户端缓冲约 2 秒用于解码)

我怀疑您需要查看的缓冲区是用于 FFMPEG 编码的缓冲区。我可以通过确保在执行 FFMPEG 时明确配置输入格式来减少这种情况。此外,请确保删除第一块数据进行编码,因为第一位无疑会比以后延迟更多。

一旦你这样做了,你会发现你的延迟是一两秒。至少,这就是我通过类似设置得到的结果。

于 2012-10-27T02:48:03.667 回答