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

Streamingnode.jsAudio StreamingShoutcastHtml5 Audio

Streaming Problem Overview


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

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

Streaming Solutions


Solution 1 - Streaming

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!

Solution 2 - Streaming

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)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionScott WilsonView Question on Stackoverflow
Solution 1 - StreamingTooTallNateView Answer on Stackoverflow
Solution 2 - StreamingWinlinView Answer on Stackoverflow