fix hls
This commit is contained in:
@@ -89,12 +89,10 @@ POSTGRES_PORT=45432
|
||||
# 链路 2(模拟实时)与链路 3(离线 batch)需开启;链路 1 真 RTSP 开录不依赖此项
|
||||
# DEMO_ORCHESTRATOR_ENABLED=false
|
||||
# DEMO_ORCHESTRATOR_RTSP_PORT=18554
|
||||
# 联调台 HLS 预览(推荐 Compose 侧车 mediamtx-hls,API 只反代)
|
||||
# DEMO_HLS_PREVIEW_UPSTREAM=http://mediamtx-hls:8888
|
||||
# DEMO_HLS_PREVIEW_CONFIG_DIR=/hls-preview-config
|
||||
# 本机无 Compose 时:留空 upstream,临时 docker 容器 + 端口 18888
|
||||
# 联调台 HLS(Compose:先 docker compose up -d mediamtx-hls api)
|
||||
# DEMO_HLS_PREVIEW_UPSTREAM=http://127.0.0.1:18888
|
||||
# 本机 uvicorn 且无 mediamtx-hls 侧车时改为:DEMO_HLS_PREVIEW_UPSTREAM=ephemeral
|
||||
# DEMO_HLS_PREVIEW_PORT=18888
|
||||
# DEMO_HLS_PREVIEW_HOST=127.0.0.1
|
||||
# Docker 内 API 访问宿主机假流时写入站点 JSON 的主机名(默认 host.docker.internal)
|
||||
# DOCKER_DEMO_ORCHESTRATOR_RTSP_JSON_HOST=host.docker.internal
|
||||
# 链路 2 simulated-start / fake_rtsp_from_file 起 MediaMTX 容器用
|
||||
|
||||
@@ -158,7 +158,15 @@ async def recording_modes_status() -> dict:
|
||||
"orchestrator_rtsp_port": settings.demo_orchestrator_rtsp_port,
|
||||
"orchestrator_rtsp_json_host": settings.demo_orchestrator_rtsp_json_host,
|
||||
"hls_preview_port": settings.demo_hls_preview_port,
|
||||
"hls_preview_upstream": (settings.demo_hls_preview_upstream or "").strip() or None,
|
||||
"hls_preview_upstream": HlsPreviewManager.resolve_upstream_setting(
|
||||
settings.demo_hls_preview_upstream
|
||||
)
|
||||
or None,
|
||||
"hls_preview_mode": (
|
||||
"attached"
|
||||
if HlsPreviewManager.resolve_upstream_setting(settings.demo_hls_preview_upstream)
|
||||
else "ephemeral"
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
@@ -212,7 +220,7 @@ async def hls_preview_ensure(
|
||||
detail="OR_SITE_CONFIG_JSON_FILE is not set",
|
||||
)
|
||||
hls_port = int(settings.demo_hls_preview_port)
|
||||
upstream_url = (settings.demo_hls_preview_upstream or "").strip()
|
||||
upstream_url = settings.demo_hls_preview_upstream
|
||||
|
||||
resolver = BackendResolver(settings, hikvision_runtime=None)
|
||||
sources: dict[str, str] = {}
|
||||
@@ -247,9 +255,16 @@ async def hls_preview_ensure(
|
||||
await asyncio.to_thread(_start)
|
||||
except Exception as exc:
|
||||
logger.exception("HLS preview start failed: {}", exc)
|
||||
detail = f"HLS preview start failed: {exc}"
|
||||
if "host.docker.internal" in str(exc) and "Invalid ip address" in str(exc):
|
||||
detail += (
|
||||
"。当前 API 可能仍是旧版本:请执行 "
|
||||
"`docker compose up -d --build api mediamtx-hls`,并确认 "
|
||||
"DEMO_HLS_PREVIEW_UPSTREAM=http://127.0.0.1:18888(勿把 host.docker.internal 用于 docker -p)。"
|
||||
)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail=f"HLS preview start failed: {exc}",
|
||||
detail=detail,
|
||||
) from exc
|
||||
|
||||
sess = HlsPreviewManager.active()
|
||||
|
||||
@@ -189,10 +189,10 @@ class Settings(BaseSettings):
|
||||
demo_orchestrator_rtsp_json_host: str = "host.docker.internal"
|
||||
demo_hls_preview_port: int = Field(default=18888, ge=1, le=65535)
|
||||
demo_hls_preview_upstream: str = Field(
|
||||
default="",
|
||||
default="http://127.0.0.1:18888",
|
||||
description=(
|
||||
"推荐:Compose 内 MediaMTX 基址,如 http://mediamtx-hls:8888。"
|
||||
"设此项后 API 不再 docker run -p,只写配置并重启 mediamtx-hls。"
|
||||
"MediaMTX HLS 基址(Compose 侧车默认 127.0.0.1:18888)。"
|
||||
"设为 ephemeral 则改回临时 docker run(本机开发)。"
|
||||
),
|
||||
)
|
||||
demo_hls_preview_config_dir: str = Field(
|
||||
|
||||
@@ -151,6 +151,14 @@ class HlsPreviewManager:
|
||||
shutil.rmtree(sess.config_dir, ignore_errors=True)
|
||||
cls._active = None
|
||||
|
||||
@classmethod
|
||||
def resolve_upstream_setting(cls, upstream_url: str) -> str:
|
||||
"""``ephemeral`` / 空 → 临时容器;否则走 Compose 侧车(写配置 + restart)。"""
|
||||
raw = (upstream_url or "").strip()
|
||||
if raw.lower() in ("ephemeral", "none", "off"):
|
||||
return ""
|
||||
return raw
|
||||
|
||||
@classmethod
|
||||
def start(
|
||||
cls,
|
||||
@@ -163,10 +171,11 @@ class HlsPreviewManager:
|
||||
ephemeral_port: int = 18888,
|
||||
ready_timeout_sec: float = 30.0,
|
||||
) -> HlsPreviewSession:
|
||||
if (upstream_url or "").strip():
|
||||
resolved = cls.resolve_upstream_setting(upstream_url)
|
||||
if resolved:
|
||||
return cls._start_attached(
|
||||
sources=sources,
|
||||
upstream_url=upstream_url.strip(),
|
||||
upstream_url=resolved,
|
||||
config_dir=config_dir,
|
||||
container_name=attached_container_name,
|
||||
ready_timeout_sec=ready_timeout_sec,
|
||||
|
||||
@@ -44,6 +44,13 @@ def test_docker_publish_bind_host_maps_docker_internal() -> None:
|
||||
assert docker_publish_bind_host("127.0.0.1") == "127.0.0.1"
|
||||
|
||||
|
||||
def test_resolve_upstream_setting() -> None:
|
||||
assert HlsPreviewManager.resolve_upstream_setting("http://127.0.0.1:18888") == (
|
||||
"http://127.0.0.1:18888"
|
||||
)
|
||||
assert HlsPreviewManager.resolve_upstream_setting("ephemeral") == ""
|
||||
|
||||
|
||||
def test_hls_preview_ensure_pull(hls_client: TestClient) -> None:
|
||||
fake_sess = HlsPreviewSession(
|
||||
upstream_base="http://127.0.0.1:18888",
|
||||
|
||||
Reference in New Issue
Block a user