Ursache: start/end wurden nur gesendet, wenn 'playing' gerade true war. Bei jedem
automatischen Songwechsel laedt das <video>-Element kurz neu, wodurch 'playing' fuer
1-2 Polls faelschlich false wird - in diesem Fenster fehlten start/end im Update
komplett. Discord ersetzt 'timestamps' bei einem unvollstaendigen SET_ACTIVITY-Update
offenbar nicht sauber, sondern behaelt die zuletzt bekannten (viel zu alten) Werte
bei, wodurch die angezeigte Zeit ueber mehrere Songs hinweg immer weiter waechst statt
pro Lied neu zu starten. Fix: start/end werden jetzt IMMER mitgeschickt, unabhaengig
vom playing-Status (ein pausierter Titel zeigt dann einfach einen eingefrorenen statt
gar keinen Fortschrittsbalken).
Co-Authored-By: Claude Sonnet 5 <[email protected]>
- Einstellungen-Tab: 'Jetzt nach Updates suchen'-Button, Status-Text (aktuell/verfuegbar/
fehlgeschlagen), Fortschrittsbalken fuer den Download (Prozent bei bekannter Groesse,
unbestimmt waehrend Entpacken/Installieren), 'Update installieren'-Button erscheint bei Fund.
- updater.py/UpdateInstaller: laedt Download jetzt in Chunks (statt copyfileobj) und meldet
echten Fortschritt in Prozent ueber ein neues progress_percent-Signal.
- Patch-Updates: CI baut zusaetzlich zum vollen Release-Paket ein kleines '-patch'-Paket,
das nur die ausfuehrbare Datei (Playtube.exe/Playtube, ~2-3 MB) enthaelt - der riesige
PySide6/QtWebEngine-Laufzeitordner _internal/ (~200 MB) bleibt unangetastet, da er sich
zwischen normalen Code-Patches nicht aendert. updater.py bevorzugt das Patch-Paket und
faellt nur auf das volle Paket zurueck, wenn kein Patch-Asset gefunden wird.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Auf vielen aktuellen YouTube-Seiten fehlt das <link rel="image_src"> Tag, auf das
sich die Thumbnail-Erkennung bisher verlassen hat - large_image fiel dadurch staendig
auf das statische Logo zurueck. Jetzt wird die Video-ID aus der URL (?v=...) gelesen
und die Thumbnail-URL direkt ueber YouTubes CDN gebaut (i.ytimg.com/vi/<id>/hqdefault.jpg),
funktioniert zuverlaessig unabhaengig vom Seiten-Markup. Per Live-Test verifiziert.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Der entscheidende verbleibende Bug: 'activity_type' wurde als rohes int gesetzt,
pypresence.Presence.update() ruft aber intern .value darauf auf und wirft
AttributeError - jedes Update mit echten Mediendaten schlug dadurch fehl (nur die
generische Idle-Presence ohne activity_type kam durch). Fix: ActivityType-Enum
verwenden (LISTENING/WATCHING statt Default PLAYING), zusammen mit 'instance: False'
nach Vorbild einer frueheren, funktionierenden Electron-Implementierung. Per
Discord-Screenshot verifiziert: RPC erscheint jetzt korrekt.
Zusaetzlich:
- large_image nutzt jetzt die echte Video-/Cover-Thumbnail-URL (Discord akzeptiert
externe Bild-URLs, nicht nur hochgeladene Asset-Keys) statt des statischen Logos,
mit Hochskalierung fuer die kleinen YouTube-Music-Player-Bar-Thumbnails.
- media_probe.py: Thumbnail-Erkennung nutzt jetzt getAttribute('src') statt .src -
bei einem noch nicht geladenen <img> (leeres src-Attribut) loeste .src faelschlich
auf die aktuelle Seiten-URL auf statt null zu liefern.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Verhindert, dass ein lokaler Test-/Dev-Build (python main.py) sich Login-Profil und
Discord-Konfiguration mit einer installierten/gepackten Playtube.exe teilt - genau das
hatte zuletzt zur falschen Discord-Client-ID in der echten Installation gefuehrt.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Wurzelursache gefunden: page().runJavaScript() liefert bei einem direkt
zurueckgegebenen JS-Objekt in dieser PySide6/QtWebEngine-Version zuverlaessig nur
einen leeren String statt das Objekt (Zahlen/Strings funktionieren, Objekte nicht).
Dadurch schlug 'isinstance(result, dict)' in BrowserTab._on_media_probe_result IMMER
fehl, mediaInfoChanged wurde nie emittiert, MainWindow._on_media_info nie aufgerufen
und der DiscordRPCWorker damit nie mit echten Daten gefuettert (Warteschlange blieb
fuer immer leer, der Worker hat sich nie mal mit Discord verbunden).
Fix: media_probe.py gibt jetzt JSON.stringify(...) zurueck, browser.py parst den
String mit json.loads(). Per isoliertem Test verifiziert (Songtitel erscheint jetzt
korrekt im Fenstertitel, Discord-Update wird erfolgreich gesendet).
Ausserdem: PLAYTUBE_DEBUG=1 Env-Var fuer Debug-Logging in browser.py/discord_rpc.py,
Exceptions in discord_rpc.py werden jetzt sichtbar geloggt statt verschluckt,
neue Discord Client-ID.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
- Settings-Tab in der App (Discord/Update/Start-Tab live editierbar, kein config.json-Handbearbeiten noetig)
- updater.py: plattformabhaengige Asset-Auswahl + Installation (Windows .zip/robocopy, Linux .tar.gz/Shell-Skript)
- browser.py/chrome_shim.py: Sec-CH-UA + navigator.userAgentData jetzt je nach sys.platform (Windows/Linux/macOS)
- app_id.py: robustere Suche nach umbenanntem QtWebEngine-Hilfsprozess (rglob statt fixer Pfade)
- packaging/playtube.spec: icon/version nur unter Windows setzen (Linux-Build faehig)
- packaging/install-linux.sh: Installationsskript fuer native Linux-Version (Desktop-Eintrag, Icon, PATH)
- .github/workflows/release.yml: baut bei Tag-Push automatisch Windows-.exe UND Linux-Binary und veroeffentlicht beide als GitHub Release
Co-Authored-By: Claude Sonnet 5 <[email protected]>