Files
story/device-simulator-windows/README.md
T
2026-08-29 21:56:51 +08:00

48 lines
3.7 KiB
Markdown

# Windows 语音终端模拟器
该程序使用Electron和火山引擎Web RTC SDK模拟一台真实语音终端。它采集Windows麦克风、加入平台分配的RTC房间、发布本地音频、订阅并播放豆包智能体音频,并通过设备v2接口完成激活、状态等待、心跳、Token续签和结束通话。进房后还会启动RTC实时字幕,收集长者与智能体的最终话轮并通过现有`turns:batch`设备接口可靠上传;字幕未成功启动时拒绝继续激活通话,避免生成没有聊天记录的完成通话。
创建通话返回的隐私策略允许原录音时,模拟器同时通过RTC原始音频帧回调采集长者`near`和智能体`far`轨道。结束通话后自动封装为单声道WAV PCM16、按平台限制分片、申请短期对象地址直传,并等待后台完整性与容器校验完成。家庭工作台的通话记录会标记“可听聊天语音”,获得独立PLAY授权的账号可在详情中选择“听长者语音”或“听智能体语音”。
## 构建
```powershell
Set-Location .\device-simulator-windows
npm install
npm run build
```
输出:`release/voice-device-simulator-0.1.0-windows-x64.exe`。
连接公网测试服务器时,可以直接双击EXE,也可以使用`launch-cloud-device.ps1`启动。Electron主进程优先读取启动脚本传入的临时环境变量,否则从当前Windows用户的`%LOCALAPPDATA%\DataTerminalVoiceDevice\server-device-secret`读取设备签名密钥。密钥不写入源码、安装包或浏览器存储,也不会回传到渲染进程;输入框留空并显示“已从Windows安全凭据文件加载”即表示可直接检测。
## 自动连续性验证
本地回归时可让模拟器自动启动通话、播放一段测试音频,并把双方最终字幕写入JSON结果文件。该入口只接受本机文件和回环地址,不影响正常交互使用:
```powershell
$env:SIMULATOR_AUTO_TEST = '1'
$env:SIMULATOR_AUTOMATED_AUDIO_PATH = 'C:\path\to\question.wav'
$env:SIMULATOR_AUTO_RESULT_PATH = 'C:\path\to\result.json'
& .\release\voice-device-simulator-0.1.0-windows-x64.exe
```
测试会等待长者与智能体的最终字幕,结束通话后退出;结果文件包含通话ID、最终话轮和通过/失败状态。测试音频支持WAV、MP3和OGG,大小不得超过10 MB。
## 安全边界
- RTC AppKey、火山AK/SK和豆包Access Token只存在本地后端的受保护文件中;
- 模拟器安装包只接收平台签发的短期RTC Token;
- 设备签名密钥只驻留Electron主进程内存,不写入浏览器存储;
- 当前测试构建只允许设备API地址指向`localhost`、`127.0.0.1`或固定测试服务器`https://121.41.46.238`,避免误连其他环境;
- 关闭软件或结束通话时停止音频采集并销毁RTC引擎。
- 未取得`record_near`或`record_far`授权的轨道不会注册PCM回调;`upload_allowed=false`时不会采集或上传任何原录音。
## 实时字幕前提
测试所用RTC AppID必须在火山RTC控制台开启“实时字幕”和“流式语音识别”。流式语音识别凭据来自豆包语音控制台创建的“流式语音识别”应用,包括APP ID、Access Token和Cluster ID;“音视频字幕生成”类型不能替代该应用。未开通时程序会显示`ServiceAccessDenied`并清理本次未激活通话。
最终字幕会在程序的“实时字幕与上传”区域显示。每条最终字幕使用通话内稳定键和严格递增序号上传;网络失败时留在内存队列,并在心跳及结束通话前重试。存在未上传字幕时,程序不会结束并丢弃当前通话。
完整本地启动顺序见[本地真实RTC联调说明](../deploy/local-rtc/README.md)。