Skip to content

v0.1.4

Choose a tag to compare

@nancheung nancheung released this 06 Jun 02:25

本版本新增实时耗时分析面板,修复关键的录音异步竞态问题,进一步提升交互体验和调试能力。

✨ 新增功能

实时耗时分析面板

  • 完整的时延可视化

    • 在协议日志标签页下方新增专用的耗时分析面板
    • 可视化每轮语音交互的关键时间点:
      • 用户开始说话
      • 用户说完话(STT 完成)
      • 服务器进入说话状态(TTS 开始)
      • 服务器停止说话(对话完成)
  • 关键性能指标

    • 端到端延迟:用户开始说话到服务器开始回复的总耗时
    • 感知延迟(重点):用户说完话到服务器开始说话的等待时间
    • 毫秒级精度,实时更新
  • 便于诊断

    • 快速识别系统中的性能瓶颈
    • 对比不同模式下的交互延迟
    • 服务端性能基准对标

🐛 Bug 修复

修复关键的录音异步竞态问题

背景:聆听状态下服务器主动关闭连接后,麦克风仍持续采集、日志持续出现 ↑ BIN 二进制数据

根因分析

  • startRecording() 是异步函数,包含多个 await 点(getUserMediaaddModule
  • 连接关闭时 teardown() 调用 resetAudio()audioStatus 置为 idle
  • 此时 startRecording 中的 await 仍在进行中,refs 尚未赋值
  • stopRecording() 发现 refs 为空,无可清理直接返回
  • 当 await 完成后,startRecording 继续执行,将 MediaStream 和 AudioWorklet 接好并启动
  • 结果:audioStatus 已为 idle 但仍在持续录音,worklet 不停地写 ↑ BIN 日志

解决方案:引入录音会话代号(epoch)机制

  • startRecording() 领取会话号,在每个 await 后校验会话是否仍有效
  • 若会话失效(epoch 已更新),则立即释放刚获取的麦克风轨道 / AudioContext 并退出,绝不接线 worklet
  • stopRecording() 递增会话号,使任一进行中的启动作废
  • 保证了 worklet 启动的原子性和正确性

📊 性能与诊断

  • 实时可见的系统端到端延迟,便于服务端性能对标
  • 精细化的时间点记录,有助于识别语音处理链路中的瓶颈
  • 支持多轮交互累积数据,便于性能趋势分析

🧪 质量保证

  • 新增 LatencyChartLatencyPanel 单元测试
  • 新增 latencySlice 单元测试(时间点记录、时差计算)
  • 新增 useAudio 竞态回归测试(确保 epoch 机制正确)
  • 所有 TypeScript 编译通过,无类型错误