【问题标题】:Get live streaming audio from NodeJS server to clients从 NodeJS 服务器获取实时流音频到客户端
【发布时间】:2016-07-19 10:39:45
【问题描述】:

我需要从 1 个客户端到服务器再到多个侦听器客户端的实时实时音频流。

目前我有来自客户端的录音,并通过 socket.io 将音频流式传输到服务器。服务器接收此数据并且必须将音频(也通过 socket.io?)流式传输到想要收听此流的客户端。它必须尽可能实时(尽量减少延迟)。

我正在使用 GetUserMedia 来录制麦克风(浏览器兼容性在这里并不重要)。我希望客户端使用 HTML5 音频标签来收听流。服务器上接收到的数据是块(当前由 700 打包)打包在音频/wav 类型的 blob 中。

这是我将其发送到服务器的代码:

mediaRecorder.ondataavailable = function(e) {
    this.chunks.push(e.data);
    if (this.chunks.length >= 700)
    {
        this.sendData(this.chunks);
        this.chunks = [];
    }
};
mediaRecorder.sendData = function(buffer) {
    blob = new Blob(buffer, { 'type' : 'audio/wav' });
    socket.emit('voice', blob);
}

在服务器上,我可以像这样将块发送到客户端:

socket.on('voice', function(blob) {
    socket.broadcast.emit('voice', blob);
});

在客户端我可以这样玩:

var audio = document.createElement('audio');
socket.on('voice', function(arrayBuffer) {
    var blob = new Blob([arrayBuffer], { 'type' : 'audio/wav' });
    audio.src = window.URL.createObjectURL(blob);
    audio.play();
});

这适用于我发送的第一个块,但您不能继续将 audio.src 更改为新的 URL 源,因此这不是一个有效的解决方案。

我想我必须在服务器上创建某种流,我可以将它放在监听客户端上的 HTML5 的音频标签中,但我不知道如何。接收到的带有块的 blob 应该被实时附加到这个流中。

执行此操作的最佳方法是什么?我是从客户端麦克风到服务器吗?

【问题讨论】:

  • 如果您听说过 webrtc,那么这是解决您的问题的自然解决方案,因为 webrtc 是点对点的。
  • 我知道,但我不希望它是点对点的,而是从服务器广播。录制音频的客户端没有足够的带宽向所有客户端广播,所以我需要一个服务器来做到这一点
  • 你可以使用 WebRTC 的 MCU 架构,但我想这超出了这里的范围。
  • 你为什么不直接发送一个二进制流?
  • 这对您得到的答案有效吗?对此非常好奇!

标签: node.js html socket.io webrtc html5-audio


【解决方案1】:

我在这里聚会有点晚了,但如果你还没有完成它,看起来网络音频 API 将成为你的朋友。它允许您将音频流直接播放到输出设备,而无需将其附加到音频元素。

我正在考虑做同样的事情,您的问题已经回答了我的问题 - 如何从客户端获取数据到服务器。 Web 音频 API 的好处是能够将流添加在一起并在服务器上对其应用音频效果。

MDN Web Audio API

io 事件应该替换音频上下文中音频缓冲区对象中的数据。音频处理可以在 nodeJS 网络音频上下文中进行,然后作为单个流发送到每个客户端。

【讨论】:

  • 这正是我想要实现的目标,但努力遵循您链接的文档中的示例。当您从套接字接收事件时,您是否有一个如何实现这一点的示例?
【解决方案2】:

您可以如下动态更改audiosrc(假设为mp3类型):

<audio id="audio" controls="controls">
    <source id="mp3Source" type="audio/mp3"></source>
        Your browser does not support the audio format.
</audio>

每当收到套接字事件时调用以下函数:

function updateSource() { 
        var audio = document.getElementById('audio');

        var source = document.getElementById('mp3Source');
        source.src= <blob>;

        audio.load(); //call this to just preload the audio without playing
        audio.play(); //call this to play the song right away
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-19
    • 1970-01-01
    • 1970-01-01
    • 2020-11-16
    • 2020-08-11
    相关资源
    最近更新 更多