How to Create a Dynamic DASH Playlist with FFmpeg
This article provides a step-by-step guide on how to create a dynamic, continuously updating DASH (Dynamic Adaptive Streaming over HTTP) playlist using FFmpeg. You will learn the exact command-line parameters required to generate a live stream, manage segment cleanup, set window sizes, and ensure seamless playback for your audience.
To create a dynamic DASH playlist (often used for live streaming),
you must configure FFmpeg to continuously generate media segments
(.m4s files) and constantly update the XML manifest file
(.mpd). Unlike static DASH, a dynamic playlist only
references the most recent segments, preventing the manifest file from
growing indefinitely.
The FFmpeg Command for Dynamic DASH
Below is the standard command used to generate a continuously updating dynamic DASH playlist from a live input source (or a looped file simulating a live source):
ffmpeg -re -i input.mp4 \
-c:v libx264 -preset veryfast -b:v 2000k -g 60 -keyint_min 60 -sc_threshold 0 \
-c:a aac -b:a 128k \
-f dash \
-seg_duration 4 \
-window_size 5 \
-extra_window_size 5 \
-remove_at_exit 0 \
-use_template 1 \
-use_timeline 1 \
-streaming 1 \
live_manifest.mpdKey Parameter Explanations
To ensure your DASH playlist updates continuously without errors, several parameters in the command above are critical:
-re: Tells FFmpeg to read the input in real-time. This is essential when simulating a live stream from a pre-recorded file.-g 60 -keyint_min 60 -sc_threshold 0: Forces a keyframe (I-frame) every 60 frames. Consistent keyframe intervals (GOP size) are mandatory for DASH because segments must begin with a keyframe. If your segment duration is 4 seconds at 15 fps, set your GOP to 60.-f dash: Specifies the output format as DASH.-seg_duration 4: Sets the target duration of each media segment in seconds. Four seconds is a standard balance between latency and encoding efficiency.-window_size 5: This is the core setting for dynamic playlists. It instructs FFmpeg to only keep the last 5 segments in the.mpdmanifest. As segment 6 is created, segment 1 is removed from the manifest.-extra_window_size 5: Keeps an additional 5 older segments on your storage disk after they are removed from the manifest. This prevents slow-loading players from hitting 404 errors on recently expired segments.-use_template 1: Instructs FFmpeg to use template-based URLs in the manifest (e.g.,chunk-stream_$RepresentationID$_$Number$.m4s) rather than listing every single segment file name, keeping the manifest file highly lightweight.-use_timeline 1: Generates highly accurate segment timelines, which helps players maintain synchronization over long streaming periods.-remove_at_exit 0: Prevents FFmpeg from deleting the segments and manifest when the encoding process stops. Set this to1if you want a clean directory immediately after stopping the stream.
Serving the Files
Once you run the command, FFmpeg will continuously write the
live_manifest.mpd and numbered .m4s segment
files to your output directory. Point your web server (such as Nginx or
Apache) to this directory. Ensure your web server is configured with the
following headers to allow seamless browser playback:
- Access-Control-Allow-Origin: * (CORS header allowing players on other domains to fetch the stream)
- Cache-Control: no-cache (Ensures players always
fetch the latest
.mpdfile instead of using a cached version)