Skip to content

Commit

Permalink
TRACK add artwork fallback searches
Browse files Browse the repository at this point in the history
LIBRARY also read art on first track after append

AAAaaa
  • Loading branch information
Beinsezii committed Aug 6, 2024
1 parent fe3798e commit 93f8aa3
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 17 deletions.
21 changes: 14 additions & 7 deletions src/library/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,17 @@ impl Library {
}
}

fn read_art(&self) {
let now = Instant::now();
if let Ok(mut art) = self.art.write() {
*art = self.player.track_get().map(|t| t.read_art()).flatten().map(|v| Arc::new(v));
}
if let Ok(mut thumbnail) = self.thumbnail.write() {
*thumbnail = None;
}
bench!("Loaded artwork in {:?}", now.elapsed());
}

/// Receiver for all library events
pub fn get_receiver(&self) -> Result<BusReader<LibEvt>, Box<dyn Error>> {
Ok(self.bus.lock().map_err(|e| e.to_string())?.add_rx())
Expand Down Expand Up @@ -307,17 +318,12 @@ impl Library {
return;
}
}
if let Some(track) = self.player.play_track(track.clone()) {
if let Some(track) = self.player.play_track(track) {
if let Ok(mut history) = self.history.lock() {
history.push(track)
}
}
if let Ok(mut art) = self.art.write() {
*art = track.map(|t| t.read_art()).flatten().map(|v| Arc::new(v));
}
if let Ok(mut thumbnail) = self.thumbnail.write() {
*thumbnail = None;
}
self.read_art();
self.broadcast(LibEvt::Playback);
}

Expand Down Expand Up @@ -616,6 +622,7 @@ impl Library {
} else {
self.get_sequential(false)
});
self.read_art();
}

bench!("Finished appending {} tracks in total {:?}", count, begin.elapsed())
Expand Down
71 changes: 61 additions & 10 deletions src/library/track/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use crate::logging::*;
use std::collections::HashMap;
use std::fs::File;
use std::io::Cursor;
use std::ops::Deref;
use std::path::Path;
use std::path::PathBuf;
Expand Down Expand Up @@ -378,6 +379,9 @@ pub struct Track {
}

impl Track {
pub const ART_SEARCH_TAGS: &'static [&'static str] = &["title", "grouping", "album", "artist"];
pub const ART_SEARCH_EXTS: &'static [&'static str] = &["jpg", "png", "jpeg"];

pub fn new<T: AsRef<Path>>(path: T) -> Option<Self> {
path.as_ref().canonicalize().ok().map(|path| Self {
path,
Expand Down Expand Up @@ -414,6 +418,40 @@ impl Track {
// }}}
}

#[cfg(feature = "album-art")]
fn find_art(&self) -> Option<image::DynamicImage> {
let Some(Ok(directory)) = self.path.parent().map(|p| p.read_dir()) else {
return None;
};

let tags: Vec<&String> = Self::ART_SEARCH_TAGS.iter().filter_map(|s| self.tags.get(&s.to_string())).collect();
for entry in directory {
let Ok(item) = entry else { continue };
let path = item.path();
let Some(ext) = path.extension().map(|e| e.to_str()).flatten() else {
continue;
};
if !Self::ART_SEARCH_EXTS.contains(&ext.to_ascii_lowercase().as_str()) {
continue;
}
let Some(stem) = path.file_stem().map(|e| e.to_str()).flatten().map(|s| s.to_lowercase()) else {
continue;
};
if tags
.iter()
.all(|t| t.to_lowercase() != stem && (t.to_string() + " cover").to_lowercase() != stem)
&& stem.to_ascii_lowercase() != "cover"
{
continue;
}

if let Ok(img) = image::open(item.path()) {
return Some(img);
}
}
None
}

/// Reads metadata into the struct. This doesn't happen on ::new() for performance reasons.
pub fn load_meta(&mut self) {
// {{{
Expand Down Expand Up @@ -476,14 +514,29 @@ impl Track {

pub fn read_art(&self) -> Option<Box<[Box<[[u8; 4]]>]>> {
// {{{
let meta = self.read_metadata();
let Some(visual) = meta.as_ref().map(|m| m.visuals().get(0)).flatten() else {
return None;
};
let buff: &[u8] = &visual.data;
let Ok(format) = image::guess_format(buff) else { return None };
if let Ok(img) = image::load(std::io::Cursor::new(buff), format) {
let (width, _height) = (img.width(), img.height());
#[cfg(not(feature = "album-art"))]
{
None
}
#[cfg(feature = "album-art")]
{
let meta = self.read_metadata();
let Some(img) = meta
.as_ref()
.map(|m| m.visuals().get(0))
.flatten()
.map(|visual| {
image::guess_format(&visual.data)
.ok()
.map(|format| image::load(Cursor::new(&visual.data), format).ok())
})
.flatten()
.flatten()
.or_else(|| self.find_art())
else {
return None;
};
let width = img.width();
Some(
img.into_rgba8()
.into_vec()
Expand All @@ -494,8 +547,6 @@ impl Track {
.map(|v| v.into())
.collect(),
)
} else {
None
}
} //}}}

Expand Down

0 comments on commit 93f8aa3

Please sign in to comment.