use std::{
fs,
io::{Read, Seek},
path::Path,
};
use symphonia::core::{
formats::{FormatOptions, TrackType, probe::Hint},
io::MediaSourceStream,
meta::{MetadataOptions, MetadataRevision},
};
use crate::{
errors::ContainerError,
media_container::{ContainerFormat, MediaContainer, Stream},
};
pub mod raw_decoder;
pub struct ContainerExtractResult {
pub container: MediaContainer,
pub metadata: Option<MetadataRevision>,
}
pub fn extract_from_file(path: impl AsRef<Path>) -> Result<ContainerExtractResult, ContainerError> {
let path = path.as_ref();
let mut file = fs::File::open(path)?;
let mut buf = [0_u8; 16];
file.read_exact(&mut buf)?;
file.seek(std::io::SeekFrom::Start(0))?;
let container_format = ContainerFormat::from_buf(&buf)
.ok_or_else(|| ContainerError::InvalidSource(path.to_path_buf()))?;
let mss = MediaSourceStream::new(Box::new(file), Default::default());
let fmt_opts = FormatOptions::default();
let metadata_opts = MetadataOptions::default();
let mut probe =
symphonia::default::get_probe().probe(&Hint::new(), mss, fmt_opts, metadata_opts)?;
let track = probe.default_track(TrackType::Audio).unwrap();
let stream = Stream::try_from(track)?;
let container = MediaContainer {
path: path.to_path_buf(),
format: container_format,
stream,
};
Ok(ContainerExtractResult {
container,
metadata: probe.metadata().pop(),
})
}