ace_player/decoder/
audio.rs1use anyhow::Result;
3use tokio::sync::mpsc::Sender;
4
5pub type AudioFrame = Vec<f32>;
6
7pub async fn decode_stream(source: String, tx: Sender<AudioFrame>) -> Result<()> {
9 use symphonia::core::audio::SampleBuffer;
10 use symphonia::core::codecs::DecoderOptions;
11 use symphonia::core::formats::FormatOptions;
12 use symphonia::core::io::MediaSourceStream;
13 use symphonia::core::meta::MetadataOptions;
14 use symphonia::core::probe::Hint;
15
16 let path = std::path::Path::new(&source);
17 let file = std::fs::File::open(path)?;
18 let mss = MediaSourceStream::new(Box::new(file), Default::default());
19
20 let hint = Hint::new();
21 let probed = symphonia::default::get_probe().format(
22 &hint,
23 mss,
24 &FormatOptions::default(),
25 &MetadataOptions::default(),
26 )?;
27
28 let mut format = probed.format;
29 let track = format
30 .tracks()
31 .iter()
32 .find(|t| t.codec_params.codec != symphonia::core::codecs::CODEC_TYPE_NULL)
33 .ok_or_else(|| anyhow::anyhow!("No audio track found"))?;
34
35 let mut decoder = symphonia::default::get_codecs()
36 .make(&track.codec_params, &DecoderOptions::default())?;
37
38 let track_id = track.id;
39
40 loop {
41 let packet = match format.next_packet() {
42 Ok(p) => p,
43 Err(_) => break,
44 };
45
46 if packet.track_id() != track_id {
47 continue;
48 }
49
50 let decoded = decoder.decode(&packet)?;
51 let spec = *decoded.spec();
52 let mut buf = SampleBuffer::<f32>::new(decoded.capacity() as u64, spec);
53 buf.copy_interleaved_ref(decoded);
54
55 if tx.send(buf.samples().to_vec()).await.is_err() {
56 break;
57 }
58 }
59
60 Ok(())
61}