From 28f97d67d53fd7daf943a4559e33b2ad0c002aec Mon Sep 17 00:00:00 2001 From: Sweetbread Date: Wed, 14 Jan 2026 23:50:21 +0300 Subject: [PATCH] Take cover art from YT if possible --- src/main.rs | 66 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 13 deletions(-) mode change 100644 => 100755 src/main.rs diff --git a/src/main.rs b/src/main.rs old mode 100644 new mode 100755 index dd1044c..d1414e4 --- a/src/main.rs +++ b/src/main.rs @@ -57,18 +57,32 @@ fn main() -> Result<(), Box> { debug!("Cached cover failure"); None } else { - let url = lb.cover_art(&track, &artist, release_name.as_deref(), 0); + let youtube_cover_url = metadata.additional_info.as_ref() + .and_then(|info| info.music_service_name.as_ref()) + .filter(|service| *service == "YouTube Music") + .and_then(|_| metadata.additional_info.as_ref()) + .and_then(|info| info.origin_url.as_ref()) + .and_then(|url| extract_youtube_video_id(url)) + .map(|video_id| format!( + "https://img.youtube.com/vi/{}/sddefault.jpg", + video_id + )); - match url { - Ok(a) => { - cover_cache.insert(hash_key, a.clone()); - Some(a) - }, - Err(e) => { - error!("Error fetching cover_art: {}", e); - cover_failure_cache.insert(hash_key); - None - }, + if let Some(url) = youtube_cover_url { + cover_cache.insert(hash_key.clone(), url.clone()); + Some(url) + } else { + match lb.cover_art(&track, &artist, release_name.as_deref(), 0) { + Ok(url) => { + cover_cache.insert(hash_key.clone(), url.clone()); + Some(url) + }, + Err(e) => { + error!("Error fetching cover_art: {}", e); + cover_failure_cache.insert(hash_key); + None + }, + } } }; @@ -80,10 +94,10 @@ fn main() -> Result<(), Box> { .state(artist.clone()) .details(track.clone()); - if let Some(url) = cover_art { + if let Some(cover_url) = cover_art { t = t.assets(|ass| { ass - .large_image(url) + .large_image(cover_url) .large_text(format!("{} - {}", &track, &artist)) }) } @@ -96,3 +110,29 @@ fn main() -> Result<(), Box> { thread::sleep(time::Duration::from_secs(15)); } } + +fn extract_youtube_video_id(url: &str) -> Option<&str> { + let patterns = [ + "youtube.com/watch?v=", + "youtu.be/", + "youtube.com/v/", + "youtube.com/embed/", + ]; + + for pattern in patterns.iter() { + if let Some(pos) = url.find(pattern) { + let start = pos + pattern.len(); + let end = url[start..] + .find(|c: char| !c.is_alphanumeric() && c != '_' && c != '-') + .map(|end_pos| start + end_pos) + .unwrap_or(url.len()); + + let video_id = &url[start..end]; + if !video_id.is_empty() { + return Some(video_id); + } + } + } + + None +}