SDD-00:项目启动与价值边界定义
SDD-00:项目启动与价值边界定义
Section titled “SDD-00:项目启动与价值边界定义”项目名称:esp-audio-stream
中文名称:ESP32 产品级实时音频流传输层
阶段状态:00 环节结论版
目标状态:进入 SDD-01 前的项目基线
1. 一句话定位
Section titled “1. 一句话定位”esp-audio-stream 是一个面向 ESP32 系列资源受限设备的实时音频流传输策略层,用于让设备侧音频上行、服务端音频下行以及未来双向音频流在弱网、断线、慢消费、慢播放、队列堆积、播放缓冲下溢等真实产品场景下保持可控、可观测、可恢复。
它不是音频框架,不是 WebRTC 重写,不是 WebSocket Demo,也不是协议合集。
2. 为什么从 uplink 改为 stream
Section titled “2. 为什么从 uplink 改为 stream”最初项目偏向 Audio Uplink Transport Layer,重点是设备麦克风音频上传。
经过重新审视,真实语音产品通常不只有上行:
- 设备麦克风音频上传到云端。
- 云端 TTS / 语音回复下发到设备播放。
- 远程播报或云端音频流下发。
- 未来可能支持半双工或全双工语音交互。
- 上行和下行都需要状态、缓冲、重连、丢弃、统计和故障诊断。
因此项目定位从:
ESP32 产品级实时音频上行传输层修正为:
ESP32 产品级实时音频流传输层也就是从单向 uplink 升级为更完整的 audio stream transport。
3. 本项目要解决的问题
Section titled “3. 本项目要解决的问题”ESP32 发送或接收音频并不难。
难的是在真实产品中回答这些问题:
- Wi-Fi 断开后如何恢复?
- 服务端消费变慢时,音频发送队列是否会无限堆积?
- 网络恢复后,是否应该继续发送旧音频?
- 实时上行音频的最大延迟如何控制?
- 音频采集任务会不会被网络发送阻塞?
- 上行失败时,如何定位是 Wi-Fi、DNS、TLS、Socket、服务端还是队列问题?
- 云端 TTS 音频下发中断后如何恢复?
- 网络抖动时播放缓冲如何控制?
- 下行音频是否需要保序、丢弃、截断或重新同步?
- 播放端消费变慢时,接收队列是否会无限增长?
- 播放缓冲下溢时,如何上报和恢复?
- 新的语音回复到达时,是否应该打断旧的下行音频?
- 设备端如何区分网络问题、解码问题、播放问题和服务端问题?
- 上行和下行是否共享同一连接?
- 控制消息、上行音频和下行音频是否应该分离?
- 半双工 / 全双工场景下如何管理方向状态?
- 如何统一统计收发两端的时延、队列、丢帧、重连和错误?
本项目的核心问题不是“用什么协议传音频”,而是:
在 ESP32 等资源受限设备上,如何构建一个产品级实时音频流传输层,使上行、下行和未来双向音频流在复杂网络条件下具备明确的行为边界、可诊断能力和可恢复能力。
4. 项目不做什么
Section titled “4. 项目不做什么”为避免低价值重复和范围失控,本项目明确不做:
- 不做 I2S 麦克风驱动。
- 不做扬声器 / I2S 播放驱动。
- 不做音频编解码库。
- 不做完整音频 pipeline 框架。
- 不重写 ESP-ADF。
- 不重写 WebRTC。
- 不做 SIP / RTSP / RTMP 协议栈。
- 不做通用网络库。
- 不做云端语音识别 SDK。
- 不做云端 TTS SDK。
- 不做“ESP32 WebSocket 音频上传 Demo”。
- 不做“ESP32 WebSocket 音频播放 Demo”。
- 不以“支持协议数量”作为核心价值。
5. 项目真正要做什么
Section titled “5. 项目真正要做什么”本项目只聚焦一个层次:
Audio Capture / Encoder Audio Decoder / Player ↓ ↑ └────── esp-audio-stream ─────────┘ ↓ ↑ Protocol Backend ↓ ↑ Server / Cloud / AI Service本项目主要负责:
- 统一音频帧模型。
- 上行音频帧序号与时间戳。
- 下行音频帧序号与时间戳。
- 有界发送队列。
- 有界接收 / 播放队列。
- 最大队列时长控制。
- 最大音频帧生命周期控制。
- 过期音频帧丢弃。
- 队列满时的丢帧策略。
- 播放缓冲下溢 / 溢出统计。
- 采集、发送、接收、播放之间的解耦。
- 控制面与数据面分离。
- 方向状态管理:uplink / downlink / bidirectional。
- 连接状态机。
- 重连与恢复策略。
- 传输统计指标。
- 错误分类。
- 弱网测试工具。
- 参考服务端 / 接收端 / 下发端实现。
- 协议 backend 抽象。
6. 与 ESP-ADF 的关系
Section titled “6. 与 ESP-ADF 的关系”ESP-ADF 是本项目必须研究、兼容和借势的生态基座,但不是本项目的直接竞品。
ESP-ADF 的定位是:
ESP32 音频应用开发框架它适合处理 audio pipeline、audio element、ringbuffer、codec、I2S stream、HTTP stream、播放器、录音器、蓝牙音频、VoIP、RTSP/SIP/RTMP 等音频应用场景。
本项目的定位是:
实时音频流传输策略层它只关注:
- 实时音频上行。
- 实时音频下行。
- 未来双向音频流。
- 弱网行为。
- 收发队列策略。
- 音频帧生命周期。
- 播放缓冲行为。
- 重连恢复。
- 传输状态机。
- 传输可观测性。
- 协议 backend 抽象。
- 产品级测试与诊断。
因此,本项目不替代 ESP-ADF。
正确关系是:
ESP-ADF / ESP-IDF / I2S / Codec / Player ↓ ↑esp-audio-stream ↓ ↑WebSocket / UDP / RTP-like / WebRTC adapter ↓ ↑Server / Cloud / AI Backend未来本项目既可以独立用于 ESP-IDF 项目,也可以作为 ESP-ADF pipeline 中的 stream transport element 使用。
7. 与 WebSocket / WebRTC 的关系
Section titled “7. 与 WebSocket / WebRTC 的关系”本项目不反对直接使用 WebSocket 或 WebRTC。
对于 Demo、局域网测试、简单音频上传或播放、小规模产品,直接 WebSocket 发送/接收音频可能已经足够。
对于完整实时音视频通信、浏览器互通、NAT 穿透、多方通信等场景,WebRTC 可能是更合适的选择。
但是,WebSocket 和 WebRTC 不是本项目要解决的全部问题。
本项目关注的是协议之上的产品行为:
- 上行发送队列是否有上限?
- 下行接收 / 播放队列是否有上限?
- 音频帧是否有生命周期?
- 网络阻塞时是否会拖死采集任务?
- 播放阻塞时是否会拖死接收任务?
- 服务端慢消费时上行延迟是否无限增长?
- 客户端慢播放时下行延迟是否无限增长?
- 断线重连后是否会补发或播放过期音频?
- 错误原因是否可分类?
- 指标是否可观测?
- backend 是否可替换?
因此,本项目不替代 WebSocket,也不替代 WebRTC。
WebSocket、UDP、RTP-like、WebRTC、QUIC 等都应被视为 backend,而不是架构中心。
8. 核心价值判断
Section titled “8. 核心价值判断”本项目的价值不在于“又实现了一个传输协议”。
本项目的价值在于:
把实时音频流传输过程中容易被 Demo 忽略的弱网、队列、重连、丢帧、播放缓冲、状态、统计和诊断问题,抽象成一个可复用、可测试、可维护的产品级传输策略层。
一句话总结:
协议能传音频,不代表产品级音频流行为可控。本项目要证明的是:
在相同硬件、相同音频源、相同网络故障、相同服务端条件下,策略层方案比直接发包 / 直接收包方案更可控、更可观测、更容易恢复。9. 第一阶段对标对象
Section titled “9. 第一阶段对标对象”本项目第一阶段不直接对标 ESP-ADF。
第一阶段真正的价值验证对象是:
Direct WebSocket Baseline包括:
Uplink Baseline:Audio Frame → websocket_send()
Downlink Baseline:websocket_recv() → Audio Frame → player_write()我们必须证明:
Audio Frame ↔ esp-audio-stream ↔ WebSocket Backend在真实异常条件下比直接 WebSocket 收发更可控。
10. 首版最小有价值形态
Section titled “10. 首版最小有价值形态”V0 / MVP 不追求多协议,也不要求同时把上行和下行做到完整产品形态。
首版最小有价值形态建议是:
统一 AudioFrame+ 方向字段:uplink / downlink / control+ 有界发送队列+ 有界接收 / 播放队列+ 音频帧生命周期+ 丢帧 / 丢包 / 丢播放策略+ WebSocket backend+ 连接状态机+ 重连恢复+ 收发统计+ 错误分类+ 测试服务端+ 故障注入工具+ Direct WebSocket baseline 对比首版可以优先把上行验证做深,同时保留下行接口、状态和测试框架,避免项目名和抽象被 uplink 锁死。
首版不做:
完整 WebRTC backend完整 QUIC backend完整 RTP/RTCP 实现完整 SIP/RTSP/RTMP 支持复杂自适应码率复杂拥塞控制完整云端 SDK完整播放器框架完整 TTS SDK11. 核心设计原则
Section titled “11. 核心设计原则”原则 1:协议是 backend,不是架构中心
Section titled “原则 1:协议是 backend,不是架构中心”项目不能围绕“我要支持 WebSocket、UDP、WebRTC、QUIC”展开。
应该围绕:
AudioFrameStreamSessionStreamDirectionFrameQueuePlayQueueTransportPolicyStateMachineStatsBackend展开。
原则 2:实时音频优先保证新鲜度
Section titled “原则 2:实时音频优先保证新鲜度”实时语音不是文件上传,也不是普通音频文件播放。
旧的上行音频在很多场景下没有继续发送的价值。旧的下行音频在交互场景中也可能已经不应该继续播放。
因此,模块默认应支持:
- 最大帧年龄。
- 最大发送队列时长。
- 最大接收 / 播放队列时长。
- 过期帧丢弃。
- 重连后丢弃过期音频。
- 新响应打断旧下行音频的策略。
原则 3:队列必须有界
Section titled “原则 3:队列必须有界”不允许因为网络阻塞、服务端慢消费或播放慢消费导致音频帧无限堆积。
队列至少需要以下限制:
- 最大字节数。
- 最大帧数。
- 最大缓存时长。
- 最大帧生命周期。
原则 4:采集、发送、接收、播放必须解耦
Section titled “原则 4:采集、发送、接收、播放必须解耦”采集任务不应该被网络发送长期阻塞。
接收任务不应该被播放任务长期阻塞。
发送端和播放端都需要明确的背压与丢弃策略。
原则 5:控制面和数据面分离
Section titled “原则 5:控制面和数据面分离”控制消息和音频帧不应该被同等对待。
控制面:
auth / start / stop / interrupt / heartbeat / config / stats / error数据面:
uplink audio frame / downlink audio frame / sequence / timestamp / codec / payload控制消息更关注可靠性。音频帧更关注低延迟、生命周期和可控丢弃。
原则 6:失败必须可观测
Section titled “原则 6:失败必须可观测”模块必须能解释:
- 当前连接状态。
- 当前方向状态。
- 是否正在重连。
- 上行队列中堆积了多少音频。
- 下行 / 播放队列中堆积了多少音频。
- 丢了多少上行帧。
- 丢了多少下行帧。
- 是否发生播放下溢。
- send / recv / decode / play 失败原因。
- 最近一次 backend 错误。
- Wi-Fi 是否断开。
- 服务端是否慢消费。
- 客户端是否慢播放。
- heap 是否持续下降。
- task stack 是否危险。
原则 7:复杂度必须由测试证明
Section titled “原则 7:复杂度必须由测试证明”本项目不能因为“架构看起来合理”就成立。
必须通过 baseline 对比证明:
策略层方案带来的收益 > 额外 RAM / CPU / 代码复杂度成本12. 进入 SDD-01 的条件
Section titled “12. 进入 SDD-01 的条件”进入 SDD-01 前,需要接受以下基线:
- 项目定位已经确定为实时音频流传输层,而不是只做 uplink。
- 第一阶段可以优先验证上行,但架构必须覆盖下行。
- ESP-ADF 是生态基座,不是直接竞品。
- Direct WebSocket 是第一阶段 baseline。
- WebSocket backend 是 MVP 第一 backend。
- UDP / RTP-like backend 作为 Phase 2。
- WebRTC / QUIC 只作为未来 adapter 研究。
- 第一阶段必须包含价值验证实验。
- 不通过价值验证,不进入大规模架构设计。
13. 00 环节最终判断
Section titled “13. 00 环节最终判断”本项目值得继续,但前提是始终坚持以下判断:
让 ESP32 收发音频不稀缺;让 ESP32 在真实网络环境下稳定、可控、可诊断地持续处理实时音频流,才是价值。因此,00 环节结论为:
继续推进本项目,但不得做成 ESP-ADF 的低配替代品、WebRTC 的重写版本或 WebSocket 音频 Demo。项目定位应从上行音频上传扩展为实时音频流传输,覆盖上行、下行和未来双向场景。下一阶段应围绕 Direct WebSocket baseline 与 Policy Layer candidate 的价值验证展开。只有当策略层能通过实验数据证明其可控性、可观测性和恢复能力优于直接收发方案时,项目才具备继续开源和产品化的价值。