通过 socket.io 1.0 实时音频

Posted

技术标签:

【中文标题】通过 socket.io 1.0 实时音频【英文标题】:Live audio via socket.io 1.0 【发布时间】:2014-09-12 12:25:05 【问题描述】:

来自 socket.io 网站

二进制流

从 1.0 开始,可以来回发送任何 blob:图像、音频、视频。

我现在想知道,如果这不能成为我最近想要实现的目标的解决方案。

我实际上正在寻找一种方法,如何将实时音频流从(A - 即麦克风输入..)广播到连接到我的网站的所有客户端。这样的事情可能吗?我一直在搞乱 WebRTC (https://www.webrtc-experiment.com/) 示例,但我无法管理多个已连接客户端的目标。

我的想法是关于诸如 getUserMedia 或 A 侧的任何其他音频源(PCM,等等)之类的东西被切成块并提供给客户端并由例如 html5 音频元素或任何东西播放。我需要做到这一点尽可能多地实时流式传输,没有喊叫/冰播服务不够快(实际上,它们不能解决我的问题,它们应该以这种方式使用)而且我并不真正关心音频质量。跨平台兼容性会很棒。

这样的事情可能吗?通过使用 socket.io 如何将这些数据提供给客户端?

我将非常感谢任何可以帮助我实现这一目标的参考、提示或来源。 非常感谢。

【问题讨论】:

【参考方案1】:

此示例向您展示如何使用MediaRecorder 上传音频,然后使用socket.io 转发。此代码仅在您被称为mediaRecorder.stop() 后才会广播。您可以选择在ondataavailable 内广播。如果这样做,您可能需要将timeslice 传递给mediaRecorder.start(),这样它就不会经常触发ondataavailable

此解决方案并未真正上线,但我认为它会帮助那些回来并找到此问题的人。

客户端代码

var constraints =  audio: true ;
navigator.mediaDevices.getUserMedia(constraints).then(function(mediaStream) 
    var mediaRecorder = new MediaRecorder(mediaStream);
    mediaRecorder.onstart = function(e) 
        this.chunks = [];
    ;
    mediaRecorder.ondataavailable = function(e) 
        this.chunks.push(e.data);
    ;
    mediaRecorder.onstop = function(e) 
        var blob = new Blob(this.chunks,  'type' : 'audio/ogg; codecs=opus' );
        socket.emit('radio', blob);
    ;

    // Start recording
    mediaRecorder.start();

    // Stop recording after 5 seconds and broadcast it to server
    setTimeout(function() 
        mediaRecorder.stop()
    , 5000);
);

// When the client receives a voice message it will play the sound
socket.on('voice', function(arrayBuffer) 
    var blob = new Blob([arrayBuffer],  'type' : 'audio/ogg; codecs=opus' );
    var audio = document.createElement('audio');
    audio.src = window.URL.createObjectURL(blob);
    audio.play();
);

服务器代码

socket.on('radio', function(blob) 
    // can choose to broadcast it to whoever you want
    socket.broadcast.emit('voice', blob);
);

【讨论】:

嘿,您的代码工作正常,但由于 setTimeout 功能在其他客户端可以侦听后,它在 5 秒后停止。这是让其他客户在每一秒内听到所有声音的任何方式吗? 嘿@niteshsingh,我不完全确定如何在不弄乱代码的情况下做到这一点。我不知道我什么时候会回来修改它,但希望这可以帮助您获得基础设置!如果你弄清楚了,请告诉我:)【参考方案2】:

Client Code 中,您可以编写 setInterval() 而不是 setTimeout(),然后递归调用 mediaRecorder.start() 以便每 5 秒,blob 将连续发射一次。

setInterval(function() 
        mediaRecorder.stop()
        mediaRecorder.start()
    , 5000);

客户端代码

var constraints =  audio: true ;
navigator.mediaDevices.getUserMedia(constraints).then(function(mediaStream) 
var mediaRecorder = new MediaRecorder(mediaStream);
mediaRecorder.onstart = function(e) 
    this.chunks = [];
;
mediaRecorder.ondataavailable = function(e) 
    this.chunks.push(e.data);
;
mediaRecorder.onstop = function(e) 
    var blob = new Blob(this.chunks,  'type' : 'audio/ogg; codecs=opus' );
    socket.emit('radio', blob);
;

// Start recording
mediaRecorder.start();

// Stop recording after 5 seconds and broadcast it to server
setInterval(function() 
    mediaRecorder.stop()
    mediaRecorder.start()
  , 5000);
);

// When the client receives a voice message it will play the sound
socket.on('voice', function(arrayBuffer) 
  var blob = new Blob([arrayBuffer],  'type' : 'audio/ogg; codecs=opus' );
  var audio = document.createElement('audio');
  audio.src = window.URL.createObjectURL(blob);
  audio.play();
);

服务器代码

socket.on('voice', function(blob) 
    // can choose to broadcast it to whoever you want
    socket.broadcast.emit('voice', blob);
);

【讨论】:

有没有办法不是每 5 秒执行一次,而是实时执行一次?像 1 毫秒? 我如何在 Java 中读取这个 blob?它看起来像一个 ebml 文件

以上是关于通过 socket.io 1.0 实时音频的主要内容,如果未能解决你的问题,请参考以下文章

在 node.js 中使用 socket.io 通过 webrtc 广播实时音频

节点(套接字)实时音频流/广播

如何通过 socks5 代理使用 JavaScript socket.io-client 库?

Socket.IO 入门

通过 socket.io 更新实时 d3 图表

通过 Socket.IO 1.0 发送到具有 socketId 的特定客户端