我要创建语音聊天。我的后端服务器在 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 方法不执行任何操作。
有人可以帮忙吗?
最佳答案
我认为网络套接字在这里很合适。只需确保您使用的是二进制传输。 (我自己使用 BinaryJS 来实现此目的,允许我向服务器打开任意流。)
从用户媒体捕获中获取数据非常简单。你所拥有的就是一个好的开始。棘手的聚会正在播放。您必须缓冲数据并使用您自己的脚本处理 Node 进行回放。
如果您到处使用 PCM,这并不太难...从 Web Audio API 获得的原始样本。这样做的缺点是 32 位浮点 PCM 会产生大量开销。这会使用大量的带宽,而这仅是语音所不需要的。
我认为在您的情况下最简单的方法是将位深度减少到适合您的应用程序的任意位深度。 8 位样本对于可辨别的语音来说足够了,并且占用的带宽要少得多。通过使用 PCM,您可以避免在 JS 中实现编解码器,然后再处理该编解码器的数据缓冲和成帧。
总而言之,一旦您在脚本处理 Node 的类型化数组中获得了原始样本数据,就可以编写一些代码将这些样本从 32 位 float 转换为 8 位有符号整数。通过二进制 Web 套接字将这些缓冲区以与传入时相同大小的 block 发送到您的服务器。然后,服务器会将这些发送到二进制 Web 套接字上的所有其他客户端。当客户端收到音频数据时,它将缓冲您选择的任意时间,以防止丢失音频。您的客户端代码会将这些 8 位样本转换回 32 位 float ,并将其放入播放缓冲区中。您的脚本处理 Node 将拾取缓冲区中的所有内容,并在数据可用时开始播放。
关于node.js - 通过 websocket 进行音频流传输,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31995677/