How to encode one input file to multiple HLS streams with FFmpeg including the master playlist
So, apparently, the wrong EXTINF duration observed in alternate streams was caused by a fixed defect, see patchwork here.
A sample snippet that will produce three variant HLS renditions, assuming that the incoming video stream has a frame rate of 29.97 fps, and using a fixed GOP size, via the NVENC encoder, can be done as such:
ffmpeg -loglevel debug -threads 4 -vsync 1 -i '/home/lin/Desktop/src/sowdtow.webm' \
-vf yadif -g 29.97 -r 29.97 \
-b:v:0 5250k -c:v h264_nvenc -preset llhq -rc:v vbr_hq -pix_fmt yuv420p -profile:v main -level 4.1 -strict_gop 1 -rc-lookahead 32 -no-scenecut 1 -forced-idr 1 -gpu 0 \
-b:v:1 4200k -c:v h264_nvenc -preset llhq -rc:v vbr_hq -pix_fmt yuv420p -profile:v main -level 4.1 -strict_gop 1 -rc-lookahead 32 -no-scenecut 1 -forced-idr 1 -gpu 1 \
-b:v:1 3150k -c:v h264_nvenc -preset llhq -rc:v vbr_hq -pix_fmt yuv420p -profile:v main -level 4.1 -strict_gop 1 -rc-lookahead 32 -no-scenecut 1 -forced-idr 1 -gpu 2 \
-b:a:0 256k \
-b:a:0 192k \
-b:a:0 128k \
-c:a aac -ar 48000 -map 0:v -map 0:a:0 -map 0:v -map 0:a:0 -map 0:v -map 0:a:0 \
-f hls -var_stream_map "v:0,a:0 v:1,a:1 v:2,a:2" \
-master_pl_name master.m3u8 -t 300 -hls_time 10 -hls_init_time 4 -hls_list_size 10 -master_pl_publish_rate 10 -hls_flags delete_segments+discont_start+split_by_time \
"/home/lin/Desktop/dest/vs%v/manifest.m3u8"
Marking as solved.
Related videos on Youtube
Dennis Mungai
Updated on September 18, 2022Comments
-
Dennis Mungai over 1 year
Here's the scenario:
I need to encode a single input file, assume with libx264 to multiple HLS streams, and the goal is to also generate the HLS master playlist with the same FFmpeg snippet.
From FFmpeg's documentation on the same, they describe a scenario that takes in multiple inputs, such as MPEG transport streams, classifying the audio and video streams therein, and then generating multiple HLS streams as specified above, as shown here. See the documentation on
var_stream_map
on the same page.A similar question has been asked before, but the user's case describes the scenario documented by FFmpeg.
Any leads will do, thanks.
Follow-up:
I have made some progress to the query above.
One can set the same input more than once, allowing for both a remap of the inputs AND a re-encode on the fly that can then be muxed into HLS as shown below with the
h264_nvenc
encoder:ffmpeg -loglevel debug -threads 4 -i /home/lin/Desktop/src/sowdtow.webm \ -i /home/lin/Desktop/src/sowdtow.webm \ -map '0:v' -c:v h264_nvenc -s 1920x1080 -preset llhq -rc:v vbr_hq -pix_fmt yuv420p -profile:v main -level 4.1 -b:v 3500k -maxrate:v 4250k -bufsize:v 8400k -map '0:a' -c:a aac -ab 128k \ -map '1:v' -c:v h264_nvenc -s 1280x720 -preset llhq -rc:v vbr_hq -pix_fmt yuv420p -profile:v main -level 4.1 -b:v 2800k -maxrate:v 2996k -bufsize:v 4200k -map '1:a' -c:a aac -ab 128k \ -f hls -var_stream_map "v:0,a:0 v:1,a:1" -hls_segment_filename 'vs%v/file_%03d.ts' -hls_time 5 -master_pl_name 'mainmanifest.m3u8' /home/lin/Desktop/dest/vs%v/manifest.m3u8
However, this command has the following anomaly: It outputs the last stream (-map 1:v -map:1:a) twice, ignoring the first and second streams completely:
less mainmanifest.m3u8 #EXTM3U #EXT-X-VERSION:3 #EXT-X-STREAM-INF:BANDWIDTH=3220800,RESOLUTION=1280x720,CODECS="avc1.4d4029,mp4a.40.2" vs0/manifest.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=3220800,RESOLUTION=1280x720,CODECS="avc1.4d4029,mp4a.40.2" vs1/manifest.m3u8
Which may help in narrowing down the issue to a remap issue for the HLS muxer.
Still investigating. This stinks of a syntax error somewhere in the command above, will update as soon as I have a fix for that.
Edit:
It was caused by a bug in FFmpeg: https://trac.ffmpeg.org/ticket/7073 which is now fixed.
-
Dennis Mungai about 6 yearsNotes: Leave this question marked as open incase anyone else comes across such an issue.
-