From 24963233f3886cdf30c2795e6b1958ea11e0f6e7 Mon Sep 17 00:00:00 2001 From: Rijul-A <31570722+Rijul-A@users.noreply.github.com> Date: Sun, 19 Apr 2026 13:04:57 +0000 Subject: [PATCH 1/3] feat(entrypoint): accept timestamp When another plugin or the user sends a request with a `timestamp=x` parameter, honour it --- jellyfin_kodi/entrypoint/default.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/jellyfin_kodi/entrypoint/default.py b/jellyfin_kodi/entrypoint/default.py index bf041dfc..1be7d2d5 100644 --- a/jellyfin_kodi/entrypoint/default.py +++ b/jellyfin_kodi/entrypoint/default.py @@ -104,7 +104,28 @@ class Events(object): elif mode == "play": item = api_client.get_item(params["id"]) - item["resumePlayback"] = sys.argv[3].split(":")[1] == "true" + timestamp = params.get("timestamp") + + if timestamp is not None: + player = xbmc.Player() + if player.isPlayingVideo(): + try: + playing_file = player.getPlayingFile() + if params["id"] in playing_file: + player.seekTime(float(timestamp)) + return + except Exception: + pass + + item["UserData"] = item.get("UserData", {}) + item["UserData"]["PlaybackPositionTicks"] = int(float(timestamp) * 10000000) + item["resumePlayback"] = True + else: + try: + item["resumePlayback"] = sys.argv[3].split(":")[1] == "true" + except IndexError: + item["resumePlayback"] = False + Actions(server, api_client).play( item, params.get("dbid"), From 11fc40b287a5ca0bf53e8a01823e80e12bc47213 Mon Sep 17 00:00:00 2001 From: Rijul-A <31570722+Rijul-A@users.noreply.github.com> Date: Sun, 19 Apr 2026 13:49:03 +0000 Subject: [PATCH 2/3] fix: support both modes --- jellyfin_kodi/entrypoint/default.py | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/jellyfin_kodi/entrypoint/default.py b/jellyfin_kodi/entrypoint/default.py index 1be7d2d5..42208aad 100644 --- a/jellyfin_kodi/entrypoint/default.py +++ b/jellyfin_kodi/entrypoint/default.py @@ -105,20 +105,35 @@ class Events(object): item = api_client.get_item(params["id"]) timestamp = params.get("timestamp") - + # check that timestamp is a float + try: + timestamp = float(timestamp) + except (TypeError, ValueError): + timestamp = None + # a timestamp of 0.0 is false-y so check for None if timestamp is not None: + is_current = False player = xbmc.Player() if player.isPlayingVideo(): try: playing_file = player.getPlayingFile() - if params["id"] in playing_file: - player.seekTime(float(timestamp)) + if settings( "useDirectPaths" ) == "0": + is_current = params["id"] in playing_file + else: + queue = json.loads(window("jellyfin_play.json") or "[]") + for item in queue: + if item.get("Path") == playing_file: + if item.get("Id") == params["id"]: + is_current = True + break + if is_current: + player.seekTime(timestamp) return - except Exception: - pass + except Exception as e: + LOG.debug("Failed to check playing file: %s", e) item["UserData"] = item.get("UserData", {}) - item["UserData"]["PlaybackPositionTicks"] = int(float(timestamp) * 10000000) + item["UserData"]["PlaybackPositionTicks"] = int(timestamp * 10000000.0) item["resumePlayback"] = True else: try: From 301e6f2087ee71fd45e65de72739daedd5345af8 Mon Sep 17 00:00:00 2001 From: Rijul-A <31570722+Rijul-A@users.noreply.github.com> Date: Sun, 19 Apr 2026 13:51:56 +0000 Subject: [PATCH 3/3] rename vars to avoid confusion --- jellyfin_kodi/entrypoint/default.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jellyfin_kodi/entrypoint/default.py b/jellyfin_kodi/entrypoint/default.py index 42208aad..298e07a1 100644 --- a/jellyfin_kodi/entrypoint/default.py +++ b/jellyfin_kodi/entrypoint/default.py @@ -121,9 +121,9 @@ class Events(object): is_current = params["id"] in playing_file else: queue = json.loads(window("jellyfin_play.json") or "[]") - for item in queue: - if item.get("Path") == playing_file: - if item.get("Id") == params["id"]: + for p_item in queue: + if p_item.get("Path") == playing_file: + if p_item.get("Id") == params["id"]: is_current = True break if is_current: