What You’ll Learn

  • The basic MPEG-DASH segmenting command
  • Multi-bitrate adaptive streaming (ABR) setup
  • Segment duration (-seg_duration) and initialization file settings
  • Key differences between HLS and MPEG-DASH
  • Comparison of VOD and live streaming options

Tested with: FFmpeg 6.1 (ubuntu-latest / CI-verified) Platform: Windows / macOS / Linux


MPEG-DASH Fundamentals

MPEG-DASH (Dynamic Adaptive Streaming over HTTP) is a standard that delivers video over HTTP by splitting it into small segment files.

ComponentDescription
MPD fileManifest (equivalent to a playlist)
Segment fileThe actual video/audio data (typically 2–10 seconds)
RepresentationA bitrate/resolution combination
AdaptationSetA group of video or audio streams

Basic Command (Single Bitrate)

ffmpeg -i input.mp4 -c:v libx264 -b:v 1500k -c:a aac -b:a 128k -f dash -seg_duration 4 output.mpd

This produces:

  • output.mpd — the manifest file
  • init-stream0.m4s — video initialization segment
  • init-stream1.m4s — audio initialization segment
  • chunk-stream0-XXXXX.m4s — numbered video segments
  • chunk-stream1-XXXXX.m4s — numbered audio segments

Multi-Bitrate ABR Setup

The real power of adaptive streaming comes from generating multiple quality levels in parallel. Use -map to produce several bitrates from the same input.

ffmpeg -i input.mp4 \
  -map 0:v -map 0:a -map 0:v -map 0:a \
  -c:v libx264 \
  -b:v:0 2500k -s:v:0 1280x720 \
  -b:v:1 800k  -s:v:1 854x480 \
  -c:a aac -b:a 128k \
  -f dash \
  -seg_duration 4 \
  -adaptation_sets "id=0,streams=v id=1,streams=a" \
  output.mpd

The command above produces two bitrates: 720p (2500 kbps) and 480p (800 kbps). The player switches between them automatically based on network conditions.


Key Options

OptionExampleDescription
-seg_duration4Segment length in seconds (usually 2–6)
-use_timeline1SegmentTimeline mode (recommended for VOD)
-use_template1Template URLs (recommended for live)
-window_size5Number of segments kept in the manifest during live
-adaptation_sets"id=0,streams=v"Grouping of representations
-init_seg_name"init_$RepresentationID$.m4s"Initialization segment name template
-media_seg_name"seg_$Number$.m4s"Media segment name template

VOD Settings

ffmpeg -i input.mp4 \
  -c:v libx264 -b:v 1500k \
  -c:a aac -b:a 128k \
  -f dash \
  -seg_duration 4 \
  -use_timeline 1 \
  -use_template 1 \
  output.mpd

Choosing HLS vs. MPEG-DASH

CriterionHLSMPEG-DASH
Native Safari supportYes (built-in)Partial (requires JS)
Segment format.ts / .m4s.m4s / .mp4
Standards bodyApple proprietaryISO international
Dynamic ABR switchingYesYes
Primary use caseiOS and SafariGeneral-purpose / OTT

Frequently Asked Questions

DASH vs HLS — which should I use?

HLS is mandatory for iOS/Safari, DASH is preferred for desktop browsers and smart TVs. For the widest reach, generate both with -hls_segment_filename and -dash.

What segment length should I pick?

4–6 second segments balance startup time and switching latency. Shorter (2 s) gives faster channel-change but increases manifest churn and CDN cost.

Why does my DASH player buffer at every quality switch?

Most likely keyframes are not aligned across renditions. Force keyframes with -force_key_frames "expr:gte(t,n_forced*4)" for every rendition.

Can I do live DASH from FFmpeg directly?

Yes — -f dash -window_size 5 -extra_window_size 10 produces a sliding live window. Pair it with HTTP PUT to a CDN ingest endpoint.

Do I need separate audio segments?

For multi-bitrate or multi-language audio, yes. Use -adaptation_sets "id=0,streams=v id=1,streams=a" to split video and audio sets.



Tested with ffmpeg 6.1 / Ubuntu 24.04 (GitHub Actions runner) Primary sources: ffmpeg.org/ffmpeg-formats.html#dash / trac.ffmpeg.org/wiki/Create%20a%20DASH%20playlist