I have three videos: low.mp4, mid.mp4
and high.mp4
, all of which were generated from the same source file using ffmpeg with the following command:
ffmpeg -y -i source.mp4 -c:v libx264 -crf SOMEVALUE -preset veryfast -vsync 0 -bf 0 -x264-params scenecut=0:keyint=25:min-keyint=25 -c:a aac -ab 128k -f mp4 OUTPUT.mp4
Now, I want to stream these videos using the HLS protocol. I use the following ffmpeg command to generate the HLS streams:
ffmpeg -i low.mp4 -i mid.mp4 -i high.mp4 \
-map 0:v -map 0:a -map 1:v -map 1:a -map 2:v -map 2:a \
-c:v copy -c:a copy \
-hls_time 4 -hls_playlist_type vod -hls_segment_type fmp4 \
-hls_flags independent_segments \
-var_stream_map "v:0,a:0,name:low v:1,a:1,name:mid v:2,a:2,name:high" \
-master_pl_name master.m3u8 \
-hls_segment_filename '%v/segment-%06d.m4s' \
-hls_fmp4_init_filename '%v/init.mp4' \
-strftime_mkdir 1 \
-f hls '%v.m3u8'
While this command does generate the HLS streams, the resulting video quality is poor. However, if I omit the -c:v copy -c:a copy
flags, the video quality is good, but the command takes significantly longer to run because it re-encodes the video.
I'm looking for a solution that meets the following requirements:
Separate Quality Generation: The different quality versions (low.mp4, mid.mp4, high.mp4) should be created in a separate step. This is important because, in practice, we speed up this process by cutting the videos into smaller pieces, transcoding them in parallel, and then recombining them.
No Re-encoding During HLS Generation: The HLS generation step should not involve re-encoding the video, to save time.
High-Quality HLS Output: The final HLS output should have good video quality, similar to what is achieved when re-encoding.
Is this possible? How?