support duration extraction from WAV files

This commit is contained in:
jhspetersson 2024-01-10 17:37:28 +01:00
parent 6fb0fb592f
commit ba2e3ada20
5 changed files with 77 additions and 1 deletions

25
Cargo.lock generated
View File

@ -145,6 +145,12 @@ version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205"
[[package]]
name = "bytemuck"
version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6"
[[package]]
name = "byteorder"
version = "1.5.0"
@ -509,6 +515,7 @@ dependencies = [
"update-informer",
"uzers",
"wana_kana",
"wavers",
"xattr",
"zip",
]
@ -1094,6 +1101,12 @@ dependencies = [
"subtle",
]
[[package]]
name = "paste"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
[[package]]
name = "pbkdf2"
version = "0.11.0"
@ -2059,6 +2072,18 @@ version = "0.2.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f"
[[package]]
name = "wavers"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93a97475d1432afab6f3e845a7934f6de1bd39d495aedc93dafb54e62f57be2c"
dependencies = [
"bytemuck",
"num-traits",
"paste",
"thiserror",
]
[[package]]
name = "web-sys"
version = "0.3.66"

View File

@ -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]

Binary file not shown.

View File

@ -3,6 +3,7 @@ use std::io;
mod mkv;
mod mp3;
mod mp4;
mod wav;
use std::path::Path;
@ -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 {
@ -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> {

47
src/util/duration/wav.rs Normal file
View File

@ -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(())
}
}