6

I am trying to get the audio through getUserMedia() using webrtc and using socket.io to send it to server(socket.io support audio , video , binarydata) and then server will broadcast it to all connected clients. The problem is when stream reaches connected clients it is converted into JSON object not media stream object. So I am unable to send audio I have also tried socket.io-stream module but I it was not succesfull. Can you please help me to capture audio stream properly and sending it to all connected clients.

Here is code of client who sends data

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);
});

While on receiving client the code is as follows

socket.on('receiveaudio' , function(media)
{
   console.log(media); //but here i am receiving it as a simple object
   other.src= media;
});
Robert
  • 5,484
  • 1
  • 22
  • 35
Nauman Bashir
  • 189
  • 1
  • 4
  • 10
  • I think you should aim at sending binary data, as `Buffer` or `Blob` objects. Socket.io supports binary data since 1.0. Try to convert you mediaStream object to a buffer and then send it. On the other side, recreate the object based on the buffer. – Maxime Piraux May 30 '15 at 11:16
  • @MaximePiraux Can you send link of any good tutorial or example that can help me to convert mediastream into buffer or blob.i find it very hard to do. – Nauman Bashir May 30 '15 at 13:21

1 Answers1

6

I copied my answer from here.

This example shows you how to use the MediaRecorder to upload audio and then forward it using socket.io. This code will only broadcast after you're called mediaRecorder.stop(). You can choose to broadcast inside of ondataavailable. If you do that, you might want to pass a timeslice to mediaRecorder.start(), so that it doesn't trigger ondataavailable so often.

This solution isn't truly live, but I think it will help people who come back and find this question.

Client Code

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();
});

Server Code

socket.on('radio', function(blob) {
    // can choose to broadcast it to whoever you want
    socket.broadcast.emit('voice', blob);
});
Community
  • 1
  • 1
Dehli
  • 5,950
  • 5
  • 29
  • 44
  • 2
    What if we want to send a recording of 1 hour and live. Should we just start and stop after every 5 seconds? – Ali Sajid Nov 11 '19 at 13:56
  • Or even better, interval for every 100ms? – Jerry Jan 29 '21 at 01:00
  • MediaRecorder DOES NOT support playing each recorded segment individually. This means, that to play the recorded audio you must store every single recorded chunk, then create a blob out of them in the same order. For streaming, you should see other solutions. – Emanuel L Apr 23 '22 at 00:20