From 79edc15f0ba1115cd0f5518085affaef8c06d6f3 Mon Sep 17 00:00:00 2001 From: nutty Date: Sun, 28 Jun 2026 04:29:26 +1000 Subject: [PATCH] Fixed accent colors --- now-playing/settings/settings.json | 2 +- now-playing/smtc-bridge.py | 24 ++---------------------- now-playing/themes/card/script.js | 16 +++++++++------- 3 files changed, 12 insertions(+), 30 deletions(-) diff --git a/now-playing/settings/settings.json b/now-playing/settings/settings.json index 2c47d5b..3bffb9b 100644 --- a/now-playing/settings/settings.json +++ b/now-playing/settings/settings.json @@ -83,7 +83,7 @@ }, { "id": "showAlbumArt", - "label": "Show AlbumArt", + "label": "Show Album Art", "description": "", "type": "checkbox", "defaultValue": true, diff --git a/now-playing/smtc-bridge.py b/now-playing/smtc-bridge.py index d43593a..ddc245b 100644 --- a/now-playing/smtc-bridge.py +++ b/now-playing/smtc-bridge.py @@ -33,23 +33,6 @@ CORS(app) # --- GLOBAL MEMORY CACHE --- ARTWORK_CACHE = {} -def get_smart_accent(img): - """Sorts pixels by saturation to find the most vibrant color.""" - thumb = img.copy() - thumb.thumbnail((20, 20)) # Higher sample rate than 1x1 - pixels = list(thumb.getdata()) - - # Sort by saturation: (max_channel - min_channel) - pixels.sort(key=lambda p: max(p) - min(p), reverse=True) - best_rgb = pixels[0] - - # Safety boost: ensure it's readable and vibrant - min_val = 80 - rgb = [max(c, min_val) for c in best_rgb] - rgb = [min(int(c * 1.2), 255) for c in rgb] - - return '#{:02x}{:02x}{:02x}'.format(*rgb) - async def get_all_media_info(): global ARTWORK_CACHE import winsdk._winrt @@ -90,11 +73,10 @@ async def get_all_media_info(): artist = raw_media.artist if raw_media else "Unknown" track_key = f"{title} - {artist}" - media_data = {"Title": title, "Artist": artist, "Base64Image": None, "AccentColor": "#ffffff"} + media_data = {"Title": title, "Artist": artist, "Base64Image": None} if app_id in ARTWORK_CACHE and ARTWORK_CACHE[app_id]["track_key"] == track_key: media_data["Base64Image"] = ARTWORK_CACHE[app_id]["base64"] - media_data["AccentColor"] = ARTWORK_CACHE[app_id]["accent"] elif raw_media and raw_media.thumbnail: try: @@ -106,12 +88,10 @@ async def get_all_media_info(): reader.read_bytes(buffer) img = Image.open(io.BytesIO(buffer)) - hex_color = get_smart_accent(img) base64_art = f"data:image/png;base64,{base64.b64encode(buffer).decode('utf-8')}" - ARTWORK_CACHE[app_id] = {"track_key": track_key, "base64": base64_art, "accent": hex_color} + ARTWORK_CACHE[app_id] = {"track_key": track_key, "base64": base64_art} media_data["Base64Image"] = base64_art - media_data["AccentColor"] = hex_color except Exception: pass diff --git a/now-playing/themes/card/script.js b/now-playing/themes/card/script.js index 56ffe9c..88baa7f 100644 --- a/now-playing/themes/card/script.js +++ b/now-playing/themes/card/script.js @@ -51,7 +51,7 @@ if (!showProgressBar) //////////////////// // Each theme must implement the following -function UpdatePlayerState(data) { +async function UpdatePlayerState(data) { // Check if the user has provided a target application in the settings const isFiltering = targetApplication && targetApplication.trim() !== ""; @@ -72,6 +72,9 @@ function UpdatePlayerState(data) { const playbackInfo = targetSession.playback_info; const mediaProps = targetSession.media_properties; const timelineProps = targetSession.timeline_properties; + + // Calcualte an accent color + const accentColorPalette = await GetAccentPalette(mediaProps.Base64Image); // 1. Check if playback status has changed and update visibility accordingly if (playbackInfo.PlaybackStatus !== CurrentPlaybackStatus) { @@ -85,7 +88,7 @@ function UpdatePlayerState(data) { // 2. Check if the track name/artist have changed - this is our indicator that the next track has loaded const newTrackKey = `${mediaProps.Title}|${mediaProps.Artist}`; if (newTrackKey !== CurrentSong) { - ChangeTrack(mediaProps); // Now trigger your cross-fade logic here! + ChangeTrack(mediaProps, accentColorPalette.LightVibrant); // Now trigger your cross-fade logic here! CurrentSong = newTrackKey; // Update the tracker with the string key } @@ -116,7 +119,7 @@ function UpdatePlayerState(data) { let progressPercent = durationMs > 0 ? (currentPositionMs / durationMs) * 100 : 0; progressPercent = Math.min(100, Math.max(0, progressPercent)); progressBarFill.style.width = `${progressPercent}%`; - progressBarFill.style.setProperty('--accent-color', mediaProps.AccentColor); + progressBarFill.style.setProperty('--accent-color', accentColorPalette.LightVibrant); } } else @@ -152,7 +155,7 @@ function SetVisibility(visible) { } } -async function ChangeTrack(mediaProps) { +async function ChangeTrack(mediaProps, tintColor) { // Fade in the overlay (shows the new text) trackLabel.style.opacity = "0"; artistLabel.style.opacity = "0"; @@ -166,7 +169,6 @@ async function ChangeTrack(mediaProps) { // Extract the image source string (use fallback if Windows has no art) const newArtUrl = mediaProps.Base64Image; - const accent = mediaProps.AccentColor || "#ffffff"; // Set the image backgroundLayer.style.backgroundImage = `url('${newArtUrl}')`; @@ -174,7 +176,7 @@ async function ChangeTrack(mediaProps) { // Apply a tint: Use 30% opacity of the accent color + a dark overlay for contrast // 'rgba(0,0,0,0.6)' ensures the text stays readable - backgroundLayer.style.backgroundColor = accent + "80"; // 80 is 50% opacity in hex + backgroundLayer.style.backgroundColor = tintColor + "80"; // 80 is 50% opacity in hex trackLabel.style.opacity = ""; artistLabel.style.opacity = ""; @@ -188,7 +190,7 @@ async function ChangeTrack(mediaProps) { // Apply a tint: Use 30% opacity of the accent color + a dark overlay for contrast // 'rgba(0,0,0,0.6)' ensures the text stays readable - backgroundTransitionLayer.style.backgroundColor = accent + "80"; // 80 is 50% opacity in hex + backgroundTransitionLayer.style.backgroundColor = tintColor + "80"; // 80 is 50% opacity in hex SetVisibility(true); // Show the overlay for a few seconds if autoHide is enabled }, 250);