black_frames/
black_frames.rs1use std::process;
16use std::time::Duration;
17
18use ff_analysis::BlackFrameDetector;
19
20fn fmt_duration(d: Duration) -> String {
21 let h = d.as_secs() / 3600;
22 let m = (d.as_secs() % 3600) / 60;
23 let s = d.as_secs() % 60;
24 let ms = d.subsec_millis();
25 format!("{h:02}:{m:02}:{s:02}.{ms:03}")
26}
27
28fn main() {
29 let mut args = std::env::args().skip(1);
30 let mut input = None::<String>;
31 let mut threshold = 0.1_f64;
32
33 while let Some(flag) = args.next() {
34 match flag.as_str() {
35 "--input" | "-i" => input = Some(args.next().unwrap_or_default()),
36 "--threshold" | "-t" => {
37 let raw = args.next().unwrap_or_default();
38 threshold = raw.parse().unwrap_or_else(|_| {
39 eprintln!("Invalid threshold: {raw}");
40 process::exit(1);
41 });
42 }
43 other => {
44 eprintln!("Unknown flag: {other}");
45 process::exit(1);
46 }
47 }
48 }
49
50 let input = input.unwrap_or_else(|| {
51 eprintln!("Usage: black_frames --input <video> [--threshold <0.0–1.0>]");
52 process::exit(1);
53 });
54
55 println!("Detecting black frames in: {input}");
56 println!("Threshold: {threshold:.2}");
57 println!();
58
59 let black_starts = BlackFrameDetector::new(&input)
60 .threshold(threshold)
61 .run()
62 .unwrap_or_else(|e| {
63 eprintln!("Error: {e}");
64 process::exit(1);
65 });
66
67 if black_starts.is_empty() {
68 println!("No black intervals detected.");
69 } else {
70 println!("Detected {} black interval(s):", black_starts.len());
71 for (i, ts) in black_starts.iter().enumerate() {
72 println!(" [{i:3}] {}", fmt_duration(*ts));
73 }
74 }
75}