Merge pull request #88 from zaethan/opus_integration
add support for opus files
This commit is contained in:
commit
7cbf27fce0
5 changed files with 69 additions and 9 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -1457,6 +1457,11 @@ dependencies = [
|
|||
"vcpkg 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opus_headers"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.9.0"
|
||||
|
@ -1589,6 +1594,7 @@ dependencies = [
|
|||
"metaflac 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mp3-duration 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mp4ameta 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"opus_headers 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pbkdf2 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -3079,6 +3085,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum openssl 0.10.30 (registry+https://github.com/rust-lang/crates.io-index)" = "8d575eff3665419f9b83678ff2815858ad9d11567e082f5ac1814baba4e2bcb4"
|
||||
"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
|
||||
"checksum openssl-sys 0.9.58 (registry+https://github.com/rust-lang/crates.io-index)" = "a842db4709b604f0fe5d1170ae3565899be2ad3d9cbc72dedc789ac0511f78de"
|
||||
"checksum opus_headers 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "afbb993947f111397c2bc536944f8dac7f54a4e73383d478efe1990b56404b60"
|
||||
"checksum parking_lot 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733"
|
||||
"checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252"
|
||||
"checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b"
|
||||
|
|
|
@ -30,6 +30,7 @@ log = "0.4.5"
|
|||
metaflac = "0.2.3"
|
||||
mp3-duration = "0.1.9"
|
||||
mp4ameta = "0.2.2"
|
||||
opus_headers = "0.1.2"
|
||||
pbkdf2 = "0.4"
|
||||
rand = "0.7"
|
||||
rayon = "1.3"
|
||||
|
|
|
@ -9,6 +9,7 @@ use mp4ameta;
|
|||
use regex::Regex;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use opus_headers;
|
||||
|
||||
use crate::utils;
|
||||
use crate::utils::AudioFormat;
|
||||
|
@ -33,6 +34,7 @@ pub fn read(path: &Path) -> Option<SongTags> {
|
|||
Some(AudioFormat::MP4) => Some(read_mp4(path)),
|
||||
Some(AudioFormat::MPC) => Some(read_ape(path)),
|
||||
Some(AudioFormat::OGG) => Some(read_vorbis(path)),
|
||||
Some(AudioFormat::OPUS) => Some(read_opus(path)),
|
||||
_ => None,
|
||||
};
|
||||
match data {
|
||||
|
@ -160,15 +162,50 @@ fn read_vorbis(path: &Path) -> Result<SongTags> {
|
|||
};
|
||||
|
||||
for (key, value) in source.comment_hdr.comment_list {
|
||||
match key.as_str() {
|
||||
"TITLE" => tags.title = Some(value),
|
||||
"ALBUM" => tags.album = Some(value),
|
||||
"ARTIST" => tags.artist = Some(value),
|
||||
"ALBUMARTIST" => tags.album_artist = Some(value),
|
||||
"TRACKNUMBER" => tags.track_number = value.parse::<u32>().ok(),
|
||||
"DISCNUMBER" => tags.disc_number = value.parse::<u32>().ok(),
|
||||
"DATE" => tags.year = value.parse::<i32>().ok(),
|
||||
_ => (),
|
||||
utils::match_ignore_case! {
|
||||
match key {
|
||||
"TITLE" => tags.title = Some(value),
|
||||
"ALBUM" => tags.album = Some(value),
|
||||
"ARTIST" => tags.artist = Some(value),
|
||||
"ALBUMARTIST" => tags.album_artist = Some(value),
|
||||
"TRACKNUMBER" => tags.track_number = value.parse::<u32>().ok(),
|
||||
"DISCNUMBER" => tags.disc_number = value.parse::<u32>().ok(),
|
||||
"DATE" => tags.year = value.parse::<i32>().ok(),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(tags)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "profile-index", flame)]
|
||||
fn read_opus(path: &Path) -> Result<SongTags> {
|
||||
let headers = opus_headers::parse_from_path(path)?;
|
||||
|
||||
let mut tags = SongTags {
|
||||
artist: None,
|
||||
album_artist: None,
|
||||
album: None,
|
||||
title: None,
|
||||
duration: None,
|
||||
disc_number: None,
|
||||
track_number: None,
|
||||
year: None,
|
||||
};
|
||||
|
||||
for (key, value) in headers.comments.user_comments {
|
||||
utils::match_ignore_case! {
|
||||
match key {
|
||||
"TITLE" => tags.title = Some(value),
|
||||
"ALBUM" => tags.album = Some(value),
|
||||
"ARTIST" => tags.artist = Some(value),
|
||||
"ALBUMARTIST" => tags.album_artist = Some(value),
|
||||
"TRACKNUMBER" => tags.track_number = value.parse::<u32>().ok(),
|
||||
"DISCNUMBER" => tags.disc_number = value.parse::<u32>().ok(),
|
||||
"DATE" => tags.year = value.parse::<i32>().ok(),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -258,4 +295,5 @@ fn test_read_metadata() {
|
|||
assert_eq!(read(Path::new("test/sample.ogg")).unwrap(), sample_tags);
|
||||
assert_eq!(read(Path::new("test/sample.flac")).unwrap(), flac_sample_tag);
|
||||
assert_eq!(read(Path::new("test/sample.m4a")).unwrap(), m4a_sample_tag);
|
||||
assert_eq!(read(Path::new("test/sample.opus")).unwrap(), sample_tags);
|
||||
}
|
||||
|
|
14
src/utils.rs
14
src/utils.rs
|
@ -3,6 +3,18 @@ use app_dirs::{app_root, AppDataType, AppInfo};
|
|||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! match_ignore_case {
|
||||
(match $v:ident {
|
||||
$( $lit:literal => $res:expr, )*
|
||||
_ => $catch_all:expr $(,)?
|
||||
}) => {{
|
||||
$( if $lit.eq_ignore_ascii_case(&$v) { $res } else )*
|
||||
{ $catch_all }
|
||||
}};
|
||||
}
|
||||
pub use crate::match_ignore_case;
|
||||
|
||||
#[cfg(target_family = "windows")]
|
||||
const APP_INFO: AppInfo = AppInfo {
|
||||
name: "Polaris",
|
||||
|
@ -30,6 +42,7 @@ pub enum AudioFormat {
|
|||
MP4,
|
||||
MPC,
|
||||
OGG,
|
||||
OPUS,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "profile-index", flame)]
|
||||
|
@ -48,6 +61,7 @@ pub fn get_audio_format(path: &Path) -> Option<AudioFormat> {
|
|||
"m4a" => Some(AudioFormat::MP4),
|
||||
"mpc" => Some(AudioFormat::MPC),
|
||||
"ogg" => Some(AudioFormat::OGG),
|
||||
"opus" => Some(AudioFormat::OPUS),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
BIN
test/sample.opus
Normal file
BIN
test/sample.opus
Normal file
Binary file not shown.
Loading…
Add table
Reference in a new issue