0
votes

Here are a few commands I am using to convert and transize a video in MP4 format to a M3U8 playlist.

For a given input video (MP4 format), generate multiple video segments with segment duration 30 seconds.

ffmpeg -loglevel error -i input.mp4 -dn -sn -an -c:v copy -bsf:v h264_mp4toannexb -copyts -start_at_zero -f segment -segment_time 30 30%03d.mp4 -dn -sn -vn -c:a copy audio.aac

Apply a video filter (in this case scaling) on each segment and convert it to a M3U8 format.

ls 30*.mp4 | parallel 'ffmpeg -loglevel error -i {} -vf scale=-2:144 -hls_list_size 0 {}.m3u8'

Store the list of m3u8 files generated in list.txt in this format file 'segment-name.m3u8'

for f in 30*.m3u8; do echo "file '$f'" >> list.txt; done

Using concat demuxer, combine all segment files (which are in M3U8 format) and the audio to get one final m3u8 playlist pointing to segments with duration of 10 seconds.

ffmpeg -loglevel error -f concat -i list.txt -i audio.aac -c copy -hls_list_size 0 -hls_time 10 output_30.m3u8

I can change the segment duration in the first step from 30 seconds to 60 seconds, and compare the MD5 hash of the final M3U8 playlist generated in both the cases using this command:

ffmpeg -loglevel error -i <input m3u8 playlist> -f md5 -

The MD5 hash of the output files differ, i.e., video streams of output_30.m3u8 and output_60.m3u8 are not the same.

Can anyone elaborate on this?

(I expected the MD5 hash to be the same)

2

2 Answers

0
votes

An M3U8 file is just a text file. Run diff on them, and it will tell you exactly what is different.

0
votes

Adding -crf 0 (which implies lossless encoding) in the second step, gives the same checksums.

In case of lossy encoding, from what I have learnt so far, segmented encodes are bound to be different from normal encodes due to threads (quality differs as more threads are used) and lossy codec. Even with options such as --stitchable (x264 parameter) and --threads 1 (FFmpeg output option), the checksum differs.