1.0.0+kodimov.13: updates don't stop live TV; IPTV Simple restarts only when idle

- After an add-on update the new service found port 57031 still held by the
  old proxy for a moment and moved to a random port; the stream playing kept
  asking 57031 for its manifest and died a minute later (.49, 2026-11-13).
  The proxy now waits up to 10 s for the port, and SO_REUSEADDR /
  allow_reuse_address are set before binding (upstream set them after, so
  they did nothing).
- IPTV Simple is restarted only when nothing plays and no key was pressed
  for 30 s: on .49 a channel opened during a restart failed with an error.
- After start or update, changed instance files (duplicate removed, refresh
  timer) are picked up by the guide reload instead of a restart of their
  own; the service restarts IPTV Simple itself only if that reload didn't
  happen within 10 minutes. 3 restarts after kodimov.12 -> 2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
XoséandClaude Opus 5.5 committed 2026-11-13 15:16:30 +01:00
1 parent 69a37ff064
commit 7873b50203
6 files changed
+63 -15

No files matched your search

+32 -5
View File
@@ -492,25 +492,51 @@ def reload_iptv_guide(pvr_dir, addon_id):
restart it with the hourly timer. Restarting stops live TV, so this does
nothing if something is playing."""
import xbmc
monitor, player = xbmc.Monitor(), xbmc.Player()
if player.isPlaying(): return
monitor = xbmc.Monitor()
if not wait_until_idle(timeout=600): return
if not set_iptv_refresh(pvr_dir, addon_id, 1): return
try:
restart_iptv_simple()
monitor.waitForAbort(90)
finally:
set_iptv_refresh(pvr_dir, addon_id, 60)
while player.isPlaying(): # until then it keeps reloading every minute
if monitor.waitForAbort(10): return
if not monitor.abortRequested():
if wait_until_idle(): # until then it keeps reloading every minute
restart_iptv_simple()
def is_idle(seconds=30):
"""Nothing playing and nobody pressed a key for a while. Restarting IPTV
Simple stops live TV, and a channel opened while it restarts fails."""
import xbmc
return not xbmc.Player().isPlaying() and xbmc.getGlobalIdleTime() >= seconds
def wait_until_idle(timeout=None):
"""Waits until is_idle(). False if Kodi is closing or the timeout ran out."""
import xbmc
monitor = xbmc.Monitor()
end = time.time() + timeout if timeout else None
while not is_idle():
if monitor.waitForAbort(5) or (end and time.time() > end): return False
return not monitor.abortRequested()
# IPTV Simple is shared with other add-ons (Radios de Vigo keeps its own
# instance for the Radio section). Restarting it restarts every instance, so
# the add-ons take turns: whoever restarts it says so in this property of
# Kodi's home window (the time it started), and the others wait.
IPTV_RESTART_PROPERTY = 'pvr.iptvsimple.restarting'
# When this add-on last restarted it, so the service can skip a restart that
# one from the plugin (the guide reload) already did
LAST_RESTART_PROPERTY = 'kodimovplus.iptvsimple.restarted'
def last_iptv_restart():
import xbmcgui
try:
return float(xbmcgui.Window(10000).getProperty(LAST_RESTART_PROPERTY) or 0)
except ValueError:
return 0
def restart_iptv_simple():
@@ -526,6 +552,7 @@ def restart_iptv_simple():
if not busy: break
xbmc.sleep(1000)
window.setProperty(IPTV_RESTART_PROPERTY, str(time.time()))
window.setProperty(LAST_RESTART_PROPERTY, str(time.time()))
try:
for enabled in (False, True):
xbmc.executeJSONRPC(json.dumps({'jsonrpc': '2.0', 'id': 1, 'method': 'Addons.SetAddonEnabled',