Stream Video Over HTTP Chunked Encoding with FFmpeg
This guide explains how to stream live or pre-recorded video over HTTP chunked transfer encoding using FFmpeg. You will learn how HTTP chunked transfer works for video, the exact FFmpeg commands required to configure the stream, and how to set up a receiving server to capture the chunked video data in real time.
Understanding HTTP Chunked Transfer Encoding
HTTP chunked transfer encoding allows a server or client to send data
in a series of “chunks” without needing to know the final size of the
content beforehand. This is ideal for live video streaming because the
video is generated continuously, making it impossible to define a
Content-Length header in advance.
By using chunked transfer encoding, FFmpeg can continuously push
video data to an HTTP server using a POST or
PUT request as the video is being encoded.
The FFmpeg Command for Chunked Streaming
To stream video via HTTP chunked transfer encoding, you must use
FFmpeg’s HTTP protocol muxer and enable the -chunked_post
option.
Below is the standard command to stream an input video file (or live camera feed) to a remote server using MPEG-TS format over chunked HTTP:
ffmpeg -re -i input.mp4 -c:v libx264 -preset veryfast -c:a aac -f mpegts -chunked_post 1 http://yourserver.com/live/streamParameter Breakdown:
-re: Reads the input file at its native frame rate. This is required when streaming pre-recorded files to simulate a live stream. (Omit this if you are using a live camera input).-i input.mp4: Specifies the source video file or capture device.-c:v libx264: Encodes the video to H.264, which is widely compatible with streaming players.-preset veryfast: Balance encoding speed and compression efficiency to minimize latency.-c:a aac: Encodes the audio to AAC.-f mpegts: Uses the MPEG Transport Stream (MPEG-TS) container format. This format is ideal for chunked streaming because it can be parsed incrementally without needing the entire file header.-chunked_post 1: Instructs FFmpeg to use HTTP Chunked Transfer Encoding for thePOSTrequest.http://yourserver.com/live/stream: The destination URL of your receiving HTTP server.
Setting Up a Receiving Server
For the stream to work, you need a web server configured to accept
HTTP POST requests and handle the incoming chunked data.
Below is a minimal example using Node.js to receive the stream and save
it to a file on the disk:
const http = require('http');
const fs = require('fs');
const server = http.createServer((req, res) => {
if (req.method === 'POST') {
console.log('Receiving chunked video stream...');
const writeStream = fs.createWriteStream('received_stream.ts');
req.on('data', (chunk) => {
writeStream.write(chunk);
});
req.on('end', () => {
writeStream.end();
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Stream finished');
console.log('Stream completed.');
});
} else {
res.writeHead(404);
res.end();
}
});
server.listen(8080, () => {
console.log('Server listening on port 8080');
});To stream to this local test server, you would point your FFmpeg
command to: http://localhost:8080/.
Optimizing for Low Latency
If you experience high latency when streaming, adjust the following FFmpeg settings to reduce buffering:
- Reduce GOP (Group of Pictures) size: Use
-g 30(or double your framerate) to create frequent keyframes. - Disable B-frames: Use
-bf 0to prevent frame reordering delay. - Tune for latency: Add
-tune zerolatencyto the H.264 encoder options.
An optimized low-latency command looks like this:
ffmpeg -re -i input.mp4 -c:v libx264 -preset veryfast -tune zerolatency -g 30 -bf 0 -c:a aac -f mpegts -chunked_post 1 http://localhost:8080/