zvidlib_container/
container.rs1use crate::api::{Capability, Support};
4use crate::audio::AudioTrackTiming;
5use crate::codec::TrackKind;
6use crate::io::ByteSource;
7use crate::media::Container;
8use crate::mp4_demux::{Mp4Demuxer, Mp4DemuxerOptions, Mp4Track, probe_mp4};
9use crate::webm_demux::{WebmDemuxer, WebmDemuxerOptions, probe_webm};
10use crate::{Error, ErrorKind, Limits, Result};
11
12pub async fn probe_container<S: ByteSource + ?Sized>(source: &S) -> Result<Option<Container>> {
17 if probe_webm(source).await? {
18 return Ok(Some(Container::WebM));
19 }
20 if probe_mp4(source).await? {
21 return Ok(Some(Container::Mp4));
22 }
23 Ok(None)
24}
25
26pub fn container_capabilities() -> Vec<Capability> {
31 Container::ALL
32 .iter()
33 .map(|container| Capability {
34 name: container.name().to_owned(),
35 support: Support::Available,
36 transfer_mode: None,
37 })
38 .collect()
39}
40
41#[doc(hidden)]
44pub async fn open_tracks<S: ByteSource + ?Sized>(
45 source: &S,
46 limits: &Limits,
47) -> Result<Vec<Mp4Track>> {
48 if probe_container(source).await? == Some(Container::WebM) {
49 let demuxer = WebmDemuxer::open(
50 source,
51 WebmDemuxerOptions {
52 limits: *limits,
53 ..WebmDemuxerOptions::default()
54 },
55 )
56 .await?;
57 return Ok(demuxer.tracks);
58 }
59 let demuxer = Mp4Demuxer::open(
60 source,
61 Mp4DemuxerOptions {
62 limits: *limits,
63 ..Mp4DemuxerOptions::default()
64 },
65 )
66 .await?;
67 Ok(demuxer.tracks)
68}
69
70#[doc(hidden)]
74pub async fn open_audio_track<S: ByteSource + ?Sized>(
75 source: &S,
76 index: usize,
77 limits: &Limits,
78) -> Result<(Mp4Track, AudioTrackTiming)> {
79 let no_track = || Error::new(ErrorKind::InvalidInput, "no such audio track");
80 if probe_container(source).await? == Some(Container::WebM) {
81 let demuxer = WebmDemuxer::open(
82 source,
83 WebmDemuxerOptions {
84 limits: *limits,
85 ..WebmDemuxerOptions::default()
86 },
87 )
88 .await?;
89 let track = demuxer
90 .tracks
91 .iter()
92 .filter(|track| track.kind == TrackKind::Audio)
93 .nth(index)
94 .ok_or_else(no_track)?;
95 let timing = demuxer.audio_timing(track.id)?;
96 return Ok((track.clone(), timing));
97 }
98 let demuxer = Mp4Demuxer::open(
99 source,
100 Mp4DemuxerOptions {
101 limits: *limits,
102 ..Mp4DemuxerOptions::default()
103 },
104 )
105 .await?;
106 let track = demuxer
107 .tracks
108 .into_iter()
109 .filter(|track| track.kind == TrackKind::Audio)
110 .nth(index)
111 .ok_or_else(no_track)?;
112 let timing = track.audio_timing(demuxer.movie_timescale)?;
113 Ok((track, timing))
114}