【问题标题】:Stream audio over websocket with low latency and no interruption通过 websocket 以低延迟和无中断的方式流式传输音频
【发布时间】:2019-05-03 19:14:48
【问题描述】:

我正在开展一个项目,该项目需要能够将音频从网页流式传输到其他客户端。我已经在使用 websocket 并希望在那里传输数据。

我目前的方法使用媒体记录器,但采样存在问题,导致中断。它注册 1s 音频,然后将其发送到服务器,服务器将其中继到其他客户端。有没有办法捕获连续的音频流并将其转换为 base64?

也许如果有一种方法可以从 MediaStream 毫不拖延地创建 base64 音频,它就会解决问题。你怎么看?

我想继续使用 websockets,我知道有 webrtc。 你有没有做过这样的事情,这可行吗?

                                                                --> Device 1
 MediaStream -> MediaRecorder -> base64 -> WebSocket -> Server --> Device ..
                                                                --> Device 18

这里是当前方法的演示......您可以在这里尝试:https://jsfiddle.net/8qhvrcbz/

var sendAudio = function(b64) {
  var message = 'var audio = document.createElement(\'audio\');';
  message += 'audio.src = "' + b64 + '";';
  message += 'audio.play().catch(console.error);';
  eval(message);
  console.log(b64);
}

 navigator.mediaDevices.getUserMedia({
      audio: true
 }).then(function(stream) {
        setInterval(function() {
            var chunks = [];
            var recorder = new MediaRecorder(stream);
            recorder.ondataavailable = function(e) {
                chunks.push(e.data);
            };
            recorder.onstop = function(e) {
                var audioBlob = new Blob(chunks);
                var reader = new FileReader();
                reader.readAsDataURL(audioBlob);
                reader.onloadend = function() {
                    var b64 = reader.result
                    b64 = b64.replace('application/octet-stream', 'audio/mpeg');
                    sendAudio(b64);
                }
            }
            recorder.start();
            setTimeout(function() {
                recorder.stop();
            }, 1050);
        }, 1000);
    });

【问题讨论】:

  • 旁注:为什么要使用 Base64? WebSockets 支持二进制数据。保存编码/解码将节省 CPU 和带宽。
  • 用base64更容易测试,我试过用二进制但没有太大的改进
  • @Myst 我认为问题出在 MediaRecorder 而不是数据本身,即使不涉及 websockets 它也会跳过。或者可能是因为玩家延迟。我做了一个小提琴女巫正在使用 blob 而不是 base64 jsfiddle.net/StarStep/0cqm56rz/4
  • 为什么要为此使用 Web Sockets?使用 WebRTC,它具有为低延迟而设计的整个堆栈。不要重新发明轮子。
  • 我刚刚在 2 分钟前发布了相同的答案。但是是的,webrtc 似乎可以更好地处理音频。我想使用 websocket,因为它更容易将数据发送到许多客户端,将作业卸载到服务器。使用 WebRTC,我们正在使用更多的连接......将对其进行测试。

标签: javascript node.js websocket streaming audio-streaming


【解决方案1】:

Websocket 不是最好的。我通过使用 WebRTC 而不是 websocket 解决了。 使用 websocket 的解决方案是在录制 1050ms 而不是 1000 时获得的,它会导致一些覆盖,但仍然比听空白要好。

【讨论】:

    【解决方案2】:

    虽然您已经通过行业推荐的 WebRTC 解决了这个问题,但我想分享一下我的答案。

    这里的问题通常不是 websockets,而是 MediaRecorder API。可以使用 PCM 音频捕获代替使用它,然后将捕获的数组缓冲区提交到 Web Worker 或 WASM 以编码为 MP3 块或类似内容。

    const context = new AudioContext();
    let leftChannel = [];
    let rightChannel = [];
    let recordingLength = null;
    let bufferSize = 512;
    let sampleRate = context.sampleRate;
    
    const audioSource = context.createMediaStreamSource(audioStream);
    const scriptNode = context.createScriptProcessor(bufferSize, 1, 1);
    
    audioSource.connect(scriptNode);
    scriptNode.connect(context.destination);
    scriptNode.onaudioprocess = function(e) {
        // Do something with the data, e.g. convert it to WAV or MP3
    };
    

    根据我的实验,这将为您提供“实时”音频。我对 MediaRecorder API 的理论是,它在发出任何导致可观察延迟的内容之前先进行一些缓冲。

    【讨论】:

      猜你喜欢
      • 2019-09-29
      • 2020-11-01
      • 2015-05-04
      • 2015-07-28
      • 2012-09-16
      • 2011-09-30
      • 1970-01-01
      • 1970-01-01
      • 2020-02-13
      相关资源
      最近更新 更多