Streaming audio from a Node.js server to HTML5 <audio> tag
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 Fi开发者_如何学JAVArefox. Any ideas?
Possible candidates including encoding issues, or just partially-implemented HTML5 features...
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!
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)
精彩评论