dev: bump to 0.1.71-dev – vollständiges Trakt-Scrobbling mit stop-Monitor

This commit is contained in:
2026-03-01 19:17:58 +01:00
parent 7243c5353b
commit 3c0891b638
3 changed files with 81 additions and 2 deletions

View File

@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<addon id="plugin.video.viewit" name="ViewIt" version="0.1.70-dev" provider-name="ViewIt">
<addon id="plugin.video.viewit" name="ViewIt" version="0.1.71-dev" provider-name="ViewIt">
<requires>
<import addon="xbmc.python" version="3.0.0" />
<import addon="script.module.requests" />

View File

@@ -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