为何同一视频经不同分段时长生成的M3U8播放列表MD5不一致?
output_30.m3u8 and output_60.m3u8 Have Different Video Stream MD5 Hashes Let’s break down exactly why your two workflows produce mismatched MD5s, even though they start with the same source video:
Key Root Causes
1. Per-segment re-encoding creates frame-dependent differences
Your second step applies the scale=-2:144 filter to each segmented MP4 file. Since you didn’t add -c:v copy here, FFmpeg is re-encoding every segment using its default encoder (usually x264).
- When splitting the source into 30-second vs 60-second chunks, each chunk starts at a different point in the original video’s frame sequence.
- x264 relies on inter-frame compression (P/B frames) that depend on preceding frames. A chunk starting at frame N vs frame M will generate different encoded output—even when scaling to the same resolution. These small differences cascade through every subsequent step of your workflow.
2. Time-based segmentation breaks keyframe alignment
Your initial segment command (-f segment -segment_time 30) splits the video at time boundaries, not keyframe boundaries. This means some chunks start mid-GOP (Group of Pictures), which:
- Forces FFmpeg to generate a new keyframe at the start of each chunk during re-encoding (to make the segment playable independently).
- Creates inconsistent frame dependencies between the 30s and 60s chunk sets, leading to divergent encoded content.
3. Final concat + HLS segmentation amplifies discrepancies
When you concat the segment-specific M3U8 files and re-segment into 10-second chunks, the already divergent video streams will produce completely different 10-second segments. Even one differing early frame will affect every subsequent segment that relies on it.
How to Fix This (Get Matching MD5s)
To ensure both workflows produce identical video streams, decouple scaling from segmentation:
- First scale the entire source video to 144p (do this once, not per segment):
ffmpeg -loglevel error -i input.mp4 -dn -sn -an -vf scale=-2:144 scaled_144p.mp4 - Extract the audio once (same as your original step):
ffmpeg -loglevel error -i input.mp4 -dn -sn -vn -c:a copy audio.aac - Run your two segmentation workflows on the pre-scaled video:
- For 30-second intermediate segments:
ffmpeg -loglevel error -i scaled_144p.mp4 -c:v copy -bsf:v h264_mp4toannexb -copyts -start_at_zero -f segment -segment_time 30 30%03d.mp4 # Then generate M3U8s, concat, and final 10s segments as before - For 60-second intermediate segments:
ffmpeg -loglevel error -i scaled_144p.mp4 -c:v copy -bsf:v h264_mp4toannexb -copyts -start_at_zero -f segment -segment_time 60 60%03d.mp4 # Repeat the same M3U8/concat/final segmentation steps
- For 30-second intermediate segments:
By scaling first, you ensure both workflows start with an identical 144p video stream. Subsequent segmentation and HLS steps only split this identical stream into chunks, so the final video MD5s will match.
Bonus: Ensure Clean Segment Boundaries
To avoid mid-GOP splits entirely (for even more consistency), add -segment_type mpegts and -segment_keyframe_interval 1 to your initial segment command (forces keyframes at segment starts):
ffmpeg -loglevel error -i scaled_144p.mp4 -c:v copy -bsf:v h264_mp4toannexb -copyts -start_at_zero -f segment -segment_time 30 -segment_type mpegts -segment_keyframe_interval 1 30%03d.ts
内容的提问来源于stack exchange,提问作者Saurabh P Bhandari

