fix(video): keep source frame timing when transcoding to HLS
Variable-frame-rate sources (phone clips that change capture rate, screen recordings) report r_frame_rate as their 1/90000 timebase. The HLS transcode used the mpegts muxer's default CFR mode, so ffmpeg duplicated frames to fill 90000 fps: on prod, three 2.6-5 s phone clips became 3-second "segments" of up to 446 MB / 250k frames. Players download the whole thing before starting and can't seek within it. -fps_mode vfr passes source timestamps through. Verified on 20220208_164356_01.mp4: 233 frames over 2.578 s in, 233 frames over 2.578 s out, 5.9 MB vs 221 MB. The copy path already keeps timestamps and is unchanged. Requires ffmpeg >= 5.1 (prod runs 8.0.1). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
052609d604
commit
83b1923e25
1 file changed
+6
@@ -668,6 +668,12 @@ impl Handler<GeneratePlaylistMessage> for PlaylistGenerator {
|
||||
// segment starts on a keyframe — accurate seeking without
|
||||
// players having to decode from a prior segment.
|
||||
cmd.arg("-force_key_frames").arg("expr:gte(t,n_forced*3)");
|
||||
// Keep source frame timestamps. Variable-frame-rate phone
|
||||
// clips and screen recordings report r_frame_rate as their
|
||||
// timebase (90000/1); the mpegts muxer's default CFR mode
|
||||
// then duplicates frames to fill it — a 2.6 s clip came out
|
||||
// as 233k frames / 221 MB. vfr leaves timing untouched.
|
||||
cmd.arg("-fps_mode").arg("vfr");
|
||||
}
|
||||
|
||||
// -f hls is required because the playlist is written to a .tmp
|
||||
|
||||
Reference in new issue
Block a user