dev: bump to 0.1.71-dev – vollständiges Trakt-Scrobbling mit stop-Monitor
This commit is contained in:
@@ -3814,9 +3814,10 @@ def _play_final_link(
|
||||
player = xbmc.Player()
|
||||
player.play(item=link, listitem=list_item)
|
||||
|
||||
# Trakt Scrobble Start (Hintergrund-Thread)
|
||||
# Trakt Scrobble: Start senden, dann blockierend auf Wiedergabe-Ende warten
|
||||
if trakt_media and _get_setting_bool("trakt_enabled", default=False):
|
||||
_trakt_scrobble_start_async(trakt_media)
|
||||
_trakt_monitor_playback(trakt_media)
|
||||
|
||||
|
||||
def _trakt_scrobble_start_async(media: dict[str, object]) -> None:
|
||||
@@ -3844,6 +3845,77 @@ def _trakt_scrobble_start_async(media: dict[str, object]) -> None:
|
||||
threading.Thread(target=_do, daemon=True).start()
|
||||
|
||||
|
||||
def _trakt_scrobble_stop_async(media: dict[str, object], progress: float = 100.0) -> None:
|
||||
"""Sendet scrobble/stop an die Trakt-API in einem Hintergrund-Thread."""
|
||||
def _do() -> None:
|
||||
try:
|
||||
from core.trakt import TraktClient
|
||||
except Exception:
|
||||
return
|
||||
client_id = _get_setting_string("trakt_client_id").strip()
|
||||
client_secret = _get_setting_string("trakt_client_secret").strip()
|
||||
access_token = _get_setting_string("trakt_access_token").strip()
|
||||
if not client_id or not client_secret or not access_token:
|
||||
return
|
||||
client = TraktClient(client_id, client_secret, log=lambda m: _log(m, xbmc.LOGDEBUG))
|
||||
client.scrobble_stop(
|
||||
access_token,
|
||||
media_type=str(media.get("kind", "movie")),
|
||||
title=str(media.get("title", "")),
|
||||
tmdb_id=int(media.get("tmdb_id", 0)),
|
||||
imdb_id=str(media.get("imdb_id", "")),
|
||||
season=int(media.get("season", 0)),
|
||||
episode=int(media.get("episode", 0)),
|
||||
progress=progress,
|
||||
)
|
||||
_log(f"Trakt scrobble/stop: {media.get('title')} progress={progress:.0f}%", xbmc.LOGDEBUG)
|
||||
threading.Thread(target=_do, daemon=True).start()
|
||||
|
||||
|
||||
def _trakt_monitor_playback(media: dict[str, object]) -> None:
|
||||
"""Blockiert bis die Wiedergabe endet, berechnet Fortschritt und sendet scrobble/stop.
|
||||
|
||||
Muss im Haupt-Thread nach player.play() / setResolvedUrl() aufgerufen werden,
|
||||
damit der Plugin-Prozess bis zum Wiedergabe-Ende aktiv bleibt.
|
||||
"""
|
||||
monitor = xbmc.Monitor()
|
||||
player = xbmc.Player()
|
||||
|
||||
# Warten bis Wiedergabe startet (max 15 Sekunden)
|
||||
timeout = 0
|
||||
while not player.isPlaying() and timeout < 15:
|
||||
if monitor.waitForAbort(1):
|
||||
return
|
||||
timeout += 1
|
||||
if not player.isPlaying():
|
||||
_log("Trakt monitor: Wiedergabe nicht gestartet.", xbmc.LOGDEBUG)
|
||||
return
|
||||
|
||||
last_pos: float = 0.0
|
||||
total_time: float = 0.0
|
||||
try:
|
||||
total_time = player.getTotalTime()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Wiedergabe verfolgen (alle 5 Sekunden)
|
||||
while player.isPlaying() and not monitor.abortRequested():
|
||||
try:
|
||||
last_pos = player.getTime()
|
||||
if not total_time:
|
||||
total_time = player.getTotalTime()
|
||||
except Exception:
|
||||
pass
|
||||
monitor.waitForAbort(5)
|
||||
|
||||
if monitor.abortRequested():
|
||||
return
|
||||
|
||||
progress = min(100.0, (last_pos / total_time * 100.0)) if total_time > 0 else 100.0
|
||||
_log(f"Trakt monitor: Wiedergabe beendet, progress={progress:.0f}%", xbmc.LOGDEBUG)
|
||||
_trakt_scrobble_stop_async(media, progress=progress)
|
||||
|
||||
|
||||
def _track_playback_and_update_state_async(key: str) -> None:
|
||||
# Eigenes Resume/Watched ist deaktiviert; Kodi verwaltet das selbst.
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user