跳到正文
EN

接入与协议适配 ​

1. 职责与边界 ​

本模块负责连接与消息处理,将两种 WebSocket 协议转换为统一内部配置,组织音频收发、正常结束与异常退出,并提供 HTTP 路由。它调用缓冲、会话和转换模块,不实现模型算法。

主要源码:ws.py、protocol_detector.py、protocol_adapter.py、base.py、tools.py。完整消息与字段由语音转换 API 中文 / English维护。

2. 输入与输出 ​

边界输入输出
WebSocket 初始化首条 JSON 配置消息统一配置、Session、Buffer 和协议适配器;标准协议另发 ready
音频收发二进制 PCM 数据或原始 Opus 包转换后的单声道 int16 PCM 字节,无 WAV 头
连接结束协议结束消息、断联或超时正常路径发完成消息,退出路径执行清理
HTTP健康、版本或会话数据请求状态、版本或已保存会话数据;合同见系统 API与会话数据 API

3. 关键流程 ​

3.1 协议归一化与初始化 ​

/ 和 /ws 使用同一 WebSocket 处理函数。接受连接后,路由读取首条 JSON,由 ProtocolDetector 识别协议并创建适配器。

协议识别依据内部处理
简单协议signal = start将 stream_id、sample_bit 等映射到统一字段,使用内部 api_key 占位值,不发送 ready
标准协议type = config保留初始化字段,完成初始化后发送 ready

识别器对其他消息也返回标准适配器,路由随后检查归一化结果是否为配置消息。适配器还负责识别结束消息、格式化完成和错误消息。

路由校验配置类型、api_key 和单声道要求,随后从转换实例创建 Session,再按编码选择 PCM 或 Opus Buffer,并将 Session 绑定到 Buffer 用于事件记录。ready 按协议需要发送,连接计数在初始化末尾登记。

3.2 音频收发 ​

收到非空二进制消息后,路由调用 buffer.add_chunk(),再通过 has_complete_chunk() 循环消费可用的完整块。每次 process_chunk() 执行:

  1. 从 Buffer 取得浮点音频块。
  2. 调用 chunk_vc(numpy_chunk, session),从 session.out_data 取得结果。
  3. 将结果乘以 32768 并转换为 int16 字节,发送给客户端。
  4. 记录处理耗时和输出事件。

因此网络包边界与推理块边界不同。输入格式与块长度由音频缓冲解释,逐块算法由转换流水线解释。

3.3 正常结束与异常退出 ​

初始化后的每次 websocket.receive() 使用 app.receive_timeout;首条配置的 receive_json() 不在该超时包装内。

收到适配器识别的正常结束消息时,路由循环处理剩余缓冲,不足一块时由 Buffer 补齐,再发送该协议的完成消息并退出。完成响应当前不填充实际统计数据。

超时、断联和接收异常会退出收包流程,不执行上述正常结束的尾块处理。finally 尝试关闭连接、移除已登记连接、清空 Buffer,并为路由已持有的 Session 创建后台保存与清理任务。状态及资源释放见会话与状态管理。

3.4 HTTP 入口 ​

/health 返回固定健康状态,/version 返回包版本与构建日期。健康接口没有逐请求试运行模型的检查。

/tools/session/{session_id} 调用 App 中的 SessionDataManager 读取已落盘会话文件;它不查询活跃 Session,也不触发推理或等待后台保存完成。文件组织与编码流程见数据记录与可观测性。

4. 约束与关联文档 ​

标准协议的 api_key 校验只检查非空,简单协议使用内部占位值;HTTP 工具接口没有访问鉴权。这是当前实现边界,部署侧访问控制见配置与部署。

部分处理异常仅写日志并返回,Opus 解码失败可能补静音,协议未保证每次内部失败都返回结构化错误。完成消息表示正常结束分支走到响应步骤,不证明每块转换成功、音质合格或录音已经保存。持久化完成语义见数据记录。

Fast-VC · 实时流式语音转换