Skip to main content

decode_stream/
decode_stream.rs

1use std::env;
2use std::fs;
3use std::io;
4use std::path::Path;
5
6use xaac_rs::{DecodeStatus, Decoder, DecoderConfig};
7
8fn main() -> Result<(), Box<dyn std::error::Error>> {
9    let input = env::args().nth(1).ok_or_else(usage)?;
10    let path = Path::new(&input);
11    let data = fs::read(path)?;
12
13    let mut decoder = Decoder::new(DecoderConfig::default())?;
14    let mut frame_count = 0usize;
15    let mut pcm_bytes = 0usize;
16    let mut offset = 0usize;
17
18    while offset < data.len() {
19        let end = (offset + 256).min(data.len());
20        match decoder.decode_stream_chunk(&data[offset..end])? {
21            DecodeStatus::Frame(frame) => {
22                frame_count += 1;
23                pcm_bytes += frame.pcm.len();
24                println!(
25                    "frame {}: {} pcm bytes, {} Hz, {} ch",
26                    frame_count,
27                    frame.pcm.len(),
28                    frame.stream_info.sample_rate,
29                    frame.stream_info.channels
30                );
31            }
32            DecodeStatus::NeedMoreInput(progress) => {
33                if let Some(info) = progress.stream_info {
34                    println!(
35                        "need more input: initialized={}, {} Hz, {} ch",
36                        progress.initialized, info.sample_rate, info.channels
37                    );
38                } else {
39                    println!("need more input: initialized={}", progress.initialized);
40                }
41            }
42            DecodeStatus::EndOfStream => break,
43        }
44        offset = end;
45    }
46
47    loop {
48        match decoder.finish()? {
49            DecodeStatus::Frame(frame) => {
50                frame_count += 1;
51                pcm_bytes += frame.pcm.len();
52                println!(
53                    "flush frame {}: {} pcm bytes, {} Hz, {} ch",
54                    frame_count,
55                    frame.pcm.len(),
56                    frame.stream_info.sample_rate,
57                    frame.stream_info.channels
58                );
59            }
60            DecodeStatus::NeedMoreInput(_) => continue,
61            DecodeStatus::EndOfStream => break,
62        }
63    }
64
65    println!("decoded frames: {}", frame_count);
66    println!("decoded pcm bytes: {}", pcm_bytes);
67    Ok(())
68}
69
70fn usage() -> Box<dyn std::error::Error> {
71    Box::new(io::Error::new(
72        io::ErrorKind::InvalidInput,
73        "usage: cargo run --example decode_stream -- <input.aac>",
74    ))
75}