|
|
vor 4 Wochen | |
|---|---|---|
| deploy | vor 4 Wochen | |
| src | vor 4 Wochen | |
| test | vor 4 Wochen | |
| .dockerignore | vor 1 Monat | |
| .env.example | vor 4 Wochen | |
| .gitignore | vor 1 Monat | |
| Dockerfile | vor 1 Monat | |
| README.md | vor 4 Wochen | |
| openapi.yaml | vor 4 Wochen | |
| package-lock.json | vor 4 Wochen | |
| package.json | vor 4 Wochen |
yuban-server 是自传语伴新增业务能力的独立 Node.js 服务。它承载旧服务器尚未实现的长录音异步转写,并可在严格校验用户访问权限后提交权威逐字稿。
首个能力是“历史长录音异步转写”:浏览器提交旧对象存储中的录音 URL,新服务临时下载并转为 16kHz 单声道 PCM WAV,调用讯飞 IST,最后返回完整正文和说话人分段。生产启用权威落库后,服务会先写入并回读校验 ChatVoice;浏览器写入只作为兼容性兜底。
ChatVoice。ChatSession、Article、会员或订单等其他业务表。/users/me 校验现有 Session Token;不会实现第二套用户系统。默认每个用户最多同时运行 2 个任务、保留 20 个临时任务,避免合法账号误触发任务风暴。
sequenceDiagram
participant Web as Angular 前端
participant Old as 旧服务器 / Parse
participant New as yuban-server
participant OSS as 对象存储
participant ASR as 讯飞 IST
Web->>Old: 读取 ChatVoice.audioUrl
Web->>New: POST /recording-transcription/jobs
New->>Old: /users/me 校验 Session Token
New-->>Web: 202 + jobId
New->>OSS: 临时下载录音
New->>New: ffmpeg 转码
New->>ASR: 提交并轮询转写
Web->>New: GET /recording-transcription/jobs/:jobId
New-->>Web: 完整 text + segments + SHA-256
New->>Old: 写入并回读校验 ChatVoice 权威逐字稿
Web->>Old: 兼容性回读/兜底保存
GET /health健康检查,不返回密钥或任务内容。
POST /recording-transcription/jobs创建异步任务,正常情况下立即返回 HTTP 202。
{
"audioUrl": "https://file.yuban.co/path/recording.mp3",
"chatVoiceId": "ChatVoice-object-id",
"durationMs": 3600000,
"roleType": 1,
"roleNum": 0,
"requestId": "chatVoice-object-id"
}
请求头:
Authorization: Bearer <现有 Parse Session Token>
Idempotency-Key: <ChatVoice objectId 或稳定请求 ID>
Content-Type: application/json
响应:
{
"success": true,
"reused": false,
"job": {
"id": "7d84a8db-4b55-43d8-b9f7-6d20d35c443f",
"status": "queued",
"stage": "queued",
"progress": 0,
"createdAt": "2026-08-05T09:00:00.000Z",
"updatedAt": "2026-08-05T09:00:00.000Z",
"heartbeatAt": null,
"expiresAt": "2026-08-06T09:00:00.000Z"
}
}
GET /recording-transcription/jobs/:jobId查询任务。completed 时增加:
{
"result": {
"text": "完整逐字稿……",
"segments": [
{
"text": "片段正文",
"startMs": 0,
"endMs": 1200,
"speakerId": "1"
}
],
"charCount": 15732,
"sha256": "..."
}
}
任务状态为 queued、running、retry_wait、completed、failed 或 cancelled。临时错误会进入 retry_wait 并由 Worker 自动重试。
POST /recording-transcription/jobs/:jobId/retry为已经 failed 或 cancelled 且仍保留源请求的任务创建新 jobId。新任务包含 parentJobId,不会继续查询已经失败的旧任务。
POST /recording-transcription/jobs/:jobId/cancel取消尚未完成的任务。讯飞侧可能已经收到音频,但新服务会停止继续轮询,也不会返回逐字稿。
完整契约见 openapi.yaml。
要求:Node.js 22+、ffmpeg、ffprobe。
cp .env.example .env
# 填写讯飞凭据和前端来源白名单
npm test
npm start
服务默认监听 http://127.0.0.1:3200(生产示例使用 0.0.0.0:3200)。本项目仅使用 Node 内置模块,不需要安装 npm 运行依赖。
开发环境若暂时不连接旧 Parse,可使用 NODE_ENV=development AUTH_MODE=disabled;生产环境会拒绝关闭认证。
推荐使用 Docker:
docker build -t yuban-server:1.1.0 .
docker run -d \
--name yuban-server \
--restart unless-stopped \
--env-file .env \
-p 127.0.0.1:3200:3200 \
-v yuban-server-jobs:/app/var/jobs \
yuban-server:1.1.0
deploy/nginx.conf.example 展示了 HTTPS 反向代理配置。不要让 Node 端口直接暴露到公网。生产环境至少要完成:
https://server.yuban.co;Node 端口只监听反向代理所在主机。把 CORS_ALLOWED_ORIGINS 限制为真实 Angular 域名(精确匹配,不要使用 *):
CORS_ALLOWED_ORIGINS=https://www.yuban.co,https://yuban.co,http://localhost:4200,http://127.0.0.1:4200
保持 ALLOWED_AUDIO_HOSTS=file.yuban.co 或更窄。
仅在服务器环境变量中保存讯飞密钥。
监控 /health、任务失败率、磁盘容量和 ffmpeg/ffprobe 可用性。
权威逐字稿服务端落库需要额外配置 CANONICAL_PERSISTENCE_ENABLED=true 和仅存在于服务器环境中的 PARSE_MASTER_KEY。创建任务时服务会先用用户 Session Token 校验 ChatVoice 访问权限,完成后才用服务凭据写入并回读 hash/字数。
只为历史长录音重转写配置新服务地址:
<script>
window.__YUBAN_RUNTIME_CONFIG__ = {
...(window.__YUBAN_RUNTIME_CONFIG__ || {}),
recordingTranscriptionBusinessApiBaseUrl: 'https://server.yuban.co'
};
</script>
旧服务器地址不需要更改。实时录音、已有长语音上传、数据保存、故事生成等现有链路仍走原接口。