use std::io::{Read, Seek};
use self::read_seek_source::ReadSeekSource;
use ::symphonia::core::io::{MediaSource, MediaSourceStream};
use super::*;
#[derive(Clone, Debug)]
pub struct Settings {
pub(crate) byte_len: Option<u64>,
pub(crate) coarse_seek: bool,
pub(crate) gapless: bool,
pub(crate) hint: Option<String>,
pub(crate) mime_type: Option<String>,
pub(crate) is_seekable: bool,
}
impl Default for Settings {
fn default() -> Self {
Self {
byte_len: None,
coarse_seek: false,
gapless: true,
hint: None,
mime_type: None,
is_seekable: false,
}
}
}
#[derive(Clone, Debug)]
pub struct DecoderBuilder<R> {
data: Option<R>,
settings: Settings,
}
impl<R> Default for DecoderBuilder<R> {
fn default() -> Self {
Self {
data: None,
settings: Settings::default(),
}
}
}
impl<R: Read + Seek + Send + Sync + 'static> DecoderBuilder<R> {
pub fn new() -> Self {
Self::default()
}
pub fn with_data(mut self, data: R) -> Self {
self.data = Some(data);
self
}
pub fn with_byte_len(mut self, byte_len: u64) -> Self {
self.settings.byte_len = Some(byte_len);
self.settings.is_seekable = true;
self
}
pub fn with_coarse_seek(mut self, coarse_seek: bool) -> Self {
self.settings.coarse_seek = coarse_seek;
self
}
pub fn with_gapless(mut self, gapless: bool) -> Self {
self.settings.gapless = gapless;
self
}
pub fn with_hint(mut self, hint: &str) -> Self {
self.settings.hint = Some(hint.to_string());
self
}
pub fn with_mime_type(mut self, mime_type: &str) -> Self {
self.settings.mime_type = Some(mime_type.to_string());
self
}
pub fn with_seekable(mut self, is_seekable: bool) -> Self {
self.settings.is_seekable = is_seekable;
self
}
fn build_impl(self) -> Result<(DecoderImpl<R>, Settings), DecoderError> {
let data = self.data.ok_or(DecoderError::UnrecognizedFormat)?;
let mss = MediaSourceStream::new(
Box::new(ReadSeekSource::new(data, &self.settings)) as Box<dyn MediaSource>,
Default::default(),
);
symphonia::SymphoniaDecoder::new(mss, &self.settings)
.map(|decoder| (DecoderImpl::Symphonia(decoder, PhantomData), self.settings))
}
pub fn build(self) -> Result<Decoder<R>, DecoderError> {
let (decoder, _) = self.build_impl()?;
Ok(Decoder(decoder))
}
pub fn build_looped(self) -> Result<LoopedDecoder<R>, DecoderError> {
let (decoder, settings) = self.build_impl()?;
Ok(LoopedDecoder {
inner: Some(decoder),
settings,
})
}
}