fix wheplayer

This commit is contained in:
2026-04-28 17:24:26 +07:00
parent ecd9845e14
commit 8ad28090eb
5 changed files with 121 additions and 21 deletions
+56 -8
View File
@@ -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")