yuban-server 是自传语伴新增业务能力的独立 Node.js 服务。它只承载旧服务器尚未实现、且不负责正式数据读写的业务接口。
首个能力是“历史长录音异步转写”:浏览器提交旧对象存储中的录音 URL,新服务临时下载并转为 16kHz 单声道 PCM WAV,调用讯飞 IST,最后返回完整正文和说话人分段。浏览器再通过原有 server.fmode.cn/Parse 接口把结果保存到 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
Web->>Old: 使用原接口保存 ChatVoice 权威逐字稿
GET /health健康检查,不返回密钥或任务内容。
POST /recording-transcription/jobs创建异步任务,正常情况下立即返回 HTTP 202。
{
"audioUrl": "https://file.yuban.co/path/recording.mp3",
"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、completed、failed 或 cancelled;阶段为 queued、downloading、transcoding、submitting、transcribing、completed、failed、cancelled。
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.0.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.0.0
deploy/nginx.conf.example 展示了 HTTPS 反向代理配置。不要让 Node 端口直接暴露到公网。生产环境至少要完成:
business-api.yuban.co。把 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 可用性。
只为历史长录音重转写配置新服务地址:
<script>
window.__YUBAN_RUNTIME_CONFIG__ = {
...(window.__YUBAN_RUNTIME_CONFIG__ || {}),
recordingTranscriptionBusinessApiBaseUrl: 'https://business-api.yuban.co'
};
</script>
旧服务器地址不需要更改。实时录音、已有长语音上传、数据保存、故事生成等现有链路仍走原接口。