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