How to encode one input file to multiple HLS streams with FFmpeg including the master playlist

8,535

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.

Share:
8,535

Related videos on Youtube

Dennis Mungai
Author by

Dennis Mungai

Updated on September 18, 2022

Comments

  • Dennis Mungai
    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_mapon 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
      Dennis Mungai about 6 years
      Notes: Leave this question marked as open incase anyone else comes across such an issue.