use crate::api::{Capability, Support};
use crate::audio::AudioTrackTiming;
use crate::codec::TrackKind;
use crate::io::ByteSource;
use crate::media::Container;
use crate::mp4_demux::{Mp4Demuxer, Mp4DemuxerOptions, Mp4Track, probe_mp4};
use crate::webm_demux::{WebmDemuxer, WebmDemuxerOptions, probe_webm};
use crate::{Error, ErrorKind, Limits, Result};
pub async fn probe_container<S: ByteSource + ?Sized>(source: &S) -> Result<Option<Container>> {
if probe_webm(source).await? {
return Ok(Some(Container::WebM));
}
if probe_mp4(source).await? {
return Ok(Some(Container::Mp4));
}
Ok(None)
}
pub fn container_capabilities() -> Vec<Capability> {
Container::ALL
.iter()
.map(|container| Capability {
name: container.name().to_owned(),
support: Support::Available,
transfer_mode: None,
})
.collect()
}
#[doc(hidden)]
pub async fn open_tracks<S: ByteSource + ?Sized>(
source: &S,
limits: &Limits,
) -> Result<Vec<Mp4Track>> {
if probe_container(source).await? == Some(Container::WebM) {
let demuxer = WebmDemuxer::open(
source,
WebmDemuxerOptions {
limits: *limits,
..WebmDemuxerOptions::default()
},
)
.await?;
return Ok(demuxer.tracks);
}
let demuxer = Mp4Demuxer::open(
source,
Mp4DemuxerOptions {
limits: *limits,
..Mp4DemuxerOptions::default()
},
)
.await?;
Ok(demuxer.tracks)
}
#[doc(hidden)]
pub async fn open_audio_track<S: ByteSource + ?Sized>(
source: &S,
index: usize,
limits: &Limits,
) -> Result<(Mp4Track, AudioTrackTiming)> {
let no_track = || Error::new(ErrorKind::InvalidInput, "no such audio track");
if probe_container(source).await? == Some(Container::WebM) {
let demuxer = WebmDemuxer::open(
source,
WebmDemuxerOptions {
limits: *limits,
..WebmDemuxerOptions::default()
},
)
.await?;
let track = demuxer
.tracks
.iter()
.filter(|track| track.kind == TrackKind::Audio)
.nth(index)
.ok_or_else(no_track)?;
let timing = demuxer.audio_timing(track.id)?;
return Ok((track.clone(), timing));
}
let demuxer = Mp4Demuxer::open(
source,
Mp4DemuxerOptions {
limits: *limits,
..Mp4DemuxerOptions::default()
},
)
.await?;
let track = demuxer
.tracks
.into_iter()
.filter(|track| track.kind == TrackKind::Audio)
.nth(index)
.ok_or_else(no_track)?;
let timing = track.audio_timing(demuxer.movie_timescale)?;
Ok((track, timing))
}