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

Key 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 .mpd manifest. 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 to 1 if 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 .mpd file instead of using a cached version)