【发布时间】:2020-11-16 01:46:42
【问题描述】:
我正在尝试从客户端 Web 浏览器捕获麦克风音频,使用 WebSocket 将捕获的音频实时流式传输到 Node.js 服务器,然后再次将音频流式传输回不同的 Web 浏览器客户端。
到目前为止,在客户端,我在 JavaScript 中打开了一个 WebSocket 连接
const webSocket = new WebSocket('ws://127.0.0.1:8080');
webSocket.binaryType = 'blob';
在连接到服务器时,我从用户的麦克风捕获音频流,并在每 1 秒可用的每个可用数据块上,通过 WebSocket 将其发送到服务器
webSocket.onopen = event => {
console.log('info: connected to server');
navigator.mediaDevices
.getUserMedia({ audio: true, video: false })
.then(stream => {
const mediaRecorder = new MediaRecorder(stream, {
mimeType: 'audio/webm',
});
mediaRecorder.addEventListener('dataavailable', event => {
if (event.data.size > 0) {
webSocket.send(event.data);
}
});
mediaRecorder.start(1000);
});
};
现在,在服务器端,使用 ws 模块,我接收每个 blob 并将其发送到另一个客户端
wss.on('connection', ws => {
console.log('info: client connected');
ws.on('message', message => {
wss.clients.forEach(client => {
if (client !== ws && client.readyState === webSocket.OPEN) {
client.send(message);
}
});
});
});
回到客户端,我尝试使用 audio 标签和引用 audioEl 播放音频
webSocket.onmessage = event => {
audioEl.src = window.URL.createObjectURL(event.data);
audioEl.play();
};
现在,我知道这仅适用于第一块数据(并且确实有效),因为audioEl.play(); 是异步的。在这种情况下,我尝试更改 audio 元素的 blob URL,每秒通过 WebSocket 接收到一个新 blob。
现在研究了一个星期后,我发现解决方案仅涉及如何将服务器流式传输到客户端音频、开始录制音频、停止录制然后将整个块作为 blob 发送。
我也尝试发送AudioBuffer,但不知道如何处理它以播放音频。
const context = new AudioContext();
const source = context.createMediaStreamSource(stream);
const processor = context.createScriptProcessor(1024, 1, 1);
source.connect(processor);
processor.connect(context.destination);
processor.onaudioprocess = function(e) {
webSocket.send(e.inputBuffer);
}
我想要实现的是用户对着他/她的麦克风说话,音频直播流到服务器,然后流向另一个用户并同时播放。
如果我每秒发送一个 blob 的方法是正确的,我怎样才能使代码工作以连续播放音频?也许我需要创建一些我不知道的缓冲区。或者,如果方法完全不正确,请指导我使用正确的方法。
使用 WebRTC 技术进行点对点通信对我来说不是一个选择,因为我不想要 STUN 或 TURN 服务器的开销。
【问题讨论】:
-
您的意思是,您更喜欢总是通过 websocket/TCP 服务器中继数据,而不是有时通过 TURN(udp;通常)服务器中继。重新考虑您的选择。
标签: javascript node.js websocket getusermedia web-mediarecorder