Creating an HLS VOD MBR (Multi Bit Rate) stream from a static input file
Consider the option when we need to create an MBR (Multi Bit Rate) HLS VOD stream from a static input file. That is, at the output we should get adaptive video with different resolutions and bitrates for fast playback on different devices. The input file will be input.mp4.
First create a command for one representation
This command creates the HLS VOD playlist and segments of the source file in the output folder:
ffmpeg -i input.mp4 -vf scale=w=1280:h=720:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -b:a 128k -c:v h264 -profile:v main -crf 20 -g 48 -keyint_min 48 -sc_threshold 0 -b:v 2500k -maxrate 2675k -bufsize 3750k -hls_time 4 -hls_playlist_type vod -hls_segment_filename output/720p_%03d.ts output/720p.m3u8
Description of these parameters:
-i input.mp4 – specify the source file
-vf "scale=w=1280:h=720:force_original_aspect_ratio=decrease" – scale the video to the maximum possible within 1280x720, keeping the aspect ratio
-c:a aac -ar 48000 -b:a 128k – set the AAC audio codec with a sampling frequency of 48 kHz and a bit rate of 128k
-c:v h264 – set video codec H264, which is the standard codec segments HLS
-profile:v main – set the H264 profile to main mode - for support in most modern devices
-crf 20 – constant speed coefficient, high level factor for overall quality
-g 48 -keyint_min 48 – IMPORTANT - creates a keyframe (I-frame) every 48 frames (~ 2 seconds); later it will affect the correct cutting of segments
-sc_threshold 0 – do not create key frames when changing scenes, but only in accordance with the -g option
-b:v 2500k -maxrate 2675k -bufsize 3750k – limit bit rate video is taken from the table below
-hls_time 4 – target segment duration in seconds - actual length limited by keyframes
-hls_playlist_type vod – adds the tag #EXT-X-PLAYLIST-TYPE:VOD and saves all segments in the playlist
-hls_segment_filename output/720p_%03d.ts – file segments name mask
output/720p.m3u8 – playlist file path
Several representation
Each representation requires its own parameters, although ffmpeg supports multiple inputs and outputs. Therefore, all representation can be generated in parallel with one long command. It is very important that in addition to the resolution and bitrate parameters, the commands will be identical, so that the representation will be correctly aligned, that is, key frames will be set to identical positions to ensure smooth switching between them on the fly.
We will create 4 representation with popular resolutions:
ffmpeg -hide_banner -y -i input.mp4 \ -vf scale=w=640:h=360:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod -b:v 800k -maxrate 856k -bufsize 1200k -b:a 96k -hls_segment_filename output/360p_%03d.ts output/360p.m3u8 \ -vf scale=w=842:h=480:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod -b:v 1400k -maxrate 1498k -bufsize 2100k -b:a 128k -hls_segment_filename output/480p_%03d.ts output/480p.m3u8 \ -vf scale=w=1280:h=720:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod -b:v 2800k -maxrate 2996k -bufsize 4200k -b:a 128k -hls_segment_filename output/720p_%03d.ts output/720p.m3u8 \ -vf scale=w=1920:h=1080:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod -b:v 5000k -maxrate 5350k -bufsize 7500k -b:a 192k -hls_segment_filename output/1080p_%03d.ts output/1080p.m3u8
Main playlist.
HLS player should know that our video has multiple playback variants, so we create a master list of HLS playback to specify them and save with other playlists and segments:
playlist.m3u8:
#EXTM3U #EXT-X-VERSION:3 #EXT-X-STREAM-INF:BANDWIDTH=800000,RESOLUTION=640x360 360p.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=1400000,RESOLUTION=842x480 480p.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=2800000,RESOLUTION=1280x720 720p.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080 1080p.m3u8
You need to create a main playlist file with these contents in the same folder where the output fragments of the source video file will be created, that is, in the output folder.
Quality | Resolution | Bitrate - low motion | Bitrate - high motion | Audio bitrate |
---|---|---|---|---|
240p | 426x240 | 400k | 600k | 64k |
360p | 640x360 | 700k | 900k | 96k |
480p | 854x480 | 1250k | 1600k | 128k |
HD 720p | 1280x720 | 2500k | 3200k | 128k |
HD 720p 60fps | 1280x720 | 3500k | 4400k | 128k |
Full HD 1080p | 1920x1080 | 4500k | 5300k | 192k |
Full HD 1080p 60fps | 1920x1080 | 5800k | 7400k | 192k |
4k | 3840x2160 | 14000k | 18200k | 192k |
4k 60fps | 3840x2160 | 23000k | 29500k | 192k |