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

Posted

技术标签:

【中文标题】在 node.js 中使用 socket.io 通过 webrtc 广播实时音频【英文标题】:Broadcasting live audio through webrtc using socket.io in node.js 【发布时间】:2015-08-11 19:02:59 【问题描述】:

我正在尝试使用 webrtc 通过 getUserMedia() 获取音频并使用 socket.io 将其发送到服务器(socket.io 支持音频、视频、二进制数据),然后服务器会将其广播到所有连接的客户端。问题是当流到达连接的客户端时,它被转换为 JSON 对象而不是媒体流对象。所以我无法发送音频我也尝试过 socket.io-stream 模块但我没有成功。您能帮我正确捕获音频流并将其发送给所有连接的客户端吗?

这是发送数据的客户端代码

navigator.getUserMedia(audio: true, video: false, function(stream) 
  video.src = window.URL.createObjectURL(stream);
  webcamstream = stream;
  media = stream; /// here the datatype of media is mediaStream object
  socket.emit("sendaudio", media);
, function(e)
  console.log(error);
);

在接收客户端时代码如下

socket.on('receiveaudio' , function(media)

   console.log(media); //but here i am receiving it as a simple object
   other.src= media;
);

【问题讨论】:

我认为您应该以发送二进制数据为目标,如BufferBlob 对象。 Socket.io 从 1.0 开始支持二进制数据。尝试将您的 mediaStream 对象转换为缓冲区,然后发送它。另一方面,根据缓冲区重新创建对象。 @MaximePiraux 你能否发送任何可以帮助我将媒体流转换为缓冲区或 blob 的好教程或示例的链接。我觉得很难做到。 【参考方案1】:

我从here复制了我的答案。

此示例向您展示如何使用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);
);

【讨论】:

如果我们想发送 1 小时的录音并进行直播怎么办。我们应该每 5 秒启动和停止一次吗? 或者更好,每 100 毫秒的间隔?

以上是关于在 node.js 中使用 socket.io 通过 webrtc 广播实时音频的主要内容,如果未能解决你的问题,请参考以下文章

Node.js 和 socket.io 的混淆

Node.JS 服务器频繁断网?

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

在 Heroku 上使用集群和 socket.io-redis 扩展 node.js socket.io@1.*.*

使用 socket.io 在 Node.js 中使用 MySql 数据库进行 HTML5 页面日志记录

在visual studio node.js项目中使用socket.io