audio_extraction/
audio_extraction.rs1use std::process;
22
23use ff_remux::AudioExtractor;
24
25fn main() {
26 let mut args = std::env::args().skip(1);
27 let mut input = None::<String>;
28 let mut output = None::<String>;
29 let mut stream_index = None::<usize>;
30
31 while let Some(flag) = args.next() {
32 match flag.as_str() {
33 "--input" | "-i" => input = Some(args.next().unwrap_or_default()),
34 "--output" | "-o" => output = Some(args.next().unwrap_or_default()),
35 "--stream" | "-s" => {
36 let raw = args.next().unwrap_or_default();
37 stream_index = Some(raw.parse().unwrap_or_else(|_| {
38 eprintln!("Invalid stream index: {raw}");
39 process::exit(1);
40 }));
41 }
42 other => {
43 eprintln!("Unknown flag: {other}");
44 process::exit(1);
45 }
46 }
47 }
48
49 let input = input.unwrap_or_else(|| {
50 eprintln!("Usage: audio_extraction --input <file> --output <audio> [--stream <index>]");
51 process::exit(1);
52 });
53 let output = output.unwrap_or_else(|| {
54 eprintln!("--output is required");
55 process::exit(1);
56 });
57
58 println!("Input: {input}");
59 println!(
60 "Stream: {}",
61 stream_index.map_or_else(
62 || "first audio stream (default)".to_string(),
63 |i| i.to_string()
64 )
65 );
66 println!("Output: {output}");
67 println!();
68 println!("Extracting audio track (stream-copy, no re-encode)…");
69
70 let mut extractor = AudioExtractor::new(&input, &output);
71 if let Some(idx) = stream_index {
72 extractor = extractor.stream_index(idx);
73 }
74
75 extractor.run().unwrap_or_else(|e| {
76 eprintln!("Error: {e}");
77 process::exit(1);
78 });
79
80 let size = match std::fs::metadata(&output) {
81 Ok(m) => {
82 #[allow(clippy::cast_precision_loss)]
83 let kb = m.len() as f64 / 1024.0;
84 if kb < 1024.0 {
85 format!("{kb:.0} KB")
86 } else {
87 format!("{:.1} MB", kb / 1024.0)
88 }
89 }
90 Err(_) => "(unknown size)".to_string(),
91 };
92
93 println!("Done. {output} {size}");
94}