use std::time::Duration;
use ff_decode::SceneDetector;
fn hard_cut_video_path() -> std::path::PathBuf {
let manifest_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
manifest_dir
.join("../..")
.join("assets/test/hard_cut_video.mp4")
}
#[test]
fn scene_detector_should_detect_known_cuts_within_one_frame_tolerance() {
let video_path = hard_cut_video_path();
if !video_path.exists() {
println!(
"Skipping: reference asset not found at {} \
(run `cargo run --manifest-path tools/Cargo.toml` to regenerate)",
video_path.display()
);
return;
}
let timestamps = match SceneDetector::new(&video_path).threshold(0.4).run() {
Ok(ts) => ts,
Err(e) => {
println!("Skipping: SceneDetector::run failed: {e}");
return;
}
};
assert_eq!(
timestamps.len(),
5,
"expected exactly 5 scene-change timestamps, got {}: {timestamps:?}",
timestamps.len()
);
let expected = [
Duration::from_secs(1),
Duration::from_secs(2),
Duration::from_secs(3),
Duration::from_secs(4),
Duration::from_secs(5),
];
let tolerance = Duration::from_millis(34);
for (i, (detected, &expected_ts)) in timestamps.iter().zip(expected.iter()).enumerate() {
let diff = if *detected >= expected_ts {
*detected - expected_ts
} else {
expected_ts - *detected
};
assert!(
diff <= tolerance,
"cut #{i}: expected ≈{expected_ts:?} (±{tolerance:?}), got {detected:?} \
(diff={diff:?})"
);
}
}