How to create multi bit rate dash content using ffmpeg dash muxer

19,315

Solution 1

Ok, so this is how I resolved my problem. Following commands are useful for implementing pseudo-live dash content (it's when you want to stream existing video file as if it were a live video) but also the same approach could be used for on-demand video. First, we transform an input video file (sample.divx) into another, well prepared for dash streaming video file - sample_dash.mp4:

ffmpeg -y -i sample.divx ^
  -c:v libx264 -x264opts "keyint=24:min-keyint=24:no-scenecut" -r 24 ^
  -c:a aac -b:a 128k ^
  -bf 1 -b_strategy 0 -sc_threshold 0 -pix_fmt yuv420p ^
  -map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:0 ^
  -b:v:0 250k  -filter:v:0 "scale=-2:240" -profile:v:0 baseline ^
  -b:v:1 750k  -filter:v:1 "scale=-2:480" -profile:v:1 main ^
  -b:v:2 1500k -filter:v:2 "scale=-2:720" -profile:v:2 high ^
  sample_dash.mp4

I'm saying sample_dash.mp4 is well prepared because it's encoded in a good for dash format - H264/ACC and it's containing multiple (3) video streams with different qualities (baseline, main, high). ffmpeg dash muxer will translate these 3 video streams into relevant alternative video quality deash segment files. Here is how:

ffmpeg -y -re -i sample_dash.mp4 ^
  -map 0 ^
  -use_timeline 1 -use_template 1 -window_size 5 -adaptation_sets "id=0,streams=v id=1,streams=a" ^
  -f dash sample.mpd

-re flags tells ffmpeg to process the input video in a realtime manner, which is useful for pseudo-live streaming.

Solution 2

With the help of this answer and documentation, Following is the way to do this in single command:

ffmpeg -i $inputFile \
  -map 0:v:0 -map 0:a\?:0 -map 0:v:0 -map 0:a\?:0 -map 0:v:0 -map 0:a\?:0 -map 0:v:0 -map 0:a\?:0 -map 0:v:0 -map 0:a\?:0 -map 0:v:0 -map 0:a\?:0  \
  -b:v:0 350k  -c:v:0 libx264 -filter:v:0 "scale=320:-1"  \
  -b:v:1 1000k -c:v:1 libx264 -filter:v:1 "scale=640:-1"  \
  -b:v:2 3000k -c:v:2 libx264 -filter:v:2 "scale=1280:-1" \
  -b:v:3 245k  -c:v:3 libvpx-vp9 -filter:v:3 "scale=320:-1"  \
  -b:v:4 700k  -c:v:4 libvpx-vp9 -filter:v:4 "scale=640:-1"  \
  -b:v:5 2100k -c:v:5 libvpx-vp9 -filter:v:5 "scale=1280:-1"  \
  -use_timeline 1 -use_template 1 -window_size 6 -adaptation_sets "id=0,streams=v  id=1,streams=a" \
  -hls_playlist true -f dash output/output.mpd
Share:
19,315
andrii
Author by

andrii

Updated on June 18, 2022

Comments

  • andrii
    andrii about 2 years

    ffmpeg documentation says that we can use dash muxer to create dash segments and manifest file with just a single command, like:

    ffmpeg -re -i <input> -map 0 -map 0 -c:a libfdk_aac -c:v libx264
    -b:v:0 800k -b:v:1 300k -s:v:1 320x170 -profile:v:1 baseline
    -profile:v:0 main -bf 1 -keyint_min 120 -g 120 -sc_threshold 0
    -b_strategy 0 -ar:a:1 22050 -use_timeline 1 -use_template 1
    -window_size 5 -adaptation_sets "id=0,streams=v id=1,streams=a"
    -f dash /path/to/out.mpd
    

    Saying I have some HD video file and I want this video to be available through DASH in different bit rates, so that clients can automatically select from the alternatives based on current network conditions. Can all these be done with a single ffmpeg command, like given above?

    I know there is a solution with using ffmpeg + mp4box, but i'm interested if it could be done with ffmpeg only.

  • Saurabh
    Saurabh about 5 years
    Like You have originally asked is it possible to do all this in single command?
  • silentsudo
    silentsudo almost 5 years
    it can be treated as one command only. If you are using java, rest can be supplied as arguments to command
  • slhck
    slhck over 4 years
    If you're getting the error Only '-vf scale=320:-1' read, ignoring remaining -vf options: Use ',' to separate filters, this is actually not impacting the filters.
  • Ell
    Ell about 4 years
    It seems that separating the commands causes ffmpeg to recode on the second one, is this the expected behaviour?