Generate DASH Manifests with FFmpeg

This article explains how to segment video and audio streams to generate a Dynamic Adaptive Streaming over HTTP (DASH) manifest using FFmpeg. While FFmpeg includes a generic segment muxer (-f segment), that specific muxer only outputs formats like HLS playlists (.m3u8), CSVs, and flat file lists. To generate a standard DASH manifest (.mpd) alongside segmented media files, FFmpeg provides a dedicated dash muxer (-f dash). The following sections explain how to configure this muxer to control segment duration, stream mapping, and file output.

Basic DASH Segmentation Command

To create a DASH manifest and chunk your media into segments, use the -f dash muxer with an .mpd output extension:

ffmpeg -i input.mp4 -c:v libx264 -c:a aac -f dash output.mpd

This command re-encodes the inputs into standard H.264 video and AAC audio, divides the streams into fragmented MP4 segments (.m4s), and generates the main XML manifest (output.mpd).

Controlling Segment Duration and Templates

To match standard streaming requirements, you must control segment lengths and ensure consistent keyframe intervals. Keyframes (GOP size) must align with the target segment duration.

ffmpeg -i input.mp4 \
  -c:v libx264 -b:v 2000k -g 48 -keyint_min 48 -sc_threshold 0 \
  -c:a aac -b:a 128k \
  -seg_duration 2 \
  -use_template 1 \
  -use_timeline 1 \
  -init_seg_name 'init-$RepresentationID$.m4s' \
  -media_seg_name 'chunk-$RepresentationID$-$Number%05d$.m4s' \
  -f dash output.mpd

Parameter Breakdown

  • -g 48 and -keyint_min 48: Sets the Group of Pictures (GOP) size to 48 frames. For 24 fps video, this places an I-frame every 2 seconds.
  • -sc_threshold 0: Disables scene-change detection to prevent irregular keyframe spacing.
  • -seg_duration 2: Sets the target segment length to 2 seconds.
  • -use_template 1: Instructs the manifest to use <SegmentTemplate> elements, reducing the overall file size of the manifest.
  • -use_timeline 1: Adds precise segment timing information to the manifest.
  • -init_seg_name: Defines the filename format for stream initialization segments.
  • -media_seg_name: Defines the naming convention for individual media segments.

Multi-Bitrate DASH Generation

DASH is primarily used for adaptive bitrate streaming. You can generate multiple quality levels simultaneously within a single FFmpeg command:

ffmpeg -i input.mp4 \
  -map 0:v:0 -map 0:v:0 -map 0:a:0 \
  -c:v:0 libx264 -b:v:0 800k  -s:v:0 640x360  -g 48 -keyint_min 48 -sc_threshold 0 \
  -c:v:1 libx264 -b:v:1 2500k -s:v:1 1280x720 -g 48 -keyint_min 48 -sc_threshold 0 \
  -c:a:0 aac -b:a:0 128k \
  -adaptation_sets "id=0,streams=v id=1,streams=a" \
  -seg_duration 2 \
  -use_template 1 \
  -use_timeline 1 \
  -f dash output.mpd
  • -adaptation_sets "id=0,streams=v id=1,streams=a": Groups all video representations into one adaptation set and all audio representations into another, allowing video players to switch resolutions dynamically during playback based on available bandwidth.