diff --git a/.idea/dictionaries/bt.xml b/.idea/dictionaries/bt.xml
index beefee1473..be0599beae 100644
--- a/.idea/dictionaries/bt.xml
+++ b/.idea/dictionaries/bt.xml
@@ -7,6 +7,7 @@
cheermote
crockford
fakeyou
+ ffprobe
hifigan
scrollback
softvc
diff --git a/crates/lib/media/src/decode_basic_audio_info.rs b/crates/lib/media/src/decode_basic_audio_info.rs
index 2135efd6af..7549d8147b 100644
--- a/crates/lib/media/src/decode_basic_audio_info.rs
+++ b/crates/lib/media/src/decode_basic_audio_info.rs
@@ -1,13 +1,19 @@
use errors::AnyhowResult;
use std::io::Cursor;
-use symphonia::core::formats::FormatOptions;
+use symphonia::core::audio::SampleBuffer;
+use symphonia::core::formats::{FormatOptions, FormatReader};
use symphonia::core::io::{MediaSourceStream, ReadOnlySource};
use symphonia::core::meta::MetadataOptions;
use symphonia::core::probe::Hint;
+// Returned if nothing could be decoded
+const NO_AUDIO_INFO : BasicAudioInfo = BasicAudioInfo { duration_millis: None, codec_name: None, required_full_decode: false };
+
+#[derive(Clone)]
pub struct BasicAudioInfo {
pub duration_millis: Option,
pub codec_name: Option,
+ pub required_full_decode: bool,
}
pub fn decode_basic_audio_info(
@@ -38,18 +44,19 @@ pub fn decode_basic_audio_info(
let probed = symphonia::default::get_probe()
.format(&hint, mss, &fmt_opts, &meta_opts)?;
- let format = probed.format;
+ let mut format = probed.format;
- let maybe_track_duration = format.default_track()
- .map(|track| {
- track.codec_params.time_base
- .zip(track.codec_params.n_frames)
- .map(|(time_base, n_frames)| {
- // NB: This yields the duration of the track
- time_base.calc_time(n_frames)
- })
+ let default_track = match format.default_track() {
+ None => return Ok(NO_AUDIO_INFO.clone()),
+ Some(default_track) => default_track,
+ };
+
+ let mut maybe_track_duration = default_track.codec_params.time_base
+ .zip(default_track.codec_params.n_frames)
+ .map(|(time_base, n_frames)| {
+ // NB: This yields the duration of the track
+ time_base.calc_time(n_frames)
})
- .flatten()
.map(|time| {
let duration_millis = time.seconds * 1000;
let frac_millis = (time.frac * 1000.0).trunc() as u64;
@@ -58,18 +65,110 @@ pub fn decode_basic_audio_info(
let codec_registry = symphonia::default::get_codecs();
- let maybe_codec_name = format.default_track()
- .map(|track| track.codec_params.codec)
- .map(|codec_type| codec_registry.get_codec(codec_type))
- .flatten()
+ let maybe_codec_name = codec_registry.get_codec(default_track.codec_params.codec)
.map(|codec_descriptor| codec_descriptor.short_name.to_string());
+ let mut required_full_decode = false;
+
+ if maybe_track_duration.is_none() {
+ // NB: The number of samples could not be determined, so we need to decode the file.
+ // See https://github.com/pdeljanov/Symphonia/issues/18#issuecomment-770157948
+
+ maybe_track_duration = read_duration(&mut format)?;
+ required_full_decode = true;
+ }
+
Ok(BasicAudioInfo {
duration_millis: maybe_track_duration,
codec_name: maybe_codec_name,
+ required_full_decode,
})
}
+fn read_duration(format: &mut Box) -> AnyhowResult