From 16bb3c0959db7e30b89de90f697c18cd15059e3c Mon Sep 17 00:00:00 2001 From: Serial <69764315+Serial-ATA@users.noreply.github.com> Date: Sat, 24 Aug 2024 11:33:06 -0400 Subject: [PATCH] EBML: Retain all audio tracks --- lofty/src/ebml/properties.rs | 44 ++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/lofty/src/ebml/properties.rs b/lofty/src/ebml/properties.rs index 98fe2a6e..24e84a0a 100644 --- a/lofty/src/ebml/properties.rs +++ b/lofty/src/ebml/properties.rs @@ -66,7 +66,7 @@ impl EbmlExtension { } } -#[derive(Debug, Clone, PartialEq, Default)] +#[derive(Debug, Clone, PartialEq)] pub struct SegmentInfo { pub(crate) timestamp_scale: u64, pub(crate) muxing_app: String, @@ -96,6 +96,17 @@ impl SegmentInfo { } } +impl Default for SegmentInfo { + fn default() -> Self { + Self { + // https://matroska.org/technical/elements.html + timestamp_scale: 1_000_000, + muxing_app: String::new(), + writing_app: String::new(), + } + } +} + #[derive(Debug, Clone, PartialEq, Default)] pub struct AudioTrackDescriptor { pub(crate) number: u64, @@ -211,7 +222,7 @@ pub struct EbmlProperties { pub(crate) header: EbmlHeaderProperties, pub(crate) extensions: Vec, pub(crate) segment_info: SegmentInfo, - pub(crate) default_audio_track: AudioTrackDescriptor, + pub(crate) audio_tracks: Vec, } impl EbmlProperties { @@ -228,29 +239,44 @@ impl EbmlProperties { &self.extensions } - /// Information from the Matroska `\EBML\Segment\Info` element + /// Information from the `\EBML\Segment\Info` element pub fn segment_info(&self) -> &SegmentInfo { &self.segment_info } + /// All audio tracks in the file + /// + /// This includes all audio tracks in the Matroska `\EBML\Segment\Tracks` element. + /// + /// NOTE: The first audio track is **always** the default audio track. + pub fn audio_tracks(&self) -> &[AudioTrackDescriptor] { + &self.audio_tracks + } + /// Information about the default audio track /// /// The information is extracted from the first audio track with its default flag set - /// in the Matroska `\EBML\Segment\Tracks` element. - pub fn default_audio_track(&self) -> &AudioTrackDescriptor { - &self.default_audio_track + /// in the `\EBML\Segment\Tracks` element. + /// + /// NOTE: This will always return `Some` unless [`ParseOptions::read_properties`](crate::config::ParseOptions::read_properties) is set to `false`. + pub fn default_audio_track(&self) -> Option<&AudioTrackDescriptor> { + self.audio_tracks.first() } } impl From for FileProperties { fn from(input: EbmlProperties) -> Self { + let Some(default_audio_track) = input.default_audio_track() else { + return FileProperties::default(); + }; + Self { duration: todo!("Support duration"), overall_bitrate: todo!("Support bitrate"), audio_bitrate: todo!("Support bitrate"), - sample_rate: Some(input.default_audio_track.settings.sampling_frequency), - bit_depth: input.default_audio_track.settings.bit_depth, - channels: Some(input.default_audio_track.settings.channels), + sample_rate: Some(default_audio_track.settings.sampling_frequency), + bit_depth: default_audio_track.settings.bit_depth, + channels: Some(default_audio_track.settings.channels), channel_mask: todo!("Channel mask"), } }