【问题标题】:Audio streaming by websockets通过 websockets 流式传输音频
【发布时间】:2015-08-15 06:37:59
【问题描述】:

我要创建语音聊天。我的后端服务器在 Node.js 上工作,几乎每个客户端和服务器之间的连接都使用 socket.io。

websockets 适合我的用例吗?我更喜欢通信客户端 -> 服务器 -> 客户端而不是 P2P,因为我预计甚至 1000 个客户端连接到一个房间。

如果 websocket 没问题,那么哪种方法最好将 AudioBuffer 发送到服务器并在其他客户端上播放?我是这样做的:

navigator.getUserMedia({audio: true}, initializeRecorder, errorCallback);
function initializeRecorder(MediaStream) {
    var audioCtx = new window.AudioContext();
    var sourceNode = audioCtx.createMediaStreamSource(MediaStream);

    var recorder = audioCtx.createScriptProcessor(4096, 1, 1);
    recorder.onaudioprocess = recorderProcess;

    sourceNode.connect(recorder);

    recorder.connect(audioCtx.destination);
}
function recorderProcess(e) {
    var left = e.inputBuffer.getChannelData(0);

    io.socket.post('url', left);
}

但是在其他客户端接收到数据后,我不知道如何从缓冲区数组播放这个音频流。

编辑

1) 为什么如果我不将 ScriptProcessor(记录器变量)连接到目标,onaudioprocess 方法不会被触发?

文档信息 - “虽然你不必提供目的地,例如,只是想可视化一些音频数据” - Web Audio concepts and usage

2) 为什么在将记录器变量连接到目标后我听不到扬声器的任何声音,如果我将 sourceNode 变量直接连接到目标,我会听到。 即使 onaudioprocess 方法没有做任何事情。

有人可以帮忙吗?

【问题讨论】:

  • “我预计甚至 1000 个客户连接到一个房间。”与 3 人以上的语音聊天很困难。不仅存在无法同时听懂 1,000 个人讲话的实际问题,而且会占用大量带宽。您确定要构建“语音聊天”应用程序吗?您确定您不是在尝试构建只有少数人在说话而大多数人在听的东西吗?
  • 就像我说的 1000 个客户端连接到房间。只有一个人可以同时说话。我同意即使是 3 个人同时说话也会很混乱;)
  • 我仍然不清楚您正在尝试构建什么......这些细节对于选择正确的解决方案很重要。一次只能说话?还是在会话的整个生命周期中都有一个?而且,您的延迟要求是什么?
  • chatonic.com - 我想创建这样的解决方案。但他们使用来自客户端的闪存。我只想使用 JavaScript。
  • 我不知道 Chatonic 是什么,如果不创建帐户就无法尝试。您能否更详细地描述您正在尝试做什么?

标签: node.js websocket socket.io asp.net-web-api audio-streaming


【解决方案1】:

我认为网络套接字在这里很合适。只要确保您使用的是二进制传输。 (我自己使用BinaryJS,允许我向服务器打开任意流。)

从用户媒体捕获中获取数据非常简单。你所拥有的是一个好的开始。棘手的派对正在播放。您必须缓冲数据并使用您自己的脚本处理节点进行回放。

如果您在任何地方都使用 PCM,这并不难……您从 Web Audio API 获得的原始样本。这样做的缺点是有很多开销推动 32 位浮点 PCM。这会占用大量的带宽,而不仅仅是语音所需要的。

我认为在您的情况下,最简单的做法是将位深度降低到适合您的应用程序的任意位深度。 8 位样本对于可识别的语音来说已经足够了,而且占用的带宽要少得多。通过使用 PCM,您不必在 JS 中实现编解码器,然后必须为该编解码器处理数据的缓冲和成帧。

总而言之,一旦您在脚本处理节点的类型化数组中拥有原始样本数据,就可以编写一些东西将这些样本从 32 位浮点数转换为 8 位有符号整数。通过二进制 Web 套接字将这些缓冲区以与它们进入时相同大小的块发送到您的服务器。然后,服务器会将这些发送到其二进制 Web 套接字上的所有其他客户端。当客户端接收到音频数据时,它会在您选择的任何时间内对其进行缓冲,以防止丢失音频。您的客户端代码会将这些 8 位样本转换回 32 位浮点数并将其放入播放缓冲区。您的脚本处理节点将拾取缓冲区中的任何内容并在数据可用时开始播放。

【讨论】:

  • 感谢您的回答。我会尝试,但在我想解决此代码中出现的 2 个问题之前。你能检查一下吗?我在 edit 部分添加了信息。
  • 我正在做一个需要双向语音的在线教学平台。 Websockets 似乎是要走的路。您是否知道任何可以帮助拼凑 Brad 所描述的解决方案的好教程?该系统使用 PHP 和 NodeJS 进行实时处理。
  • @kiwicomb123 如果您在延迟很重要的情况下进行语音聊天,请考虑改用 WebRTC。
  • 请注意,这里的房间里有通常的网络音频大象...示例时钟同步!这些客户中的每一个都会对您使用的任何名义速率对应的采样率有一个稍微不同的想法,因此基于速率估计器的一些重新采样是有序的。专业上我们只是将音频接口锁定为 PTP 并称其为好,但我怀疑 AES67 方法不适合您。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-25
  • 2020-11-01
  • 1970-01-01
  • 2023-03-12
  • 2017-07-09
  • 2012-04-10
  • 1970-01-01
相关资源
最近更新 更多