fix wheplayer
This commit is contained in:
+56
-8
@@ -5,6 +5,7 @@ import logging
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import httpx
|
||||
import yaml
|
||||
@@ -64,6 +65,38 @@ def _extract_port(address: str, fallback: int) -> int:
|
||||
return fallback
|
||||
|
||||
|
||||
def _host_from_url(url: str, fallback: str) -> str:
|
||||
try:
|
||||
parsed = urlparse(url)
|
||||
host = (parsed.hostname or "").strip()
|
||||
if host and host not in {"0.0.0.0", "::"}:
|
||||
return host
|
||||
except ValueError:
|
||||
pass
|
||||
return fallback
|
||||
|
||||
|
||||
def _extract_host(address: str, fallback: str) -> str:
|
||||
text = str(address or "").strip()
|
||||
if not text:
|
||||
return fallback
|
||||
if text.startswith(":"):
|
||||
return fallback
|
||||
if "://" in text:
|
||||
return _host_from_url(text, fallback)
|
||||
if text.startswith("[") and "]" in text:
|
||||
host = text[1 : text.index("]")]
|
||||
return host or fallback
|
||||
if ":" in text:
|
||||
host = text.rsplit(":", 1)[0].strip()
|
||||
if host and host not in {"0.0.0.0", "::"}:
|
||||
return host
|
||||
return fallback
|
||||
if text in {"0.0.0.0", "::"}:
|
||||
return fallback
|
||||
return text
|
||||
|
||||
|
||||
def _load_mediamtx_yml() -> dict:
|
||||
if not MEDIAMTX_YML_PATH.exists():
|
||||
raise HTTPException(status_code=500, detail="mediamtx_yml_not_found")
|
||||
@@ -78,11 +111,15 @@ def _save_mediamtx_yml(data: dict) -> None:
|
||||
)
|
||||
|
||||
|
||||
def _build_mediamtx_view(data: dict) -> MediaMTXConfigView:
|
||||
def _build_mediamtx_view(data: dict, current_cfg: Optional[AppConfig] = None) -> MediaMTXConfigView:
|
||||
api_port = _extract_port(str(data.get("apiAddress", ":9997")), 9997)
|
||||
webrtc_port = _extract_port(str(data.get("webrtcAddress", ":8889")), 8889)
|
||||
current_api_host = _host_from_url((current_cfg.mediamtx_api_url if current_cfg else ""), "127.0.0.1")
|
||||
current_webrtc_host = _host_from_url((current_cfg.mediamtx_webrtc_url if current_cfg else ""), "127.0.0.1")
|
||||
api_host = _extract_host(str(data.get("apiAddress", ":9997")), current_api_host)
|
||||
|
||||
hosts = data.get("webrtcAdditionalHosts") or []
|
||||
host = hosts[0] if isinstance(hosts, list) and hosts else "127.0.0.1"
|
||||
host = hosts[0] if isinstance(hosts, list) and hosts else _extract_host(str(data.get("webrtcAddress", ":8889")), current_webrtc_host)
|
||||
|
||||
path_defaults = data.get("pathDefaults") or {}
|
||||
record_enabled = bool(path_defaults.get("record", False))
|
||||
@@ -99,7 +136,7 @@ def _build_mediamtx_view(data: dict) -> MediaMTXConfigView:
|
||||
cameras.sort(key=lambda x: x.name)
|
||||
|
||||
return MediaMTXConfigView(
|
||||
api_url=f"http://127.0.0.1:{api_port}",
|
||||
api_url=f"http://{api_host}:{api_port}",
|
||||
webrtc_url=f"http://{host}:{webrtc_port}",
|
||||
record_enabled=record_enabled,
|
||||
cameras=cameras,
|
||||
@@ -109,7 +146,7 @@ def _build_mediamtx_view(data: dict) -> MediaMTXConfigView:
|
||||
async def _sync_app_config_from_mediamtx() -> AppConfig:
|
||||
cfg = await store.load()
|
||||
data = _load_mediamtx_yml()
|
||||
view = _build_mediamtx_view(data)
|
||||
view = _build_mediamtx_view(data, cfg)
|
||||
|
||||
cfg.mediamtx_api_url = view.api_url
|
||||
cfg.mediamtx_webrtc_url = view.webrtc_url
|
||||
@@ -174,6 +211,17 @@ async def _scheduler_loop() -> None:
|
||||
try:
|
||||
cfg = await store.load()
|
||||
await scheduler.tick(cfg.schedule)
|
||||
except httpx.HTTPStatusError as e:
|
||||
code = e.response.status_code
|
||||
if code == 401:
|
||||
logger.warning(
|
||||
"scheduler_tick_unauthorized: MediaMTX API rejected credentials. "
|
||||
"Set mediamtx_api_user/mediamtx_api_pass in api/data/config.json"
|
||||
)
|
||||
else:
|
||||
logger.exception("scheduler_tick_http_status_%s", code)
|
||||
except httpx.HTTPError:
|
||||
logger.exception("scheduler_tick_http_error")
|
||||
except Exception:
|
||||
logger.exception("scheduler_tick_failed")
|
||||
finally:
|
||||
@@ -227,7 +275,7 @@ async def get_config() -> AppConfig:
|
||||
@app.get("/api/mediamtx/config")
|
||||
async def get_mediamtx_config() -> MediaMTXConfigView:
|
||||
data = _load_mediamtx_yml()
|
||||
view = _build_mediamtx_view(data)
|
||||
view = _build_mediamtx_view(data, await store.load())
|
||||
await _sync_app_config_from_mediamtx()
|
||||
return view
|
||||
|
||||
@@ -247,7 +295,7 @@ async def add_mediamtx_camera(payload: MediaMTXAddCameraRequest) -> MediaMTXConf
|
||||
paths[name] = {"source": payload.rtsp_url.strip()}
|
||||
_save_mediamtx_yml(data)
|
||||
await _sync_app_config_from_mediamtx()
|
||||
return _build_mediamtx_view(data)
|
||||
return _build_mediamtx_view(data, await store.load())
|
||||
|
||||
|
||||
@app.delete("/api/mediamtx/cameras/{name}")
|
||||
@@ -260,7 +308,7 @@ async def delete_mediamtx_camera(name: str) -> MediaMTXConfigView:
|
||||
data["paths"] = paths
|
||||
_save_mediamtx_yml(data)
|
||||
await _sync_app_config_from_mediamtx()
|
||||
return _build_mediamtx_view(data)
|
||||
return _build_mediamtx_view(data, await store.load())
|
||||
|
||||
|
||||
@app.post("/api/mediamtx/recording")
|
||||
@@ -272,7 +320,7 @@ async def set_mediamtx_recording(data: RecordingToggle) -> MediaMTXConfigView:
|
||||
path_defaults["record"] = bool(data.enabled)
|
||||
payload["pathDefaults"] = path_defaults
|
||||
_save_mediamtx_yml(payload)
|
||||
return _build_mediamtx_view(payload)
|
||||
return _build_mediamtx_view(payload, await store.load())
|
||||
|
||||
|
||||
@app.post("/api/mediamtx/restart")
|
||||
|
||||
Reference in New Issue
Block a user