如何使用Socket.io实时传输音频?

时间:2017-06-30 17:04:59

标签: javascript node.js audio socket.io streaming

我目前正在使用socket.io在HTML和JS中创建聊天应用程序。我能够在两台计算机之间进行通信,轻松发送书面信息。我的问题是我无法弄清楚如何将一台计算机中记录的实时语音发送到另一台计算机。我正在使用“navigator.getUserMedia”来录制来自麦克风的音频并且效果很好,但我无法通过Socket.io将其发送到另一台计算机。

我知道我可以开始录制,然后停止并最终发送结果,但这不是我需要的,我需要的是实时流媒体。

这是服务器的代码:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var path = require('path');
var users = [];

app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket){

socket.on('add user', function(user_id){
    users.push(user_id);
});

socket.on('chat message', function(msg){
    io.emit('chat message', msg);
});
socket.on('voice sent', function(msg){
    io.emit('voice received', msg);
});
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});

这是客户端js:

$(function () {
    var socket = io();
    var user_id = Math.random();

    socket.emit('add user', user_id);

    $('form').submit(function(){
      socket.emit('chat message', {"message": $('#m').val(), "user": user_id});
      $('#m').val('');
      return false;
    });
    socket.on('chat message', function(msg){
      if(msg.user == user_id){
        $('#messages').append($('<li class="mine">').text(msg.message));
      }
      else{
        $('#messages').append($('<li>').text(msg.message));
      }

    });

    socket.on('voice received', function(msg){
      var audio = document.querySelector('audio'); 
      audio.src = window.URL.createObjectURL(stream);
    });

    navigator.getUserMedia = navigator.getUserMedia ||
                     navigator.webkitGetUserMedia ||
                     navigator.mozGetUserMedia;
    if (navigator.getUserMedia) {
       console.log('getUserMedia supported.');
       navigator.getUserMedia ({audio: true}, successCallback, errorCallback);
    } else {
       console.log('getUserMedia not supported on your browser!');
    }

    function successCallback(stream){
       socket.emit('voice sent', stream);
    }

    function errorCallback(error) {
      console.error('An error occurred: [CODE ' + error.code + ']');
    }
  });

我希望有人可以帮助我。感谢

2 个答案:

答案 0 :(得分:0)

我尝试这样做,过了一会儿:

export default {


data() {
    return {
      audioCtx: new AudioContext(),// for get stream from mic and send via socket
      audioC: new AudioContext(), // for receive data from socket and translate and play 
    }
  },
  created() {
navigator.getUserMedia = navigator.getUserMedia ||
  navigator.webkitGetUserMedia ||
  navigator.mozGetUserMedia;
if (navigator.getUserMedia) {
  console.log('getUserMedia supported.');
  navigator.getUserMedia({
    audio: true
  }, stream => {
    var source = this.audioCtx.createMediaStreamSource(stream);
    var processor = this.audioCtx.createScriptProcessor(2048, 1, 1);
    source.connect(processor);
    processor.connect(this.audioCtx.destination);
    processor.onaudioprocess = e => {
      this.$store.state.mic.Emit("Voice",e.inputBuffer.getChannelData(0))
    };
this.$store.state.mic.On("Voice",msg=>{

                        let fbu =new Float32Array(Object.values(JSON.parse(msg)))
                        //console.log(fbu)
                        var audioBuffer = this.audioC.createBuffer(1, 2048, this.audioC.sampleRate);
                        audioBuffer.getChannelData(0).set(fbu);

                        let sourceNode = new AudioBufferSourceNode(this.audioC, {buffer: audioBuffer})

                        sourceNode.connect(this.audioC.destination)
                        sourceNode.start(0)


                    })

    this.audioC.resume()


  }, err => console.error(err))
}

}

}

,服务器将发送的所有内容发送给所有人(发件人客户端除外) 但是仍然存在问题,由于AudioBufferSourceNode的不同,通话质量不好,因此被分开了。

答案 1 :(得分:0)

在这段代码中

    socket.on('voice received', function(msg){
      var audio = document.querySelector('audio'); 
      audio.src = window.URL.createObjectURL(stream);
    });

流在任何地方都没有定义...... 我认为这可以解决您的问题

    socket.on('voice received', function(msg){
      var audio = document.querySelector('audio'); 
      audio.src = window.URL.createObjectURL(msg);
    });