use std::collections::VecDeque;
use std::time::Duration;
use super::DelayTrim;
use super::audio::{AudioBuffer, AudioDecoder};
use crate::Result;
use crate::demux::{Packet, StreamInfo};
pub struct Mp3AudioDecoder {
inner: rusty_mp3::Mp3Decoder,
trim: DelayTrim,
out: VecDeque<AudioBuffer>,
}
impl Mp3AudioDecoder {
pub fn new(stream: &StreamInfo) -> Result<Self> {
Ok(Self {
inner: rusty_mp3::Mp3Decoder::new(),
trim: DelayTrim::new(stream.codec_delay).with_end(stream.end_trim),
out: VecDeque::new(),
})
}
}
impl AudioDecoder for Mp3AudioDecoder {
fn send_packet(&mut self, packet: &Packet) -> Result<()> {
self.trim.on_packet(packet.pts);
self.inner.push(&packet.data);
let mut pts = packet.pts;
while let Ok(frame) = self.inner.next_frame() {
let frames = frame.samples.len() / frame.channels.max(1) as usize;
let next = pts + Duration::from_secs_f64(frames as f64 / frame.sample_rate.max(1) as f64);
if let Some(b) = self.trim.apply(frame.samples, frame.channels, frame.sample_rate, pts) {
self.out.push_back(b);
}
pts = next;
}
Ok(())
}
fn receive_samples(&mut self) -> Result<Option<AudioBuffer>> {
Ok(self.out.pop_front())
}
fn flush(&mut self) {
self.inner = rusty_mp3::Mp3Decoder::new();
self.out.clear();
self.trim.reset();
}
}