refactor: 移除自签名证书方案,服务只跑 HTTP
麦克风安全上下文改由部署方案解决:本机用 localhost, 对外部署挂 HTTPS 反向代理。删除 certs/、gen-cert.sh、 /cert 路由与 HTTPS server 分支,文档同步更新。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
18
CLAUDE.md
18
CLAUDE.md
@@ -11,15 +11,12 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
# 新电脑一键部署(幂等:装依赖 → 补模型 → 生成证书 → 启动,见 DEPLOY.md)
|
||||
# 新电脑一键部署(幂等:装依赖 → 补模型 → 启动,见 DEPLOY.md)
|
||||
bash bootstrap.sh
|
||||
|
||||
# 启动(HTTP:8000 + HTTPS:8443,首次自动生成自签证书)
|
||||
# 启动(HTTP:8000;麦克风需安全上下文:本机 localhost 或部署时挂 HTTPS 反向代理)
|
||||
bash start.sh # 或 node server.js
|
||||
|
||||
# 换电脑 / IP 变了后重新生成自签名证书
|
||||
bash gen-cert.sh
|
||||
|
||||
# 语法检查(无测试框架,改完用这个自查)
|
||||
node -e "new (require('vm').Script)(require('fs').readFileSync('server.js','utf8'));console.log('server ok')"
|
||||
node -e "const m=require('fs').readFileSync('index.html','utf8').match(/<script>([\s\S]*?)<\/script>/)[1];new (require('vm').Script)(m);console.log('frontend ok')"
|
||||
@@ -50,9 +47,9 @@ VOICES=Tingting,Shelley node eval.js # 多音色
|
||||
|
||||
## Architecture
|
||||
|
||||
### 后端 `server.js`(纯 Node `http`/`https`,无框架无依赖)
|
||||
- 同一个 `handler(req,res)` 同时挂在 HTTP(8000) 和 HTTPS(8443) 上。HTTPS 用 `certs/` 里的自签证书,缺证书则只起 HTTP。
|
||||
- 路由:`GET /`(index.html)、`GET /cert`(iOS 下载证书)、`GET /health`、`POST /stt`。
|
||||
### 后端 `server.js`(纯 Node `http`,无框架无依赖)
|
||||
- 单个 `handler(req,res)` 挂在 HTTP(8000)。不做 HTTPS——本机用 `localhost`(安全上下文),对外部署挂 HTTPS 反向代理。
|
||||
- 路由:`GET /`(index.html)、`GET /health`、`POST /stt`。
|
||||
- `POST /stt?a=&b=` 流水线(`transcribe()`):收原始 body Buffer → 按 `Content-Type` 定扩展名写临时文件 → `ffmpeg` 转 wav(前后各补 0.5s 静音,短音节必需)→ `whisper-cli -l zh` 语法约束解码输出 txt → 去标点/空白 → 返回 `{text}`。**前端只拿 `text`,判分在前端做**,后端不碰口诀逻辑。
|
||||
- **grammar 约束解码是识别准确率的命根子**:带 `a`/`b` 参数时用 `dynGrammar()` 按题生成 grammar(前缀锁死为本题因数、得数全开放——只约束前缀不会把答错扶正);否则退回静态 `grammar/number.gbnf`;没有 grammar 文件才用 `--prompt` 偏置。grammar 只允许中文数字输出——阿拉伯数字会把「十四/七十四」压扁成 14/74 丢掉「十」。grammar 另含发音兼容 `alias` 规则(牛/流/柳/溜/两/酒):不给别名时方言音会被硬扭到错误数字(如 niú 声学上更近 jiǔ「九」),给别名让解码器输出真实音、前端 `DIG` 映射回数字。
|
||||
|
||||
@@ -71,6 +68,5 @@ VOICES=Tingting,Shelley node eval.js # 多音色
|
||||
|
||||
## 平台约束(重要,别踩坑)
|
||||
|
||||
- **iOS 语音必须 HTTPS + 受信任证书**。iOS 上所有浏览器都是 WebKit,`http://IP` 下苹果直接禁麦克风、不弹授权;且浏览器自带的 `SpeechRecognition` 在 iOS 基本不可用 —— 这正是要走「录音上传后端识别」而非浏览器识别的原因。iOS 首次需下载 `/cert` 并在「设置 → 通用 → 证书信任设置」里开完全信任,详见 `README.md`。
|
||||
- **音频/麦克风/TTS 必须在用户手势内解锁**:`ensureAudio()` 在首页点「开始」(`startGame`)时调用一次 `getUserMedia` + `AudioContext.resume()` + 静音 TTS,之后才能全自动。
|
||||
- 证书 SAN 里写死了本机 LAN IP;IP 变了必须 `gen-cert.sh` 重新生成。
|
||||
- **麦克风只在安全上下文可用**(浏览器硬限制):本机开发/运行用 `http://localhost:8000`;对外部署把服务挂在支持 HTTPS 的反向代理后面(项目自身不做 TLS)。浏览器自带的 `SpeechRecognition` 兼容性差——这正是走「录音上传后端识别」而非浏览器识别的原因。
|
||||
- **音频/麦克风/TTS 必须在用户手势内解锁**:`ensureAudio()` 在首页点「开始」(`startGame`/`enterMatch`)时调用一次 `getUserMedia` + `AudioContext.resume()` + 静音 TTS,之后才能全自动。
|
||||
|
||||
Reference in New Issue
Block a user