diff --git a/backend/src/ffmpeg/error.rs b/backend/src/ffmpeg/error.rs index d238214..fcf05a4 100644 --- a/backend/src/ffmpeg/error.rs +++ b/backend/src/ffmpeg/error.rs @@ -11,6 +11,8 @@ pub enum VideoInfoError { #[error("Failed to read bitrate from video")] NoBitrate, #[error("Failed to read video duration from video")] + NoTimeScale, + #[error("Failed to read time scale value from video")] NoDuration, #[error("No stream in video file")] NoStream, diff --git a/backend/src/ffmpeg/render.rs b/backend/src/ffmpeg/render.rs index fabc0db..3366a5e 100644 --- a/backend/src/ffmpeg/render.rs +++ b/backend/src/ffmpeg/render.rs @@ -40,6 +40,7 @@ pub fn start_video_render( video_info.width, video_info.height, video_info.frame_rate, + video_info.time_base, render_settings.bitrate_mbps, &render_settings.encoder, output_video, @@ -116,6 +117,7 @@ pub fn spawn_encoder( width: u32, height: u32, frame_rate: f32, + time_base: u32, bitrate_mbps: u32, video_encoder: &Encoder, output_video: &PathBuf, @@ -139,6 +141,7 @@ pub fn spawn_encoder( .pix_fmt("yuv420p") .codec_video(&video_encoder.name) .args(["-b:v", &format!("{}M", bitrate_mbps)]) + .args(["-video_track_timescale", time_base.to_string().as_str()]) .overwrite() .output(output_video.to_str().unwrap()); diff --git a/backend/src/ffmpeg/video_info.rs b/backend/src/ffmpeg/video_info.rs index b529314..a32fa7f 100644 --- a/backend/src/ffmpeg/video_info.rs +++ b/backend/src/ffmpeg/video_info.rs @@ -9,6 +9,7 @@ pub struct VideoInfo { pub width: u32, pub height: u32, pub frame_rate: f32, + pub time_base: u32, pub bitrate: u32, pub duration: Duration, pub total_frames: u32, @@ -57,12 +58,22 @@ impl TryFrom for VideoInfo { .ok_or(VideoInfoError::NoDuration)?, ); + let time_base = { + let tbn_string = &stream.time_base; + let mut split = tbn_string.split('/'); + split + .nth(1) + .and_then(|num| num.parse::().ok()) + .ok_or(VideoInfoError::NoTimeScale)? + }; + let total_frames = (frame_rate * duration.as_secs_f32()) as u32; Ok(Self { width, height, frame_rate, + time_base, bitrate, duration, total_frames,