Add mobile microphone HTTPS hints and Permissions-Policy header.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-12 15:11:31 +08:00
parent 90e77f8f70
commit 984f2e03a4
2 changed files with 92 additions and 2 deletions
+52
View File
@@ -289,11 +289,28 @@ PWA_HEAD = """
return;
}
btn.style.display = "inline-flex";
// 非 HTTPS 时标记页面,用于显示麦克风提示
if (!isSecure()) {
document.documentElement.classList.add("insecure-context");
}
});
})();
</script>
"""
MIC_HINT_HTML = """
<div class="mic-hint">
<strong>📱 手机 / 平板录音说明</strong>
<ul>
<li><strong>HTTPS 域名</strong>访问才能使用麦克风(HTTP 内网 IP 仅支持上传文件)</li>
<li>iOS 请用 <strong>Safari</strong> 打开,微信内置浏览器通常无法录音</li>
<li>首次使用请允许浏览器的「麦克风」权限</li>
<li>穿透方案见 <code>PWA_NPS.md</code></li>
</ul>
</div>
"""
INSTALL_APP_BUTTON_HTML = """
<button id="pwa-install-btn" class="pwa-install-btn" type="button" title="安装到手机/平板/电脑桌面">
<img src="/pwa/icons/install.svg" alt="" class="pwa-install-icon" width="28" height="28"/>
@@ -719,6 +736,31 @@ gradio-app,
}
footer { visibility: hidden; }
/* 手机端麦克风提示(HTTP 下强制显示) */
.mic-hint {
display: none;
background: #1e3a5f !important;
border: 1px solid #3b82f6 !important;
border-radius: 10px !important;
padding: 12px 16px !important;
margin: 8px 0 14px 0 !important;
color: #dbeafe !important;
font-size: 0.9rem !important;
line-height: 1.6 !important;
}
.mic-hint strong { color: #ffffff !important; }
.mic-hint ul { margin: 8px 0 0 0 !important; padding-left: 20px !important; }
.mic-hint code {
background: #0f172a !important;
color: #93c5fd !important;
padding: 2px 6px !important;
border-radius: 4px !important;
}
@media (max-width: 1024px) {
.mic-hint { display: block; }
}
html.insecure-context .mic-hint { display: block !important; }
"""
@@ -843,6 +885,7 @@ def build_app() -> gr.Blocks:
with gr.Tabs():
# ---- Tab 1: 音色锁定 ----
with gr.Tab("🎙️ 音色锁定"):
gr.HTML(MIC_HINT_HTML)
gr.HTML(
f'<div class="hint-box">'
f'上传 <strong>10-30 秒</strong> 干净人声样本,系统将提取 Speaker Embedding '
@@ -873,6 +916,7 @@ def build_app() -> gr.Blocks:
# ---- Tab 2: 分步操作 ----
with gr.Tab("🔧 分步流水线"):
gr.HTML(MIC_HINT_HTML)
with gr.Row(elem_classes=["pipeline-steps"]):
with gr.Column(scale=1):
gr.Markdown("### Step 1 · 音频极速识别")
@@ -911,6 +955,7 @@ def build_app() -> gr.Blocks:
# ---- Tab 3: 一键生产 ----
with gr.Tab("🚀 一键生产"):
gr.HTML(MIC_HINT_HTML)
gr.Markdown(
"上传碎碎念录音,系统自动完成 **识别 → 润色 → 合成** 全流程。"
)
@@ -953,6 +998,13 @@ def create_fastapi_app():
fastapi_app = FastAPI(title="Trading Studio", docs_url=None, redoc_url=None)
@fastapi_app.middleware("http")
async def add_media_permissions(request, call_next):
"""允许浏览器在 HTTPS 下请求麦克风(配合云反代使用)。"""
response = await call_next(request)
response.headers["Permissions-Policy"] = "microphone=(self), camera=(self)"
return response
if PWA_DIR.is_dir():
fastapi_app.mount("/pwa", StaticFiles(directory=str(PWA_DIR)), name="pwa")