57

I've been experimenting with binary streams in Node.js, and much to my amazement do actually have a working demo of taking a Shoutcast stream using node-radio-stream and pushing it into a HTML5 element using chunked encoding. But it only works in Safari!

Here is my server code:

var radio = require("radio-stream");
var http = require('http');
var url = "http://67.205.85.183:7714";
var stream = radio.createReadStream(url);

var clients = [];

stream.on("connect", function() {
  console.error("Radio Stream connected!");
  console.error(stream.headers);
});


// When a chunk of data is received on the stream, push it to all connected clients
stream.on("data", function (chunk) {
    if (clients.length > 0){
        for (client in clients){
            clients[client].write(chunk);
        };
    }
});

// When a 'metadata' event happens, usually a new song is starting.
stream.on("metadata", function(title) {
  console.error(title);
});

// Listen on a web port and respond with a chunked response header. 
var server = http.createServer(function(req, res){ 
    res.writeHead(200,{
        "Content-Type": "audio/mpeg",
        'Transfer-Encoding': 'chunked'
    });
    // Add the response to the clients array to receive streaming
    clients.push(res);
    console.log('Client connected; streaming'); 
});
server.listen("8000", "127.0.0.1");

console.log('Server running at http://127.0.0.1:8000'); 

My client code is simply:

<audio controls src="http://localhost:8000/"></audio>

This works fine in Safari 5 on the Mac, but doesn't seem to do anything in Chrome or Firefox. Any ideas?

Possible candidates including encoding issues, or just partially-implemented HTML5 features...

Scott Wilson
  • 1,580
  • 1
  • 15
  • 14

1 Answers1

21

Here's a (slightly outdated) summary of the current status of HTML5 Audio and Icecast streams.

As you can see, a MP3 source only seems to work in Safari (and possibly IE9). You might need to experiment with some server-side transcoding (with ffmpeg or mencoder) to OGG Vorbis. I'm pretty sure I was able to get Chrome to behave properly when I was sending Vorbis data.

Firefox was still being a brat though, maybe it doesn't like the chunked encoding (all SHOUTcast servers respond with a HTTP/1.0 version response, which hadn't defined Transfer-Encoding: chunked yet). Try sending a Transfer-Encoding: identity response header with the OGG stream to disable chunked, and Firefox MIGHT work. I haven't tested this.

Let me know how it goes! Cheers!

danShumway
  • 450
  • 4
  • 14
TooTallNate
  • 1,440
  • 2
  • 19
  • 39
  • Thanks! I'm checking out FFMpeg now to give it a try. – Scott Wilson Oct 21 '10 at 07:35
  • I was able to mess around with this a bit last night, and was actually able to get Chrome to play the transcoded OGG Vorbis data! It seemed that `ffmpeg` couldn't make a proper OGG file from the MP3 stream, but Chrome was still able to play it. I'm also experimenting with invoking `lame` and `oggenc` manually, and result seem promising (a nice compliant OGG file). I suspect that Firefox will work with this kind of stream as well. I'll try to make an updated example in the `node-radio-stream` repo soon! – TooTallNate Oct 21 '10 at 20:25
  • Awesome! I just noticed the update on the node list - this is really nice! – Scott Wilson Nov 22 '10 at 11:13
  • 2
    For anybody stumbling upon these posts in the future, my `node-radio-stream` module has been renamed to `node-icecast-stack`: https://github.com/TooTallNate/node-icecast-stack – TooTallNate Aug 16 '11 at 01:11
  • 2
    And once again, now `node-icecast-stack` has now been renamed to simply `node-icecast`: https://github.com/TooTallNate/node-icecast – TooTallNate Jan 29 '13 at 22:55
  • 1
    @TooTallNate and now it's just `node-icy`, eh? – 1j01 Oct 22 '16 at 23:04