This is a series of articles. Follow the link here to get an overview over all articles.
Previously
on Using FFmpeg as a HLS streaming server (Part 2) - Enhanced HLS Segmentation
The livestream with constant segment duration including x264 video encoding and aac audio encoding is working well.
ffmpeg -listen 1 -i rtmp://martin-riedl.de/stream01 \
-c:v libx264 -crf 21 -preset veryfast -g 25 -sc_threshold 0 \
-c:a aac -b:a 128k -ac 2 \
-f hls -hls_time 4 -hls_playlist_type event stream.m3u8
Now it’s time to support multiple quality versions. In my case it should be the full HD variant and a second SD variant. This article focuses on the video quality.
Multiple playlists
There will be a playlist with the segments for each quality level. All of this stream playlists are then listed in a master playlist. Since now, the master playlist will be used as video URL.
stream_%v.m3u8
%v must be added in the output stream name.
This is a number counting from 0 for the stream variant.
In my case 0 will be the lower quality, 1 the higher quality.
-master_pl_name master.m3u8
This will create the new master playlist that contains the list of streams.
Video-Bitrates
Again, Apple provides a list of recommendations for resolutions and the bitrates that should be used.
I decided to use for full HD (1920x1080 6000kb/s) and for SD (960x540 2000kb/s).
This replaces the -crf value, so this is no longer used and removed from our command.
-preset veryfast -g 25 -sc_threshold 0
This parameters stay as is and are used for all video variants.
-map v:0 -c:v:0 libx264 -b:v:0 2000k
-map v:x tells ffmpeg that a new video variant starts. x is the number of input video signal.
Since I have only one video input, the index 0 is used here.
-c:v:x sets the codec for each variant.
I will just use h264.
-b:v:0 sets the bitate for stream 0 (the lower quality).
Since I want to have two different bitrates, the following parameter sequence is used:
-map v:0 -c:v:0 libx264 -b:v:0 2000k
-map v:0 -c:v:1 libx264 -b:v:1 6000k
If you want to have more variants, just copy one of this lines and change the index.
Audio-Bitrates
Well, it’s possible to do the same as we have done with the video bitrates for the audio bitrate. But I want to have for both the same audio quality (since this is not using a lot of bandwidth).
-map a:0 -map a:0
Therefore, the map command must just be placed twice before the codec settings. If you have more streams, repeat this map command.
Bringing all together
-var_stream_map "v:0,a:0 v:1,a:1"
This tells FFmpeg what streams are combined together. A space separates each variant and everything that should be placed together is concatenated with a comma.
So the full command is now:
ffmpeg -listen 1 -i rtmp://martin-riedl.de/stream01 \
-preset veryfast -g 25 -sc_threshold 0 \
-map v:0 -c:v:0 libx264 -b:v:0 2000k \
-map v:0 -c:v:1 libx264 -b:v:1 6000k \
-map a:0 -map a:0 -c:a aac -b:a 128k -ac 2 \
-f hls -hls_time 4 -hls_playlist_type event \
-master_pl_name master.m3u8 \
-var_stream_map "v:0,a:0 v:1,a:1" stream_%v.m3u8