我正在尝试从客户端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);
}
});
});
});
回到客户端,我尝试使用带有引用audioEl
的audio
标记来播放音频
webSocket.onmessage = event => {
audioEl.src = window.URL.createObjectURL(event.data);
audioEl.play();
};
现在,我知道这只适用于第一个数据块(它确实有效),因为audioEl.play();
是异步的。在本例中,我尝试更改audio
元素的blob,每秒钟通过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服务器的开销。
发布于 2020-07-28 00:48:04
MediaRecorder将数据块传递给dataavailable事件处理程序。为了使这些块有用,必须按顺序播放它们。它们是通常在.webm format (也称为Matroska format )中的媒体文件块。他们并不是孤立的。(第一个除外)。
因此,如果你通过websocket有效负载将它们传递给另一个浏览器,它们真的不能单独播放。
您可以尝试在接收浏览器上解析webm文件,并设法从websocket的message事件中播放它。有一个npm package called ebml可以帮助你做到这一点。如果您寻求解决方案,请查找“如何在浏览器中解码操作音频”。我这样做是为了视频。开发和调试是件令人头疼的事情。(我这样做只是因为一些用户需要使用Redmond中学科学项目--即Microsoft Internet Explorer --来呈现低延迟视频。我本可以为所有这些用户购买新的计算机,而这只是开发成本的一部分。)
奇怪的是,WebRTC通信堆栈打包音频的方式与MediaRecorder截然不同。
(值得一提的是,有一家名为xirsys.com的供应商提供STUN/TURN服务器。他们有一个慷慨的免费级别,用于开发和低工作量的工作。这是值得考虑的。在开发阶段,我和他们取得了很好的成功。)
https://stackoverflow.com/questions/63103293
复制相似问题