2

I'm trying to make a simulated live HLS/DASH server using the equivalent of the following chain:

tsplay -loop multi_resolution.ts | shaka_packager | nginx

The problem is creating the file "multi_resolution.ts": It needs to contain a single program with 1 audio and 3 video PIDs, one each for 720p, 480p and 360p. Why? Because that's the way shaka_packager needs it to be.

I think I'm confused by how to map the transcoded streams to the output file. Here the non-working command I've been struggling with:

ffmpeg -i "big_buck_bunny_1080p.mov" -threads 16 \
    -c:a aac -ac 2 -b:a:0 128k \
    -c:v libx264 -pix_fmt yuv420p -profile:v high -level 4.0 -preset veryslow -tune film \
        -vsync cfr -x264-params "nal-hrd=cbr" \
        -b:v:1 5000k -minrate 2000k -maxrate 2000k -bufsize 4000k -g 30 -s 1280x720 \
    -c:v libx264 -pix_fmt yuv420p -profile:v high -level 4.0 -preset veryslow -tune film \
        -vsync cfr -x264-params "nal-hrd=cbr" \
        -b:v:2 1500k -minrate 1000k -maxrate 1000k -bufsize 2000k -g 30 -s 854x480 \
    -c:v libx264 -pix_fmt yuv420p -profile:v high -level 4.0 -preset veryslow -tune film \
        -vsync cfr -x264-params "nal-hrd=cbr" \
        -b:v:3 500k -minrate 500k -maxrate 500k -bufsize 1000k -g 30 -s 640x360 \
    -program program_num=1:title=multi_p30:st=0:st=1:st=2:st=3 \
    -f mpegts "big_buck_bunny_720_480_360.ts"

I tested each of the encodings in isolation, and they look good. I suspect the problem is with my stream management/mapping.

Help?

BobC
  • 135
  • 10

1 Answers1

3

In order to insert multiple stream in an output, each input stream needs to be expressly mapped. The encoding options, by themselves, do not create a stream assignment in the output. There is the matter of automatic stream selection, which isn't applicable here, but you can read about it at https://ffmpeg.org/ffmpeg.html#Stream-selection

So,

ffmpeg -i "big_buck_bunny_1080p.mov" -threads 16 \
    -map 0:a -map 0:v -map 0:v -map 0:v \
    -c:a aac -ac 2 -b:a 128k \
    -s:v:0 1280x720 -s:v:1 854x480-s:v:2 640x360 \
    -g 30 -c:v libx264 -pix_fmt yuv420p -profile:v high -level 4.0 -preset veryslow -tune film \
    -vsync cfr -x264-params "nal-hrd=cbr" \
    -b:v:0 5000k -minrate:v:0 2000k -maxrate:v:0 2000k -bufsize:v:0 4000k \
    -b:v:1 1500k -minrate:v:1 1000k -maxrate:v:1 1000k -bufsize:v:1 2000k \
    -b:v:2 500k -minrate:v:2 500k -maxrate:v:2 500k -bufsize:v:2 1000k \
    -program program_num=1:title=multi_p30:st=0:st=1:st=2:st=3 \
    -f mpegts "big_buck_bunny_720_480_360.ts"
Gyan
  • 34,439
  • 6
  • 56
  • 98
  • Ah, so I create the mapping *at the start*, then overlay it with different content. However, I do still need to do the 3 encodings to different resolutions, not just different bit rates. and my ":n" go after the -c:v, not the -b:v, right? – BobC Nov 28 '18 at 15:45
  • size, codec, bitrates are all per-stream options so for each output stream, the option should be set with the key `-option:stream_type:index` – Gyan Nov 28 '18 at 15:51
  • I'm getting confused again: Let's say I wanted to add a text overlay. Can I apply it to the single video stream before mapping, so that each of the subsequent 3 output encodings will contain it? Or must it be applied to each of the 3 video streams after mapping? – BobC Nov 28 '18 at 15:58
  • `-vf` is short for `-filter:v` so a `-vf` or `-filter:v` argument would be applied to all output video streams. If you wanted to apply a different overlay expression to each stream, then you would add `-filter:v:0 filters0` `-filter:v:1 filters1` and `-filter:v:2 filters2`. Within a single output file, the order of options does not matter, so the maps can come before or after the filters or the bitrate. – Gyan Nov 28 '18 at 16:08
  • Also, see my answer to https://superuser.com/q/1219784/114058 – Gyan Nov 28 '18 at 16:10
  • Many thanks! I think part of my confusion is that I don't understand which ffmpeg options do or do not accept stream specifiers. The documentation appears to avoid mentioning it at the definition level, leaving me to puzzle it out from uncommented examples. Is there a cheat-sheet I could use? Edit: The BNF for the ffmpeg options syntax would do nicely... – BobC Nov 28 '18 at 16:15
  • I may also be confused by codec options vs. ffmpeg options. It's all alphabet soup to me: The context and binding is not at all intuitive, so a master all-inclusive ffmpeg command-line syntax diagram would be immensely useful. – BobC Nov 28 '18 at 16:27
  • In general, codec-related and filtering options are per stream and format-related or other options aren't. Exceptions like metadata are format related but can be per-stream. A BNF for filters is available at https://ffmpeg.org/ffmpeg-filters.html#Filtergraph-syntax-1 – Gyan Nov 28 '18 at 16:29
  • *a master all-inclusive ffmpeg command-line syntax diagram would be immensely useful* --> on my ToDo but will take a while. – Gyan Nov 28 '18 at 16:29
  • OK, back to the original command: What is the context and scope for libx264 options such as -preset and -tune? Since they do not accept a stream specifier, so do they automatically apply to *all* uses of libx264? Or just in some magical space between "-c[stream_specifier] libx264" and the next "whatever" that ***is not*** a libx264 option? Does the appearance of such an option terminate the processing of libx264 options? When do I need to repeat -preset, and when do I not need to repeat it? – BobC Nov 28 '18 at 16:59
  • `-preset` and `-tune` are codec options, even if private, and so accept stream specifiers. – Gyan Nov 28 '18 at 17:13
  • Conversely, if I omit stream specifiers on `-preset` and `-tune` then they apply to all uses of `libx264` and thus need be mentioned exactly once in the `ffmpeg` command. Right? Where is this arcane stuff documented? Google fails to find even a single example! – BobC Nov 28 '18 at 18:12
  • Right. And see https://ffmpeg.org/ffmpeg.html#AVOptions – Gyan Nov 28 '18 at 18:13
  • Stream specifiers are needed for ***each*** option in ***every*** `-b` line, else all will be encoded with the last options seen. – BobC Nov 29 '18 at 16:22
  • Yes, I missed those. – Gyan Nov 29 '18 at 16:56
  • I just added a scrolling text overlay to each encoding showing it's resolution: ` -filter:v:? "drawtext=fontfile=/usr/share/fonts/truetype/freefont/FreeSans.ttf \ :text='???p30 ?Mbps':fontcolor=white@1.0 \ :fontsize=40:y=h-line_h-30:x=w/20*mod(t\,20)" \` Replace question marks with appropriate value for each encoding. – BobC Nov 29 '18 at 18:35