Streaming audio from a Node.js server to HTML5 <audio> tag

Viewed 41717

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...

2 Answers

There are some solutions for H5 audio only live streaming:

  • HLS or LLHLS: The best compatibility, for Safari, Android, iOS. Now with MSE, Chrome is also able to play HLS by hls.js. Note that the latency is about 10s or larger for audio only stream.
  • HTTP-MP3: It's also widely supported solution, but because mp3 codec is used less and less, now aac and opus is much popular in H5. So, it is NOT recommend to use HTTP-MP3.
  • HTTP-AAC: It's supported by H5 browser, but generally not supported by CDN, so it's OK if you build your own server, but NOT if need a CDN.
  • HTTP-FLV or HTTP-TS: Use flv.js or mpegts.js by MSE. The latency is lower than HLS, and it's possible to use AAC codec, so it's a good solution also.
  • WebRTC: Yep, it's also possible to play the audio only stream by WebRTC.

Note: Opus is also available by HTTP-OGG, but ogg is not support by all browsers, and CDN does not support it, so it's NOT recommend.

Let's take a view for your stream source, however you didn't mention about it:

  • If use H5 to publish your stream, only WebRTC is available now.
  • If use IP camera, you must pull RTSP stream then covert to RTMP by FFmpeg, as such.
  • If use OBS, both RTMP or SRT is OK.

So the best solution maybe use a server(SRS) to convert your stream for player:

publisher(WebRTC, OBS, FFmpeg) 
    --RTMP/WebRTC--> Server(SRS) 
        --HLS/HTTP-FLV/WebRTC--> player(H5 audio)
Related