Files
gitlab-instance-0a899031_d2…/web2_youtube_diagnostics.py
eric d61526698d 重构无人直播助手:内嵌 youLIVE、摄像头直推、推流诊断与 UI 焕新
将 README 改写为产品文档;移除微信/EasyTier/工作台等遗留模块;新增 youLIVE 目标端监控、摄像头推流、质量守卫与转播历史能力。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 20:50:44 -05:00

106 lines
3.4 KiB
Python

"""YouTube relay diagnostics: source + FFmpeg + target watch URL layers."""
from __future__ import annotations
import time
from typing import Any
from web2_quality_guard import build_youtube_quality_guard_report, parse_ffmpeg_metrics
def _source_configured(url_lines: str) -> bool:
for raw in str(url_lines or "").splitlines():
t = raw.strip()
if not t or t.startswith("#"):
continue
if "douyin" in t.lower() or "live.douyin.com" in t.lower():
return True
return False
def build_youtube_diagnostics_report(
rows: list[dict[str, Any]],
*,
config_by_process: dict[str, dict[str, str]] | None = None,
) -> dict[str, Any]:
config_by_process = config_by_process or {}
guard = build_youtube_quality_guard_report(rows, config_by_process=config_by_process)
lanes: list[dict[str, Any]] = []
target_ok = 0
source_ok = 0
ffmpeg_ok = 0
for lane in guard.get("lanes") or []:
proc = str(lane.get("process") or "")
cfg = config_by_process.get(proc) or {}
watch = str(cfg.get("watch_url") or "").strip()
src_cfg = _source_configured(cfg.get("url_lines", ""))
pushing = bool(lane.get("is_pushing"))
metrics = lane.get("metrics") if isinstance(lane.get("metrics"), dict) else {}
if not metrics and pushing:
metrics = parse_ffmpeg_metrics(
str((rows[0] if rows else {}).get("recent_log") or ""),
)
issues = list(lane.get("issues") or [])
score = int(lane.get("score") or 0)
if src_cfg:
source_ok += 1
else:
issues.append({"level": "warning", "text": "源站地址未配置"})
score = max(0, score - 12)
if watch:
target_ok += 1
else:
issues.append({"level": "warning", "text": "未配置 YouTube 目标监听地址"})
score = max(0, score - 8)
ffmpeg_active = bool(lane.get("ffmpeg_active"))
if pushing and ffmpeg_active:
ffmpeg_ok += 1
elif pushing and not ffmpeg_active:
issues.append({"level": "critical", "text": "推流中但未检测到 FFmpeg 进程"})
lanes.append(
{
**lane,
"score": max(0, min(100, score)),
"issues": issues[:8],
"layers": {
"source": {
"ok": src_cfg,
"hint": lane.get("source_url") or "",
},
"ffmpeg": {
"ok": ffmpeg_active or not pushing,
"pushing": pushing,
"metrics": metrics,
},
"target": {
"ok": bool(watch),
"watch_url": watch,
},
},
}
)
lane_count = len(lanes)
overall = int(sum(l["score"] for l in lanes) / lane_count) if lane_count else 0
return {
**guard,
"score": max(0, min(100, overall)),
"lanes": lanes,
"diagnostics": {
"generated_at": time.time(),
"layers": ["source", "ffmpeg", "target"],
"summary": {
"lanes": lane_count,
"source_configured": source_ok,
"target_configured": target_ok,
"ffmpeg_active": ffmpeg_ok,
},
},
}