This commit is contained in:
eric
2026-03-29 02:14:17 -05:00
parent c3ee09674f
commit 16dc9abbbb
8 changed files with 355 additions and 36 deletions

49
web.py
View File

@@ -148,6 +148,43 @@ def is_tiktok_script(script: str) -> bool:
return script.endswith(".py") and _stem(script).startswith("tiktok")
def _script_targets_hdmi_sink(script: str) -> bool:
"""与采集卡/板端 HDMI 输出争用同一物理链路的进程(互斥;与 YouTube RTMP 推流无关)。"""
if is_tiktok_script(script):
return True
s = _stem(script).lower()
return script.endswith(".sh") and s.startswith("obs")
async def _stop_other_hdmi_sink_processes(keep_pm2: str) -> list[str]:
sc_keep = script_for_pm2_or_pro(keep_pm2)
if not sc_keep or not _script_targets_hdmi_sink(sc_keep):
return []
await process_backend.ensure_mode()
stopped: list[str] = []
try:
online = await process_backend.online_process_names()
except Exception:
online = []
for name in online:
if name == keep_pm2:
continue
sc = script_for_pm2_or_pro(name)
if not sc or not _script_targets_hdmi_sink(sc):
continue
info = await get_process_info(name)
st = (info.get("process_status") or "").lower()
if st not in ("online", "running"):
continue
await process_backend.stop(name)
if not str(name).startswith("web"):
await force_kill_ffmpeg(str(name), BASE_DIR)
stopped.append(str(name))
if stopped:
await asyncio.sleep(0.85)
return stopped
def _build_process_monitor():
return tuple(
{
@@ -645,8 +682,12 @@ async def start(process: str = Query(..., description="进程名")):
sc = script_for_pm2_or_pro(process)
if not sc:
return JSONResponse({"output": "内部错误:找不到脚本映射"}, status_code=500)
stopped = await _stop_other_hdmi_sink_processes(process)
output = await process_backend.start(process, sc)
return JSONResponse({"output": output})
prefix = ""
if stopped:
prefix = "已停止其它占用 HDMI 链路的进程: " + "".join(stopped) + "\n"
return JSONResponse({"output": prefix + output})
@app.post("/start")
@@ -689,10 +730,14 @@ async def restart(process: str = Query(..., description="进程名")):
sc = script_for_pm2_or_pro(process)
if not sc:
return JSONResponse({"output": "内部错误:找不到脚本映射"}, status_code=500)
stopped = await _stop_other_hdmi_sink_processes(process)
output = await process_backend.restart(process, sc)
if not process.startswith("web"):
await force_kill_ffmpeg(process, BASE_DIR)
return JSONResponse({"output": output})
prefix = ""
if stopped:
prefix = "已停止其它占用 HDMI 链路的进程: " + "".join(stopped) + "\n"
return JSONResponse({"output": prefix + output})
@app.post("/restart")