use anyhow::{Context, Result, anyhow};
use symphonia::core::codecs::CODEC_TYPE_NULL;
use symphonia::core::errors::Error as SymphoniaError;
use symphonia::core::formats::{FormatOptions, FormatReader, Packet, Track};
use symphonia::core::io::{MediaSource, MediaSourceStream, MediaSourceStreamOptions};
use symphonia::core::meta::MetadataOptions;
use symphonia::core::probe::Hint;
pub fn probe_source_and_pick_default_track(
source: Box<dyn MediaSource>,
hint_extension: Option<&str>,
) -> Result<(Box<dyn FormatReader>, Track)> {
let mss_opts = MediaSourceStreamOptions {
buffer_len: 256 * 1024,
};
let mss = MediaSourceStream::new(source, mss_opts);
let mut hint = Hint::new();
if let Some(ext) = hint_extension {
hint.with_extension(ext);
}
let format_opts: FormatOptions = Default::default();
let metadata_opts: MetadataOptions = Default::default();
let probed = symphonia::default::get_probe()
.format(&hint, mss, &format_opts, &metadata_opts)
.map_err(|e| anyhow!(e))
.context("failed to probe media stream")?;
let format = probed.format;
let track = format
.tracks()
.iter()
.find(|t| t.codec_params.codec != CODEC_TYPE_NULL && t.codec_params.sample_rate.is_some())
.cloned()
.ok_or_else(|| anyhow!("no audio track found"))?;
Ok((format, track))
}
pub fn next_packet(format: &mut Box<dyn FormatReader>) -> Result<Option<Packet>> {
match format.next_packet() {
Ok(p) => Ok(Some(p)),
Err(SymphoniaError::IoError(_)) => Ok(None),
Err(e) => Err(anyhow!(e)).context("failed reading packet"),
}
}