mirror of
https://codeberg.org/unspeaker/perch.git
synced 2025-12-06 17:46:42 +01:00
load metadata using lofty (shout out @Frieder_Hannenheim - you are #1)
This commit is contained in:
parent
28f9220e6c
commit
bc067e2739
4 changed files with 92 additions and 53 deletions
74
src/model.rs
74
src/model.rs
|
|
@ -1,6 +1,11 @@
|
|||
use crate::*;
|
||||
use walkdir::DirEntry;
|
||||
use id3::{Tag, TagLike};
|
||||
use std::fs::File;
|
||||
use std::io::{BufReader, Read};
|
||||
use lofty::{
|
||||
file::TaggedFileExt,
|
||||
probe::Probe,
|
||||
tag::Accessor,
|
||||
};
|
||||
|
||||
pub struct Taggart {
|
||||
pub _root: PathBuf,
|
||||
|
|
@ -36,7 +41,7 @@ pub enum EntryInfo {
|
|||
track: Option<u32>,
|
||||
title: Option<Arc<str>>,
|
||||
date: Option<Arc<str>>,
|
||||
year: Option<i32>,
|
||||
year: Option<u32>,
|
||||
people: Option<Vec<Arc<str>>>,
|
||||
publisher: Option<Arc<str>>,
|
||||
key: Option<Arc<str>>,
|
||||
|
|
@ -104,7 +109,7 @@ impl Entry {
|
|||
Ok(None)
|
||||
}
|
||||
}
|
||||
fn new_dir (root: &impl AsRef<Path>, path: &Path, depth: usize) -> Perhaps<Self> {
|
||||
fn new_dir (_: &impl AsRef<Path>, path: &Path, depth: usize) -> Perhaps<Self> {
|
||||
Ok(Some(Self {
|
||||
depth,
|
||||
path: path.into(),
|
||||
|
|
@ -116,11 +121,11 @@ impl Entry {
|
|||
},
|
||||
}))
|
||||
}
|
||||
fn new_file (root: &impl AsRef<Path>, path: &Path, depth: usize) -> Perhaps<Self> {
|
||||
fn new_file (_: &impl AsRef<Path>, path: &Path, depth: usize) -> Perhaps<Self> {
|
||||
Ok(Some(Self {
|
||||
depth,
|
||||
info: EntryInfo::new(path)?,
|
||||
path: path.into(),
|
||||
info: EntryInfo::new(&read(path)?)?
|
||||
}))
|
||||
}
|
||||
pub fn is_dir (&self) -> bool {
|
||||
|
|
@ -165,19 +170,23 @@ impl Entry {
|
|||
}
|
||||
}
|
||||
impl EntryInfo {
|
||||
pub fn new (bytes: &[u8]) -> Usually<Self> {
|
||||
// MP3 with ID3v2
|
||||
if bytes.starts_with(&[b'I', b'D', b'3']) {
|
||||
#[allow(deprecated)]
|
||||
let id3 = Tag::read_from(bytes)?;
|
||||
return Ok(Self::Music {
|
||||
hash: hex::encode(xxh3_64(&bytes).to_be_bytes()).into(),
|
||||
pub fn new (path: &Path) -> Usually<Self> {
|
||||
let reader = BufReader::new(File::open(path)?);
|
||||
let probe = Probe::new(reader)
|
||||
//.options(ParseOptions::new().parsing_mode(ParsingMode::Strict))
|
||||
.guess_file_type()?;
|
||||
if probe.file_type().is_some() {
|
||||
let file = lofty::read_from_path(path)?;
|
||||
let tag = file.primary_tag();
|
||||
let hash = hex::encode(xxh3_64(std::fs::read(path)?.as_slice()).to_be_bytes()).into();
|
||||
Ok(Self::Music {
|
||||
hash,
|
||||
file_type: None,
|
||||
artist: id3.artist().map(|x|x.into()),
|
||||
album: id3.album().map(|x|x.into()),
|
||||
track: id3.track().map(|x|x.into()),
|
||||
title: id3.title().map(|x|x.into()),
|
||||
year: id3.year().map(|x|x.into()),
|
||||
artist: tag.map(|t|t.artist().map(|t|t.into())).flatten(),
|
||||
album: tag.map(|t|t.album().map(|t|t.into())).flatten(),
|
||||
track: tag.map(|t|t.track().map(|t|t.into())).flatten(),
|
||||
title: tag.map(|t|t.title().map(|t|t.into())).flatten(),
|
||||
year: tag.map(|t|t.year().map(|t|t.into())).flatten(),
|
||||
date: None,
|
||||
people: None,
|
||||
publisher: None,
|
||||
|
|
@ -185,29 +194,18 @@ impl EntryInfo {
|
|||
bpm: None,
|
||||
invalid: false,
|
||||
})
|
||||
} else {
|
||||
Self::new_fallback(path)
|
||||
}
|
||||
// Ogg (Opus)
|
||||
if bytes.starts_with(&[b'O', b'g', b'g', b'S']) {
|
||||
let headers = opus_headers::parse_from_read(bytes)?;
|
||||
println!("{headers:?}");
|
||||
return Ok(Self::Music {
|
||||
hash: hex::encode(xxh3_64(&bytes).to_be_bytes()).into(),
|
||||
file_type: None,
|
||||
artist: None,
|
||||
album: None,
|
||||
track: None,
|
||||
title: None,
|
||||
date: None,
|
||||
year: None,
|
||||
people: None,
|
||||
publisher: None,
|
||||
key: None,
|
||||
bpm: None,
|
||||
invalid: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
pub fn new_fallback (path: &Path) -> Usually<Self> {
|
||||
let mut reader = BufReader::new(File::open(path)?);
|
||||
let mut bytes = vec![0;16];
|
||||
reader.read(&mut bytes)?;
|
||||
// PNG
|
||||
if bytes.starts_with(&[0x89, b'P', b'N', b'G', 0x0D, 0x0A, 0x1A, 0x0A]) {
|
||||
let mut bytes = vec![];
|
||||
BufReader::new(File::open(path)?).read(&mut bytes)?;
|
||||
return Ok(Self::Image {
|
||||
file_type: None,
|
||||
hash: hex::encode(xxh3_64(&bytes).to_be_bytes()).into(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue