Search code examples
ffmpeghttp-live-streaming

FFMPEG Incorrect Stream Index Matching with -var_stream_map


I am using a bash script to run an FFMPEG command to turn an input file called Awoo.mkv into three HLS playlists each with a different resolution, video and audio bitrate.

This is the script:

name=gw

rm /tmp/hls/*

./ffmpeg -y \
    -stream_loop -1 -re \
    -i Awoo.mkv \
    -b:v:0 4000k -b:a:0 512k -s:0 1920x1080 -r:0 30 -g:0 90 -preset:0 superfast -tune:0 zerolatency -profile:v:0 high -level:v:0 4 \
    -b:v:1 2500k -b:a:1 256k -s:1 1280x720 -r:1 30 -g:1 90 -preset:1 superfast -tune:1 zerolatency -profile:v:1 high -level:v:1 4 \
    -b:v:2 800k -b:a:2 255k -s:2 960x540 -r:2 30 -g:2 90 -preset:2 superfast -tune:2 zerolatency -profile:v:2 high -level:v:2 4 \
    -hls_time 6 \
    -hls_list_size 2 \
    -hls_flags delete_segments \
    -map 0:v -map 0:a -map 0:v -map 0:a -map 0:v -map 0:a \
    -var_stream_map "v:0,a:0 v:1,a:1 v:2,a:2" \
    -f hls -master_pl_name "${name}.m3u8" \
    -hls_segment_filename "/tmp/hls/${name}_-%d-%v.ts" \
    "/tmp/hls/${name}_%v.m3u8"

This almost works great, but the output is slightly off...

If you look at these two lines:

-b:v:1 2500k -b:a:1 256k -s:1 1280x720 -r:1 30 -g:1 90 -preset:1 superfast -tune:1 zerolatency -profile:v:1 high -level:v:1 4 \
-b:v:2 800k -b:a:2 255k -s:2 960x540 -r:2 30 -g:2 90 -preset:2 superfast -tune:2 zerolatency -profile:v:2 high -level:v:2 4 \

A resolution of 1280x720 should have a bitrate of 2500k, a resolution of 960x540 should have a bitrate of 800k.

This is the relevant output from FFMPEG:

Stream #0:2(und): Video: h264 (libx264), yuv420p(progressive), 960x540 [SAR 1:1 DAR 16:9], q=-1--1, 2500 kb/s, 30 fps, 90k tbn, 30 tbc (default)
Metadata:
  CREATION_TIME   : 2017-01-27 05:02:53
  LANGUAGE        : und
  HANDLER_NAME    : VideoHandler
  DURATION        : 00:02:24.310000000
  encoder         : Lavc58.18.100 libx264
Side data:
  cpb: bitrate max/min/avg: 0/0/2500000 buffer size: 0 vbv_delay: -1
Stream #0:3(eng): Audio: aac (LC), 44100 Hz, stereo, fltp, 256 kb/s (default)
Metadata:
  LANGUAGE        : eng
  DURATION        : 00:02:24.348000000
  encoder         : Lavc58.18.100 aac
Stream #0:4(und): Video: h264 (libx264), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], q=-1--1, 800 kb/s, 29 fps, 90k tbn, 29 tbc (default)
Metadata:
  CREATION_TIME   : 2017-01-27 05:02:53
  LANGUAGE        : und
  HANDLER_NAME    : VideoHandler
  DURATION        : 00:02:24.310000000
  encoder         : Lavc58.18.100 libx264
Side data:
  cpb: bitrate max/min/avg: 0/0/800000 buffer size: 0 vbv_delay: -1
Stream #0:5(eng): Audio: aac (LC), 44100 Hz, stereo, fltp, 255 kb/s (default)
Metadata:
  LANGUAGE        : eng
  DURATION        : 00:02:24.348000000
  encoder         : Lavc58.18.100 aac

Stream #0:2 is given the wrong resolution of 960x540, and therefore also the wrong bitrate of 2500. This should be the resolution of 1280x720, but this is below matched with the bitrate of 800.

From what I know, the resolutions are showing in the wrong order, if 720 was first and 540 after then everything would match up fine. I'm not sure what's causing this, I am new to the -var_stream_map.

If it is relevant, the entire output from FFMPEG is below:

ffmpeg version 4.0.3-static https://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2018 the FFmpeg developers
  built with gcc 6.3.0 (Debian 6.3.0-18+deb9u1) 20170516
  configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc-6 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gray --enable-libaom --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg
  libavutil      56. 14.100 / 56. 14.100
  libavcodec     58. 18.100 / 58. 18.100
  libavformat    58. 12.100 / 58. 12.100
  libavdevice    58.  3.100 / 58.  3.100
  libavfilter     7. 16.100 /  7. 16.100
  libswscale      5.  1.100 /  5.  1.100
  libswresample   3.  1.100 /  3.  1.100
  libpostproc    55.  1.100 / 55.  1.100
Input #0, matroska,webm, from 'Awoo.mkv':
  Metadata:
    COMPATIBLE_BRANDS: iso6avc1mp41
    MAJOR_BRAND     : dash
    MINOR_VERSION   : 0
    ENCODER         : Lavf56.40.101
  Duration: 00:02:24.35, start: 0.000000, bitrate: 1114 kb/s
    Stream #0:0(und): Video: h264 (Main), yuv420p(tv, bt709, progressive), 1280x720 [SAR 1:1 DAR 16:9], 29 fps, 29 tbr, 1k tbn, 58 tbc (default)
    Metadata:
      CREATION_TIME   : 2017-01-27 05:02:53
      LANGUAGE        : und
      HANDLER_NAME    : VideoHandler
      DURATION        : 00:02:24.310000000
    Stream #0:1(eng): Audio: vorbis, 44100 Hz, stereo, fltp (default)
    Metadata:
      LANGUAGE        : eng
      DURATION        : 00:02:24.348000000
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (vorbis (native) -> aac (native))
  Stream #0:0 -> #0:2 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:3 (vorbis (native) -> aac (native))
  Stream #0:0 -> #0:4 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:5 (vorbis (native) -> aac (native))
Press [q] to stop, [?] for help
[libx264 @ 0x664d1c0] using SAR=1/1
[libx264 @ 0x664d1c0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
[libx264 @ 0x664d1c0] profile High, level 4.0, 4:2:0, 8-bit
[libx264 @ 0x664d1c0] 264 - core 157 r2935 545de2f - H.264/MPEG-4 AVC codec - Copyleft 2003-2018 - http://www.videolan.org/x264.html - options: cabac=1 ref=1 deblock=1:0:0 analyse=0x3:0x3 me=dia subme=1 psy=1 psy_rd=1.00:0.00 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=0 threads=4 lookahead_threads=4 sliced_threads=1 slices=4 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=1 keyint=90 keyint_min=9 scenecut=40 intra_refresh=0 rc=abr mbtree=0 bitrate=4000 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
[libx264 @ 0x664f080] using SAR=1/1
[libx264 @ 0x664f080] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
[libx264 @ 0x664f080] profile High, level 4.0, 4:2:0, 8-bit
[libx264 @ 0x664f080] 264 - core 157 r2935 545de2f - H.264/MPEG-4 AVC codec - Copyleft 2003-2018 - http://www.videolan.org/x264.html - options: cabac=1 ref=1 deblock=1:0:0 analyse=0x3:0x3 me=dia subme=1 psy=1 psy_rd=1.00:0.00 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=0 threads=4 lookahead_threads=4 sliced_threads=1 slices=4 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=1 keyint=90 keyint_min=9 scenecut=40 intra_refresh=0 rc=abr mbtree=0 bitrate=2500 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
[libx264 @ 0x6680b80] using SAR=1/1
[libx264 @ 0x6680b80] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
[libx264 @ 0x6680b80] profile High, level 4.0, 4:2:0, 8-bit
[libx264 @ 0x6680b80] 264 - core 157 r2935 545de2f - H.264/MPEG-4 AVC codec - Copyleft 2003-2018 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=abr mbtree=1 bitrate=800 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
[hls @ 0x6650000] Opening '/tmp/hls/gw_-0-0.ts' for writing
[hls @ 0x6650000] Opening '/tmp/hls/gw_-0-1.ts' for writing
[hls @ 0x6650000] Opening '/tmp/hls/gw_-0-2.ts' for writing
Output #0, hls, to '/tmp/hls/gw_%v.m3u8':
  Metadata:
    COMPATIBLE_BRANDS: iso6avc1mp41
    MAJOR_BRAND     : dash
    MINOR_VERSION   : 0
    encoder         : Lavf58.12.100
    Stream #0:0(und): Video: h264 (libx264), yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=-1--1, 4000 kb/s, 30 fps, 90k tbn, 30 tbc (default)
    Metadata:
      CREATION_TIME   : 2017-01-27 05:02:53
      LANGUAGE        : und
      HANDLER_NAME    : VideoHandler
      DURATION        : 00:02:24.310000000
      encoder         : Lavc58.18.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/4000000 buffer size: 0 vbv_delay: -1
    Stream #0:1(eng): Audio: aac (LC), 44100 Hz, stereo, fltp, 512 kb/s (default)
    Metadata:
      LANGUAGE        : eng
      DURATION        : 00:02:24.348000000
      encoder         : Lavc58.18.100 aac
    Stream #0:2(und): Video: h264 (libx264), yuv420p(progressive), 960x540 [SAR 1:1 DAR 16:9], q=-1--1, 2500 kb/s, 30 fps, 90k tbn, 30 tbc (default)
    Metadata:
      CREATION_TIME   : 2017-01-27 05:02:53
      LANGUAGE        : und
      HANDLER_NAME    : VideoHandler
      DURATION        : 00:02:24.310000000
      encoder         : Lavc58.18.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/2500000 buffer size: 0 vbv_delay: -1
    Stream #0:3(eng): Audio: aac (LC), 44100 Hz, stereo, fltp, 256 kb/s (default)
    Metadata:
      LANGUAGE        : eng
      DURATION        : 00:02:24.348000000
      encoder         : Lavc58.18.100 aac
    Stream #0:4(und): Video: h264 (libx264), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], q=-1--1, 800 kb/s, 29 fps, 90k tbn, 29 tbc (default)
    Metadata:
      CREATION_TIME   : 2017-01-27 05:02:53
      LANGUAGE        : und
      HANDLER_NAME    : VideoHandler
      DURATION        : 00:02:24.310000000
      encoder         : Lavc58.18.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/800000 buffer size: 0 vbv_delay: -1
    Stream #0:5(eng): Audio: aac (LC), 44100 Hz, stereo, fltp, 255 kb/s (default)
    Metadata:
      LANGUAGE        : eng
      DURATION        : 00:02:24.348000000
      encoder         : Lavc58.18.100 aac
[hls @ 0x6650000] Opening '/tmp/hls/gw_0.m3u8.tmp' for writing6.50 bitrate=N/A dup=12 drop=0 speed=0.965x    
[hls @ 0x6650000] Opening '/tmp/hls/gw_1.m3u8.tmp' for writing
[hls @ 0x6650000] Opening '/tmp/hls/gw_2.m3u8.tmp' for writing
[hls @ 0x6650000] Opening '/tmp/hls/gw.m3u8' for writing

Solution

  • Stream specifiers without the stream type prefix will be treated as the absolute stream index. So, -b:v:1 2500k applies to the 2nd video output stream but -s:1 1280x720 applies to the 2nd output stream, which as per your mapping, is an audio stream. Although an option can be media-specific, stream specifiers are evaluated in an agnostic manner.