84 lines
2.4 KiB
Python
84 lines
2.4 KiB
Python
|
|
#!/usr/bin/env python3
|
|||
|
|
"""Gemeinsame Launcher-Logik fuer Windows-Starter und macOS.
|
|||
|
|
|
|||
|
|
Unsichtbarer Ablauf: GStreamer vorhanden -> Engine im Hintergrund
|
|||
|
|
starten, auf die Web-UI warten, Browser oeffnen.
|
|||
|
|
Fehlt etwas -> grafischer Installer (installer_gui.py) oeffnen.
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
from __future__ import annotations
|
|||
|
|
|
|||
|
|
import json
|
|||
|
|
import subprocess
|
|||
|
|
import sys
|
|||
|
|
import time
|
|||
|
|
import urllib.request
|
|||
|
|
import webbrowser
|
|||
|
|
from pathlib import Path
|
|||
|
|
|
|||
|
|
ROOT = Path(__file__).resolve().parent
|
|||
|
|
IS_WIN = sys.platform == "win32"
|
|||
|
|
|
|||
|
|
|
|||
|
|
def web_port() -> int:
|
|||
|
|
try:
|
|||
|
|
cfg = json.loads((ROOT / "config.json").read_text("utf-8"))
|
|||
|
|
return int(cfg.get("web", {}).get("port", 8080))
|
|||
|
|
except Exception: # noqa: BLE001
|
|||
|
|
return 8080
|
|||
|
|
|
|||
|
|
|
|||
|
|
def gst_ok() -> bool:
|
|||
|
|
try:
|
|||
|
|
import gi # noqa: F401
|
|||
|
|
gi.require_version("Gst", "1.0")
|
|||
|
|
from gi.repository import Gst
|
|||
|
|
Gst.init(None)
|
|||
|
|
return True
|
|||
|
|
except Exception: # noqa: BLE001
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
|
|||
|
|
def _spawn(py: str, target: str, hidden: bool) -> None:
|
|||
|
|
if IS_WIN and hidden:
|
|||
|
|
subprocess.Popen(
|
|||
|
|
[py, str(ROOT / target)], cwd=str(ROOT),
|
|||
|
|
creationflags=0x08000000, # CREATE_NO_WINDOW
|
|||
|
|
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|||
|
|
else:
|
|||
|
|
subprocess.Popen(
|
|||
|
|
[py, str(ROOT / target)], cwd=str(ROOT),
|
|||
|
|
stdout=open("/tmp/hms-mediaengine.log", "ab"),
|
|||
|
|
stderr=subprocess.STDOUT, start_new_session=not IS_WIN)
|
|||
|
|
|
|||
|
|
|
|||
|
|
def wait_health(port: int, timeout_s: float = 25.0) -> bool:
|
|||
|
|
deadline = time.monotonic() + timeout_s
|
|||
|
|
while time.monotonic() < deadline:
|
|||
|
|
try:
|
|||
|
|
with urllib.request.urlopen(
|
|||
|
|
f"http://localhost:{port}/api/health",
|
|||
|
|
timeout=1.5) as r:
|
|||
|
|
if json.loads(r.read().decode()).get("status") == "ok":
|
|||
|
|
return True
|
|||
|
|
except Exception: # noqa: BLE001
|
|||
|
|
time.sleep(0.4)
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
|
|||
|
|
def launch() -> int:
|
|||
|
|
if gst_ok():
|
|||
|
|
_spawn(sys.executable, "run.py", hidden=True)
|
|||
|
|
port = web_port()
|
|||
|
|
if wait_health(port):
|
|||
|
|
webbrowser.open(f"http://localhost:{port}")
|
|||
|
|
return 0
|
|||
|
|
print("[Launcher] Engine antwortete nicht rechtzeitig – "
|
|||
|
|
"oeffne Installer.", file=sys.stderr)
|
|||
|
|
_spawn(sys.executable, "installer_gui.py", hidden=False)
|
|||
|
|
return 1
|
|||
|
|
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
sys.exit(launch())
|