首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用WebSocket将音频从客户端传输到服务器,再传输到客户端

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

Stack Overflow用户
提问于 2020-07-27 01:13:14
回答 1查看 3K关注 0票数 3

我正在尝试从客户端web浏览器捕获麦克风音频,使用WebSocket将捕获的音频实时传输到Node.js服务器,然后再次将音频传输回不同的web浏览器客户端。

到目前为止,在客户端,我用JavaScript打开了一个WebSocket连接

代码语言:javascript
复制
const webSocket = new WebSocket('ws://127.0.0.1:8080');
webSocket.binaryType = 'blob';

在连接到服务器时,我从用户的麦克风捕获音频流,并在每隔1秒可用的数据块上,通过WebSocket将其发送到服务器

代码语言:javascript
复制
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并将其发送到另一个客户端

代码语言:javascript
复制
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);
      }
    });
  });
});

回到客户端,我尝试使用带有引用audioElaudio标记来播放音频

代码语言:javascript
复制
  webSocket.onmessage = event => {
    audioEl.src = window.URL.createObjectURL(event.data);
    audioEl.play();
  };

现在,我知道这只适用于第一个数据块(它确实有效),因为audioEl.play();是异步的。在本例中,我尝试更改audio元素的blob,每秒钟通过WebSocket接收一个新的blob。

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

我也试着发送了一个AudioBuffer,但不知道如何处理它来播放音频。

代码语言:javascript
复制
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服务器的开销。

EN

回答 1

Stack Overflow用户

发布于 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服务器。他们有一个慷慨的免费级别,用于开发和低工作量的工作。这是值得考虑的。在开发阶段,我和他们取得了很好的成功。)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63103293

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档