Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Streaming Binary with Node.js and WebSockets

I've been googling this and looking around stackoverflow for a while but haven't found a solution - hence the post.

I am playing around with Node.js and WebSockets out of curiosity. I am trying to stream some binary data (an mp3) to the client. My code so far is below but is obviously not working as intended.

I suspect that my problem is that I am not actually sending binary data from the server and would like some clarification/help.

Heres my server...

var fs = require('fs');
var WebSocketServer = require('ws').Server;

var wss = new WebSocketServer({port: 8080,host:"127.0.0.1"});
wss.on('connection', function(ws) {    
    var readStream = 
    fs.createReadStream("test.mp3", 
     {'flags': 'r',
      'encoding': 'binary', 
      'mode': 0666, 
      'bufferSize': 64 * 1024});

    readStream.on('data', function(data) {
        ws.send(data, {binary: true, mask: false});
    });
});

And my client...

context = new webkitAudioContext();
var ws = new WebSocket("ws://localhost:8080");
ws.binaryType = 'arraybuffer';

ws.onmessage = function (evt) {
    context.decodeAudioData(
    evt.data,
        function(buffer) {
            console.log("Success");
        }, 
        function(error) {
            console.log("Error");
        });
};

The call to decode always end up in the error callback. I am assuming this is because it is receiving bad data.

So my question is how to I correctly stream the file as binary?

Thanks

like image 915
fatlog Avatar asked Mar 26 '13 13:03

fatlog


People also ask

Can WebSockets send binary data?

WebSockets support sending binary messages, too. To send binary data, one can use either Blob or ArrayBuffer object. Instead of calling the send method with string, you can simply pass an ArrayBuffer or a Blob .

Are WebSockets used for streaming?

Yes, Websocket can be used to transmit over 30 fps and even 60 fps. The main issue with Websocket is that it is low-level and you have to deal with may other issues than just transmitting video chunks. All in all it's a great transport for video and also audio.

Does Nodejs support WebSockets?

Node. js can maintain many hundreds of WebSockets connections simultaneously. WebSockets on the server can become complicated as the connection upgrade from HTTP to WebSockets requires handling.

Is Nodejs good for streaming?

Nodejs is very good to streaming audio and video, but nodejs is a new technology, so it's don't have a lot of softwares yet.


1 Answers

What your server is doing is that it is sending messages consisting of binary audio data in 64 KB chunks to your client. Your client should rebuild the audio file before calling decodeAudioData.

You are calling decodeAudioDataevery time your client is getting message on websocket. You have to create a separate buffer to add all the chunks to it. Then on completion of transfer, the buffer should be given input to decodeAudioData.

You have two options now:

  1. You load entire file (fs.read) without using stream events and send the whole file with ws.send (easy to do)
  2. You use stream events, modify your client to accept chunks of data and assemble them before calling decodeAudioData
like image 180
user568109 Avatar answered Sep 30 '22 10:09

user568109