Skip to content

Commit

Permalink
support duration extraction from WAV files
Browse files Browse the repository at this point in the history
  • Loading branch information
jhspetersson committed Jan 10, 2024
1 parent 6fb0fb5 commit ba2e3ad
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 1 deletion.
25 changes: 25 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ toml = "0.8"
tree_magic_mini = { version = "3.0", features = [ "tree_magic_db" ] }
update-informer = { version = "1.1.0", optional = true }
wana_kana = "3.0"
wavers = "1.1"
zip = "0.6"

[target.'cfg(unix)'.dependencies]
Expand Down
Binary file added resources/test/audio/silent.wav
Binary file not shown.
5 changes: 4 additions & 1 deletion src/util/duration/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::io;
mod mkv;
mod mp3;
mod mp4;
mod wav;

use std::path::Path;

Expand All @@ -11,6 +12,7 @@ use mp3_metadata::MP3Metadata;
use mkv::MkvDurationExtractor;
use mp3::Mp3DurationExtractor;
use mp4::Mp4DurationExtractor;
use wav::WavDurationExtractor;

#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Duration {
Expand All @@ -22,10 +24,11 @@ pub trait DurationExtractor {
fn try_read_duration(&self, path: &Path, mp3_metadata: &Option<MP3Metadata>) -> io::Result<Option<Duration>>;
}

const EXTRACTORS: [&dyn DurationExtractor; 3] = [
const EXTRACTORS: [&dyn DurationExtractor; 4] = [
&Mp3DurationExtractor,
&Mp4DurationExtractor,
&MkvDurationExtractor,
&WavDurationExtractor,
];

pub fn get_duration<T: AsRef<Path>>(path: T, mp3_metadata: &Option<MP3Metadata>) -> Option<Duration> {
Expand Down
47 changes: 47 additions & 0 deletions src/util/duration/wav.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use std::io;
use std::path::Path;

use mp3_metadata::MP3Metadata;

use wavers::Wav;

use crate::util::duration::DurationExtractor;
use crate::util::Duration;

pub struct WavDurationExtractor;

impl DurationExtractor for WavDurationExtractor {
fn supports_ext(&self, ext_lowercase: &str) -> bool {
"wav" == ext_lowercase
}

fn try_read_duration(
&self,
path: &Path,
_: &Option<MP3Metadata>,
) -> io::Result<Option<Duration>> {
let wav: Wav<i16> = Wav::from_path(path).map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
Ok(Some(Duration { length: wav.duration() as usize }))
}
}

#[cfg(test)]
mod test {
use super::*;
use crate::util::duration::DurationExtractor;
use crate::util::Duration;
use std::error::Error;
use std::path::PathBuf;

#[test]
fn test_success() -> Result<(), Box<dyn Error>> {
let path_string =
std::env::var("CARGO_MANIFEST_DIR")? + "/resources/test/" + "audio/silent.wav";
let path = PathBuf::from(path_string);
assert_eq!(
WavDurationExtractor.try_read_duration(&path, &None)?,
Some(Duration { length: 15 }),
);
Ok(())
}
}

0 comments on commit ba2e3ad

Please sign in to comment.