v1.0.1 — pv.youtube service preflight + sidecar runtime revert
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.
This commit is contained in:
parent
24be9497e9
commit
5f2145e5fe
4 changed files with 37 additions and 8 deletions
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<addon id="plugin.video.torttube"
|
||||
name="torttube"
|
||||
version="1.0.0"
|
||||
version="1.0.1"
|
||||
provider-name="Sulkta-Coop">
|
||||
<requires>
|
||||
<import addon="xbmc.python" version="3.0.0"/>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 <cobb@sulkta.com>"]
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue