From 5f2145e5feb9eb948cb4db982da7bbc5b0a3e793 Mon Sep 17 00:00:00 2001 From: Kayos Date: Sat, 23 May 2026 13:56:04 -0700 Subject: [PATCH] =?UTF-8?q?v1.0.1=20=E2=80=94=20pv.youtube=20service=20pre?= =?UTF-8?q?flight=20+=20sidecar=20runtime=20revert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two fixes after a 2026-05-23 regression where a Kodi restart left plugin.video.youtube's service.py un-started, breaking every delegated play with a silent "Service IPC - Monitor has not started" error. - Addon: probe pv.youtube's localhost httpd (50152/50153) before delegating. If nothing is listening, show a "YouTube service down — restart Kodi" notification and fall back to our DASH / progressive paths instead of letting setResolvedUrl fail silently. - Sidecar: revert tokio runtime from current_thread back to multi_thread with 2 worker threads so subscriptions_feed's per-channel tokio::spawn fan-out runs in parallel. The current_thread RSS savings weren't worth the behavioral change. --- addon/plugin.video.torttube/addon.xml | 2 +- addon/plugin.video.torttube/main.py | 31 +++++++++++++++++++++ sidecar/Cargo.toml | 2 +- sidecar/crates/torttube-sidecar/src/main.rs | 10 +++---- 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/addon/plugin.video.torttube/addon.xml b/addon/plugin.video.torttube/addon.xml index bcf28b2..00b2af9 100644 --- a/addon/plugin.video.torttube/addon.xml +++ b/addon/plugin.video.torttube/addon.xml @@ -1,7 +1,7 @@ diff --git a/addon/plugin.video.torttube/main.py b/addon/plugin.video.torttube/main.py index 61bd042..b813c2e 100644 --- a/addon/plugin.video.torttube/main.py +++ b/addon/plugin.video.torttube/main.py @@ -442,6 +442,21 @@ def _delegate_to_pv_youtube(yt_id: str) -> bool: if delegation succeeded (Kodi will chain-resolve).""" if not _pv_youtube_installed(): return False + if not _pv_youtube_service_alive(): + _log( + "pv.youtube installed but service httpd not responding — restart Kodi to recover", + xbmc.LOGERROR, + ) + try: + xbmcgui.Dialog().notification( + "YouTube service down", + "Restart Kodi to fix playback", + xbmcgui.NOTIFICATION_ERROR, + 6000, + ) + except Exception: + pass + return False target = f"plugin://plugin.video.youtube/play/?video_id={yt_id}" _log(f"delegating playback to plugin.video.youtube: {target}") li = xbmcgui.ListItem(label=yt_id) @@ -462,6 +477,22 @@ def _pv_youtube_installed() -> bool: return False +def _pv_youtube_service_alive() -> bool: + # Their service.py runs an httpd on 50152 (default) for MPD/segment serving. + # If it isn't listening, every delegated play silently fails with + # "Service IPC - Monitor has not started" in kodi.log and the user just sees + # nothing happen. Probe with a 500ms localhost connect — cheap and reliable. + # Custom-port users may get a false negative; addon then falls back to its + # own paths, so degradation is graceful either way. + for port in (50152, 50153): + try: + with socket.create_connection(("127.0.0.1", port), timeout=0.5): + return True + except OSError: + continue + return False + + def _play(yt_id: str) -> None: """Resolve playback in order of preference: 1. plugin.video.youtube delegation — HD via their proven DASH MPD with diff --git a/sidecar/Cargo.toml b/sidecar/Cargo.toml index 2dc95a9..b5ff0bb 100644 --- a/sidecar/Cargo.toml +++ b/sidecar/Cargo.toml @@ -3,7 +3,7 @@ resolver = "2" members = ["crates/torttube-sidecar"] [workspace.package] -version = "1.0.0" +version = "1.0.1" edition = "2021" license = "GPL-3.0-or-later" authors = ["Cobb "] diff --git a/sidecar/crates/torttube-sidecar/src/main.rs b/sidecar/crates/torttube-sidecar/src/main.rs index b9e85d6..ebde5b9 100644 --- a/sidecar/crates/torttube-sidecar/src/main.rs +++ b/sidecar/crates/torttube-sidecar/src/main.rs @@ -146,12 +146,10 @@ impl Response { } // One-shot sidecar — each invocation handles a single JSON request and exits. -// current_thread runtime keeps RSS smaller per spawn (~100KB savings vs the -// multi-thread runtime), which matters when the addon does many calls per -// Kodi session. Concurrent fan-out in subscriptions_feed uses tokio::spawn -// onto this same runtime — current_thread is single-threaded but cooperatively -// multi-tasks via futures, fine for I/O-bound rustypipe + reqwest calls. -#[tokio::main(flavor = "current_thread")] +// Two worker threads so subscriptions_feed's tokio::spawn fan-out across many +// channels actually runs in parallel; the per-spawn RSS cost is negligible at +// addon-call cadence. +#[tokio::main(flavor = "multi_thread", worker_threads = 2)] async fn main() -> anyhow::Result<()> { tracing_subscriber::fmt() .with_env_filter(