This commit is contained in:
eric
2026-03-29 03:08:07 -05:00
parent fbdcf4cc73
commit 895dafc0e0
2 changed files with 39 additions and 6 deletions

View File

@@ -142,6 +142,13 @@ type Props = {
const SCRCPY_URL = "https://github.com/Genymobile/scrcpy";
const ESCRCPY_URL = "https://github.com/viarotel-org/escrcpy";
/** 与 LiveControlApp 一致:apiBase 为空时用根相对路径(同域 FastAPI 托管静态页)。 */
function apiUrl(apiBase: string, path: string): string {
const p = path.startsWith("/") ? path : `/${path}`;
const b = (apiBase || "").trim().replace(/\/$/, "");
return b ? `${b}${p}` : p;
}
export function LiveAndroidStreamConsole({
t,
apiBase,
@@ -188,10 +195,9 @@ export function LiveAndroidStreamConsole({
const activeTransport = devices.find((d) => d.serial === serial)?.transport;
const useFastShot = liveMs > 0;
const shotUrl =
apiBase && serial
? `${apiBase}/android/screenshot?serial=${encodeURIComponent(serial)}&ts=${frameTs}${useFastShot ? "&fast=1" : ""}`
: "";
const shotUrl = serial
? `${apiUrl(apiBase, "/android/screenshot")}?serial=${encodeURIComponent(serial)}&ts=${frameTs}${useFastShot ? "&fast=1" : ""}`
: "";
const bumpFrame = useCallback(() => {
setFrameTs((n) => n + 1);
@@ -230,7 +236,9 @@ export function LiveAndroidStreamConsole({
let cancelled = false;
void (async () => {
try {
const res = await fetch(`${apiBase}/android/display_metrics?serial=${encodeURIComponent(serial)}`);
const res = await fetch(
`${apiUrl(apiBase, "/android/display_metrics")}?serial=${encodeURIComponent(serial)}`,
);
const data = (await res.json()) as { width?: number; height?: number };
if (!res.ok || cancelled) return;
if (typeof data.width === "number" && typeof data.height === "number") {
@@ -259,7 +267,7 @@ export function LiveAndroidStreamConsole({
let cancelled = false;
void (async () => {
try {
const res = await fetch(`${apiBase}/android/scrcpy/info`);
const res = await fetch(apiUrl(apiBase, "/android/scrcpy/info"));
const data = (await res.json()) as {
server_jar?: boolean;
adb_ok?: boolean;

25
web.py
View File

@@ -216,6 +216,28 @@ def _pro_script_head(pm2: str) -> Optional[str]:
return head.lower() if head else None
def _resolve_pro_style_script(head_l: str) -> Optional[str]:
"""多频道 / Electron 风格 PM2 名前缀(如 youtube2__、tiktok_live__)映射到仓库内脚本。
不能仅用 stem 相等判断:youtube2 != youtube.py 的 stem「youtube」。
"""
if not head_l:
return None
h = head_l.lower()
py_scripts = [p["script"] for p in PROCESS_MONITOR if str(p.get("script", "")).endswith(".py")]
matches: list[str] = []
if h.startswith("douyin_youtube"):
matches = [s for s in py_scripts if Path(s).stem.lower().startswith("douyin_youtube")]
elif h.startswith("youtube"):
matches = [s for s in py_scripts if Path(s).stem.lower().startswith("youtube")]
elif h.startswith("tiktok"):
matches = [s for s in py_scripts if Path(s).stem.lower().startswith("tiktok")]
if not matches:
return None
matches.sort(key=lambda s: (len(Path(s).stem), s))
return matches[0]
def script_for_pm2_or_pro(pm2: str) -> Optional[str]:
s = script_for_pm2(pm2)
if s:
@@ -223,6 +245,9 @@ def script_for_pm2_or_pro(pm2: str) -> Optional[str]:
head_l = _pro_script_head(pm2)
if not head_l:
return None
resolved = _resolve_pro_style_script(head_l)
if resolved:
return resolved
for p in PROCESS_MONITOR:
if Path(p["script"]).stem.lower() == head_l:
return p["script"]