/** * 将 HTTP API 根地址转为 WebSocket 根(用于 /android/scrcpy/ws)。 * next dev:HTTP 可走 middleware rewrite,但 WebSocket 升级通常不会转发,故在常见 dev 端口直连 uvicorn(与 middleware API_PROXY_TARGET 默认一致)。 */ const DEFAULT_DEV_API_PORT = "8001"; export function httpApiBaseToWsBase(apiBase: string): string { if (typeof window === "undefined") return `ws://127.0.0.1:${DEFAULT_DEV_API_PORT}`; const base = (apiBase || "").trim(); if (base) { try { const u = new URL(base, window.location.href); const proto = u.protocol === "https:" ? "wss:" : "ws:"; return `${proto}//${u.host}`; } catch { /* ignore */ } } const pub = typeof process !== "undefined" && process.env.NEXT_PUBLIC_API_URL ? String(process.env.NEXT_PUBLIC_API_URL).trim() : ""; if (pub) { try { const u = new URL(pub, window.location.href); const proto = u.protocol === "https:" ? "wss:" : "ws:"; return `${proto}//${u.host}`; } catch { /* ignore */ } } const port = window.location.port; if (port === "3000" || port === "3001") { const h = window.location.hostname || "127.0.0.1"; return `ws://${h}:${DEFAULT_DEV_API_PORT}`; } const { protocol, host } = window.location; const proto = protocol === "https:" ? "wss:" : "ws:"; return `${proto}//${host}`; } export function androidScrcpyWsUrl(apiBase: string, serial: string, maxSize = 1920): string { const root = httpApiBaseToWsBase(apiBase).replace(/\/$/, ""); const q = new URLSearchParams({ serial, max_size: String(maxSize) }); return `${root}/android/scrcpy/ws?${q.toString()}`; }