From 79ba1914152f5d07cd484e777484aaa058f55fbd Mon Sep 17 00:00:00 2001 From: Ethan Girouard Date: Fri, 10 May 2024 11:28:43 -0400 Subject: [PATCH] Add function to get audio file duration --- src/util/audio.rs | 33 +++++++++++++++++++++++++++++++++ src/util/mod.rs | 7 +++++++ 2 files changed, 40 insertions(+) create mode 100644 src/util/audio.rs diff --git a/src/util/audio.rs b/src/util/audio.rs new file mode 100644 index 0000000..719052f --- /dev/null +++ b/src/util/audio.rs @@ -0,0 +1,33 @@ +use symphonia::core::formats::FormatOptions; +use symphonia::core::io::MediaSourceStream; +use symphonia::core::meta::MetadataOptions; +use symphonia::core::probe::Hint; +use std::fs::File; + +/// Measure the duration (in seconds) of an audio file +pub fn measure_duration(file: File) -> Result> { + let source_stream = MediaSourceStream::new(Box::new(file), Default::default()); + + let hint = Hint::new(); + let format_opts = FormatOptions::default(); + let metadata_opts = MetadataOptions::default(); + + let probe = symphonia::default::get_probe().format(&hint, source_stream, &format_opts, &metadata_opts)?; + let reader = probe.format; + + if reader.tracks().len() != 1 { + return Err(format!("Expected 1 track, found {}", reader.tracks().len()).into()) + } + + let track = &reader.tracks()[0]; + + let time_base = track.codec_params.time_base.ok_or("Missing time base")?; + let duration = track.codec_params.n_frames + .map(|frames| track.codec_params.start_ts + frames) + .ok_or("Missing number of frames")?; + + duration + .checked_mul(time_base.numer as u64) + .and_then(|v| v.checked_div(time_base.denom as u64)) + .ok_or("Overflow while computing duration".into()) +} diff --git a/src/util/mod.rs b/src/util/mod.rs index e69de29..cf7196e 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -0,0 +1,7 @@ +use cfg_if::cfg_if; + +cfg_if! { + if #[cfg(feature = "ssr")] { + pub mod audio; + } +}