's'
This commit is contained in:
@@ -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
25
web.py
@@ -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"]
|
||||
|
||||
Reference in New Issue
Block a user