Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用WebSocket将音频从客户端传输到服务器,再传输到客户端_Javascript_Node.js_Websocket_Getusermedia_Web Mediarecorder - Fatal编程技术网

Javascript 使用WebSocket将音频从客户端传输到服务器,再传输到客户端

Javascript 使用WebSocket将音频从客户端传输到服务器,再传输到客户端,javascript,node.js,websocket,getusermedia,web-mediarecorder,Javascript,Node.js,Websocket,Getusermedia,Web Mediarecorder,我正在尝试从客户端web浏览器捕获麦克风音频,使用WebSocket将捕获的音频实时流式传输到Node.js服务器,然后再次将音频流式传输回其他web浏览器客户端 到目前为止,在客户端,我用JavaScript打开了一个WebSocket连接 const webSocket = new WebSocket('ws://127.0.0.1:8080'); webSocket.binaryType = 'blob'; 在连接到服务器时,我从用户的麦克风捕获音频流,并在每1秒可用的每个数据块上,通过

我正在尝试从客户端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
标签播放音频

  webSocket.onmessage = event => {
    audioEl.src = window.URL.createObjectURL(event.data);
    audioEl.play();
  };
现在,我知道这只适用于第一块数据(它确实有效),因为
audioEl.play()是异步的。在本例中,我试图每秒更改
audio
元素的blob URL,通过WebSocket接收一个新的blob

经过一周的研究,我发现解决方案只涉及如何将服务器音频流传输到客户端音频,开始录制音频,停止录制,然后将整个数据块作为blob发送

我还尝试发送了一个
音频缓冲区
,但不知道如何处理它以播放音频

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负载将它们传递给另一个浏览器,它们实际上无法单独播放

您可以尝试在接收浏览器上解析webm文件,并设法从websocket的消息事件中播放它。有一种方法可以帮上忙。如果你想要那个解决方案,那就去看看“如何在浏览器中解码opus音频”。我已经为视频做了这个。开发和调试是一件棘手的事情。(我之所以这么做,是因为一些用户需要使用雷德蒙中学的科学项目——也就是微软的Internet Explorer——来呈现低延迟视频。我本可以为所有这些用户购买新的计算机,而开发这些计算机的成本是多少。)

奇怪的是,WebRTC通信堆栈打包音频的方式与MediaRecorder的方式大不相同,但这是事实


(值得一提的是,有一家名为xirsys.com的供应商提供了STUN/TURN服务器。他们有一个慷慨的免费开发层和低容量的工作。这是值得考虑的。在开发阶段,我与他们一起取得了很好的成功。)

您的意思是,您更喜欢始终通过websocket/TCP服务器中继数据,而不是有时通过TURN(udp;通常是)服务器中继数据。重新考虑你的选择。