Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Streaming microphone through sockets using socket IO and Node JS

I am making an application where I want the user to use their mic (on their phone) and be able to talk to each other in the game lobby. However, this has proven to be more than difficult.

I am using Node JS socket io and socket io stream

on my client I am using the audio api to take my microphones input ( I am not really worried about this all that much because I am going to make this a Native IOS app)

    navigator.getUserMedia = ( navigator.getUserMedia ||
                     navigator.webkitGetUserMedia ||
                     navigator.mozGetUserMedia ||
                     navigator.msGetUserMedia);

    if (navigator.getUserMedia) {
          navigator.getUserMedia (
            // constraints
          {
            video: false,
            audio: true
          },


    function(localMediaStream) {
        var video = document.querySelector('audio');
        video.src = window.URL.createObjectURL(localMediaStream);
       lcm = localMediaStream;
       var audioContext = window.AudioContext;
       var context = new audioContext();
       var audioInput = context.createMediaStreamSource(localMediaStream);
       var bufferSize = 2048;
      // create a javascript node
      var recorder = context.createScriptProcessor(bufferSize, 1, 1);
      // specify the processing function
      recorder.onaudioprocess = recorderProcess;
      // connect stream to our recorder
      audioInput.connect(recorder);
      // connect our recorder to the previous destination
      recorder.connect(context.destination);
      },

  // errorCallback
  function(err) {
     console.log("The following error occured: " + err);
     $("video").remove();
     alert("@#");
          }
        );
            } else {
                 console.log("getUserMedia not supported");
            }

        function recorderProcess(e) {
            var left = e.inputBuffer.getChannelData(0);
            window.stream.write(convertFloat32ToInt16(left));
           //var f = $("#aud").attr("src");
           var src = window.URL.createObjectURL(lcm);
            ss(socket).emit('file', src, {size: src.size});
           ss.createBlobReadStream(src).pipe(window.stream);
          //ss.createReadStream(f).pipe(widnow.stream);

            }
         function convertFloat32ToInt16(buffer)
       {
            l = buffer.length;
            buf = new Int16Array(l);
            while (l--) {
               buf[l] = Math.min(1, buffer[l])*0x7FFF;
              }      
           return buf.buffer;
         }



             });

         ss(socket).on('back', function(stream, data) {

                //console.log(stream);

                var video = document.querySelector('audio');
              video.src = window.URL.createObjectURL(stream);
              console.log("getting mic data");
            });

i which I can successfully listen to my self speak on the microphone. I am using the stream socket to create a blob to upload to my server...

        index.ss(socket).on('file', function(stream, data) {
                console.log("getting stream");
               var filename = index.path.basename(data.name);
             //var myfs = index.fs.createWriteStream(filename);

            var fileWriter = new index.wav.FileWriter('demo.wav', {
                channels: 1,
                sampleRate: 48000,
                bitDepth: 16
             });
          var streams = index.ss.createStream();
          streams.pipe(fileWriter);

        index.ss(socket).emit('back', fileWriter, {size: fileWriter.size});


        });

I cannot get the stream to write to a file or even a temporary buffer, and Then stream back to a client so I can then play or "stream" the audio real time. After a while the server crashes with saying that the pipe is not writable.

Has anyone else encountered this?

like image 514
Dnaso Avatar asked Aug 17 '26 01:08

Dnaso


1 Answers

By using SFMediaStream library you can socket.io and Nodejs server for live streaming your microphone from a browser. But this library still need some improvement before release to the production.

For the presenter

var mySocket = io("/", {transports:['websocket']});

// Set latency to 100ms (Equal with streamer)
var presenterMedia = new ScarletsMediaPresenter({
    audio:{
        channelCount:1,
        echoCancellation: false
    }
}, 100);

// Every new client streamer must receive this header buffer data
presenterMedia.onRecordingReady = function(packet){
    mySocket.emit('bufferHeader', packet);
}

// Send buffer to the server
presenterMedia.onBufferProcess = function(streamData){
    mySocket.emit('stream', streamData);
}

presenterMedia.startRecording();

For the streamer

var mySocket = io("/", {transports:['websocket']});

// Set latency to 100ms (Equal with presenter)
var audioStreamer = new ScarletsAudioBufferStreamer(100);
audioStreamer.playStream();

// Buffer header must be received first
mySocket.on('bufferHeader', function(packet){
    audioStreamer.setBufferHeader(packet);
});

// Receive buffer and play it
mySocket.on('stream', function(packet){
    // audioStreamer.realtimeBufferPlay(packet);
    audioStreamer.receiveBuffer(packet);
});

// Request buffer header
mySocket.emit('requestBufferHeader', '');

Or you can test it from your localhost with this example

like image 200
StefansArya Avatar answered Aug 18 '26 16:08

StefansArya



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!