Skip to main content

AudioExtractor

Struct AudioExtractor 

Source
pub struct AudioExtractor { /* private fields */ }
Expand description

Demux an audio track from a media file and write it to a standalone audio file.

The audio bitstream is stream-copied (no decode/encode cycle). By default the first audio stream is selected; call stream_index to pick a specific one.

Returns RemuxError::OperationFailed when:

  • no audio stream is found (or stream_index points to a non-audio stream), or
  • the audio codec is incompatible with the output container.

§Example

use ff_remux::AudioExtractor;

AudioExtractor::new("source.mp4", "audio.mp3").run()?;

Implementations§

Source§

impl AudioExtractor

Source

pub fn new(input: impl Into<PathBuf>, output: impl Into<PathBuf>) -> Self

Create a new AudioExtractor.

  • input — source media file.
  • output — destination audio file (format auto-detected from extension).
Examples found in repository?
examples/audio_extraction.rs (line 70)
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}
Source

pub fn stream_index(self, idx: usize) -> Self

Select a specific audio stream by index (0-based over all streams in the container). Defaults to the first audio stream when not set.

Examples found in repository?
examples/audio_extraction.rs (line 72)
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}
Source

pub fn run(self) -> Result<(), RemuxError>

Execute the audio extraction operation.

§Errors
Examples found in repository?
examples/audio_extraction.rs (line 75)
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}

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.