2 Commits
Author SHA1 Message Date
Fojadrachi 5379be6c11 Release v2.2.1
Release / build-windows (push) Waiting to run
Release / build-linux (push) Waiting to run
Release / publish-release (push) Blocked by required conditions
2026-09-12 13:44:47 +02:00
FojadrachiandClaude Sonnet 5 c6fe895334 Fix: Discord-Thumbnail bleibt ueber mehrere Songs stehen (YT Music)
Log-Beweis: dieselbe Thumbnail-URL blieb ueber mehrere komplett verschiedene
Songs (unterschiedliche Titel/Interpreten) unveraendert stehen, waehrend Titel
und Zeit bereits korrekt aktualisiert wurden. Das bisher bevorzugte <img> in
der YT-Music-Playerleiste wird von YouTube per Crossfade/Shadow-DOM animiert
und aktualisiert sein src-Attribut dabei nicht zuverlaessig pro Titel.

Thumbnail wird jetzt primaer aus der Video-ID in der URL abgeleitet (wechselt
garantiert synchron mit dem Titel, dieselbe Quelle die schon zuverlaessig als
Fallback diente) statt aus dem unzuverlaessigen Player-Leisten-<img>, das nur
noch als letzter Fallback dient. Debug-Log zeigt jetzt zusaetzlich die URL pro
Send fuer weitere Verifikation.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-12 13:44:41 +02:00
3 changed files with 13 additions and 4 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
"""Playtube - ein eigenstaendiger YouTube- & YouTube-Music-Player mit Discord Rich Presence.""" """Playtube - ein eigenstaendiger YouTube- & YouTube-Music-Player mit Discord Rich Presence."""
__app_name__ = "Playtube" __app_name__ = "Playtube"
__version__ = "2.2.0" __version__ = "2.2.1"
+2 -1
View File
@@ -259,9 +259,10 @@ class DiscordRPCWorker(QThread):
payload = build_presence_payload(item, self._session_start, start_ts, end_ts) payload = build_presence_payload(item, self._session_start, start_ts, end_ts)
self._presence.update(**payload) self._presence.update(**payload)
log_line( log_line(
"[send] title=%r thumbnail=%r large_image=%r start=%s end=%s" "[send] title=%r url=%r thumbnail=%r large_image=%r start=%s end=%s"
% ( % (
item.get("title"), item.get("title"),
item.get("url"),
item.get("thumbnail"), item.get("thumbnail"),
payload.get("large_image"), payload.get("large_image"),
start_ts, start_ts,
+10 -2
View File
@@ -82,10 +82,18 @@ MEDIA_PROBE_JS = r"""
var videoId = videoIdFromUrl(location.href); var videoId = videoIdFromUrl(location.href);
var title = null, subtitle = null, thumbnail = null; var title = null, subtitle = null, thumbnail = null;
// WICHTIG: die Video-ID aus der URL ist die zuverlaessigste Thumbnail-Quelle - sie
// wechselt garantiert synchron mit dem Titel. Das <img> in der YT-Music-Playerleiste
// (fruehere Praeferenz) wird von YouTube per Crossfade/Shadow-DOM animiert und
// aktualisiert sein src-Attribut dabei nachweislich NICHT zuverlaessig pro Titel -
// empirisch bestaetigt: dieselbe Thumbnail-URL blieb ueber mehrere komplett
// unterschiedliche Songs hinweg stehen, obwohl Titel/Zeit schon laengst gewechselt
// hatten. Das DOM-<img> dient nur noch als Fallback, falls keine Video-ID in der
// URL steckt.
if (isMusic) { if (isMusic) {
title = txt('.title.ytmusic-player-bar') || txt('ytmusic-player-bar .title'); title = txt('.title.ytmusic-player-bar') || txt('ytmusic-player-bar .title');
subtitle = txt('.byline.ytmusic-player-bar') || txt('ytmusic-player-bar .byline'); subtitle = txt('.byline.ytmusic-player-bar') || txt('ytmusic-player-bar .byline');
thumbnail = imgSrc('ytmusic-player-bar img, .image.ytmusic-player-bar img') || ytThumbnailUrl(videoId); thumbnail = ytThumbnailUrl(videoId) || imgSrc('ytmusic-player-bar img, .image.ytmusic-player-bar img');
} else { } else {
var t = document.title.replace(/ - YouTube$/, ''); var t = document.title.replace(/ - YouTube$/, '');
title = t || null; title = t || null;
@@ -94,7 +102,7 @@ MEDIA_PROBE_JS = r"""
|| txt('#channel-name a') || txt('#channel-name a')
|| txt('ytd-channel-name#channel-name a'); || txt('ytd-channel-name#channel-name a');
var imgY = document.querySelector('link[rel="image_src"]'); var imgY = document.querySelector('link[rel="image_src"]');
thumbnail = (imgY ? imgY.href : null) || ytThumbnailUrl(videoId); thumbnail = ytThumbnailUrl(videoId) || (imgY ? imgY.href : null);
} }
var timeInfo = isMusic ? musicTimeInfo() : youtubeTimeInfo(); var timeInfo = isMusic ? musicTimeInfo() : youtubeTimeInfo();