FFmpeg: tee muxer fails on multiple outputs HLS and .mp4

audioffmpeghlsvideovideo conversion

I'm trying to encode an input .mp4 for both HLS and re-size into separate .mp4 files using the tee muxer, and HLS's "var_stream_map". When I run the below command with both HLS and .mp4s in the tee muxer, it fails. It does not fail when running the HLS only. Any ideas?

ffmpeg \
-hide_banner \
-report \
-benchmark \
-vstats \
-i INPUT.MP4 \
-dn \
-sn \
-filter_complex \
"[0:v]fps=fps=24000/1001, \
setpts=(PTS-STARTPTS), \
split=6[vsplit1][vsplit2][vsplit3][vsplit4][vsplit5][vsplit6]; \
[vsplit1]scale=-1:144[video_144]; \
[vsplit2]scale=-1:144[video_144h]; \
[vsplit3]scale=-1:270[video_270]; \
[vsplit4]scale=640:360[base_360]; \
[vsplit5]scale=1280:720[base_720]; \
[vsplit6]scale=1920:1080[base_1080]" \
\
-map "[video_144]" \
-r:v:0 "24000/1001" \
-c:v:0 "libx264" \
-x264-params "keyint=144:min-keyint=144:scenecut=0:open_gop=0" \
-preset:v:0 "slow" \
-profile:v:0 "baseline" \
-level:v:0 "3.0" \
-refs:v:0 "2" \
-b-pyramid:v:0 "strict" \
-tune:v:0 "film" \
-b:v:0 "56000" \
-maxrate:v:0 "56000" \
-bufsize:v:0 "6*56000/8" \
-vsync:v:0 "cfr" \
-bsf:v:0 "h264_metadata=fixed_frame_rate_flag=1" \
\
-map "[video_144h]" \
-r:v:1 "24000/1001" \
-c:v:1 "libx264" \
-x264-params "keyint=144:min-keyint=144:scenecut=0:open_gop=0" \
-preset:v:1 "slow" \
-profile:v:1 "high" \
-level:v:1 "4.1" \
-refs:v:1 "2" \
-b-pyramid:v:1 "strict" \
-tune:v:1 "film" \
-b:v:1 "64000" \
-maxrate:v:1 "64000" \
-bufsize:v:1 "6*64000/8" \
-vsync:v:1 "cfr" \
-bsf:v:1 "h264_metadata=fixed_frame_rate_flag=1" \
\
-map "[video_270]" \
-r:v:2 "24000/1001" \
-c:v:2 "libx264" \
-x264-params "keyint=144:min-keyint=144:scenecut=0:open_gop=0" \
-preset:v:2 "slow" \
-profile:v:2 "main" \
-level:v:2 "3.1" \
-refs:v:2 "2" \
-b-pyramid:v:2 "strict" \
-tune:v:2 "film" \
-b:v:2 "200000" \
-maxrate:v:2 "200000" \
-bufsize:v:2 "6*200000/8" \
-vsync:v:2 "cfr" \
-bsf:v:2 "h264_metadata=fixed_frame_rate_flag=1" \
\
-map "[base_360]" \
-c:v:3 "libx264" \
-preset:v:3 "slow" \
\
-map "[base_720]" \
-c:v:4 "libx264" \
-preset:v:4 "slow" \
\
-map "[base_1080]" \
-c:v:5 "libx264" \
-preset:v:5 "slow" \
\
-map a:0 -map a:0 -map a:0 -map a:0 -map a:0 -map a:0 \
-c:a "libfdk_aac" \
-ar "48000" \
-ab "128k" \
-af "aresample=async=1:min_hard_comp=0.100000:first_pts=0" \
\
-f tee \
"[f=hls: \
hls_flags=discont_start+temp_file: \
hls_time=6: \
hls_list_size=0: \
var_stream_map=\'v:0,a:0 v:1,a:1 v:2,a:2\': \
master_pl_name=playlist.m3u8: \
hls_segment_filename=out_%v_%d.ts]out_%v.m3u8| \
[select=\'v:3,a:3\':f=mp4:movflags=+faststart]sm-640-360.mp4| \
[select=\'v:4,a:4\':f=mp4:movflags=+faststart]med-1280-720.mp4| \
[select=\'v:5,a:5\':f=mp4:movflags=+faststart]large-1920-1080.mp4"

Error given:

[hls @ 0x7fcdce32aa00] Unable to find mapping variant stream    
[1]    79703 segmentation fault  ffmpeg -hide_banner -report -benchmark -vstats -i  -dn -sn

Best Answer

  • Without select for a given tee output, all output streams are sent to that tee output. So, the HLS muxer will expect var_stream_map to set mapping for all received streams. But your var_stream_map only handles the first three video and audio streams. So, add select=\'v:0,a:0,v:1,a:1,v:2,a:2\' for the HLS output.

    P.S. when using tee, for output to MP4 or other formats with global headers, like FLV, you have to add -flags +global_header to satisfy players like Quicktime, which expect to read stream parameter sets only from the header.

  • Related Question