問題描述
Siaran Langsung Node.js: Hindari buffering (Node.js Live Streaming: Avoid buffering)
I've written a small nodeJS server that outputs system audio captured by ffmpeg on Windows (using DirectShow) to the browser as a streaming MP3 file. The audio needs to be as live as possible, with minimum/no buffering, and a "skipping" effect in the audio is perfectly acceptable.
When I play the audio in Chrome using the HTML5 audio tag, there's a delay of about 8‑10 secs over a low‑latency LAN connection. I suspected this to be a client‑side buffer, and used a Flash MP3 player on the client‑side, which brought down the delay to 2‑3 secs.
Now, the buffering seems to taking place on the server‑side. The documentation for NodeJS's response.write mentions that the data is written kernel buffers. How do I go about avoiding any buffering altogether or at least getting around it, so that the client always gets the latest audio data? Strategies for handling 'drain' events to always push live data?
On the request object, I've used setNoDelay(true) to avoid the use of Nagle's algorithm. Following is a snippet of how data is written when the spawned ffmpeg process emits data.
var clients = []; //List of client connections currently being served
ffmpeg.stdout.on('data', function(data) {
for(var i = 0; i < clients.length; i++){
clients[i].res.write(data);
}
});
‑‑‑‑‑
參考解法
方法 1:
There are a few places where delay/buffering occurs:
- DirectShow Capturing (~100ms or so)
- FFMPEG MPEG Encoding Buffer (1‑10 seconds, depending on configuration)
- Network Writes and Transmission (near 0 in your setup)
- Client‑Side Buffering (varies by client, as you have seen ‑ most clients buffer ~2 seconds for decoding)
I suspect the buffer you need to look at is the one for FFMPEG encoding. I've been able to reduce this by making sure the input format is configured explicitly when executing FFMPEG. Also, make sure to drop the first chunks of data for encoding, as the first bits will undoubtedly be delayed more than later.
Once you've done this, you will find that your delay is a second or two. At least, that's what I'm getting with a similar setup.
(by Shirish Kamath、Brad)