资讯动态

ESP-ADF 扣子(Coze)WebSocket 双向流式语音对话例程实战:从账号申请到 ESP32 语音助手落地

发布时间:2026/10/14 3:09:19 来源:尧图企业网站定制
音视频音频处理嵌入式物联网语音【免费下载链接】esp-adfEspressif Advanced Development Framework for Multimedia Applications项目地址https://gitcode.com/gh_mirrors/es/esp-adf点击查看免费下载本指南完整讲解 esp-adf 仓库中adf_examples/ai_agent/coze_ws_app例程的工程结构、前置条件、三种交互工作模式、编解码配置、编译烧录流程与常见故障排查。读完本文你将能够独立完成扣子智能语音对话 WebSocket OpenAPI 的接入并在 ESP32 系列芯片上实现支持直接对话、语音唤醒与按键打断的语音助手设备。例程概览基于 WebSocket 的双向流式语音对话coze_ws_app是 ESP-ADFEspressif Advanced Development Framework for Multimedia Applications中位于 adf_examples/ai_agent/coze_ws_app 的完整示例工程。它实现了扣子Coze智能语音对话的WebSocket OpenAPI即双向流式语音对话设备端将麦克风采集并编码后的音频持续上行发送服务端通过同一条 WebSocket 连接回传语音回复与字幕等事件从而实现全双工语音交互。例程支持三种与智能体交互的方式直接对话普通模式无需唤醒词开机即可连续语音对话语音唤醒通过唤醒词默认Hi 乐鑫唤醒设备后开始对话按键打断/触发通过实体按键默认REC控制对话的开启与结束。从技术底座看该例程基于ESP-GMF框架搭建音频流水线演示了音频初始化以及 3A 算法自动增益 AGC、回声消除 AEC、噪声抑制 NS在实际语音对话设备中的应用而 WebSocket 协议侧则由本仓库内的esp_coze组件components/esp_coze承担。对应的英文版本见 README.md。一、前置准备申请 Access Token 与 BOT ID接入扣子语音对话服务前需要先在扣子开放平台完成两项凭证申请Access Token用于 WebSocket 鉴权的访问令牌。例程中令牌默认以pat_为前缀个人访问令牌 PAT 形式BOT ID在扣子平台创建 Bot 后获得的唯一标识用于指定本次对话的智能体目标。提示更完整的 WebSocket 协议细节如双向流式对话事件定义可查阅扣子开放平台的双向流式对话事件文档本文以仓库内例程的实际实现为准展开。从源码侧可以确认这两个凭证的承载方式。在 main/Kconfig.projbuild 中定义了两个字符串配置项config COZE_BOT_ID string COZE_BOT_ID default 7239506************** config COZE_ACCESS_TOKEN string COZE_ACCESS_TOKEN default pat_******************它们随后在 main/coze_chat_app.c 的init_coze_chat()中注入到会话配置esp_coze_chat_config_t chat_config ESP_COZE_CHAT_DEFAULT_CONFIG(); chat_config.enable_subtitle true; chat_config.bot_id CONFIG_COZE_BOT_ID; chat_config.access_token CONFIG_COZE_ACCESS_TOKEN; chat_config.uplink_audio_type UPLINK_AUDIO_ENCODE_TYPE; chat_config.downlink_audio_type DOWNLINK_AUDIO_ENCODE_TYPE; chat_config.audio_callback audio_data_callback; chat_config.event_callback audio_event_callback;esp_coze_chat_config_t的完整字段定义可在 components/esp_coze/include/esp_coze_chat.h 中查看其中bot_id、access_token等字符串字段会在esp_coze_chat_init()时做深拷贝调用方在初始化返回后可以安全释放原始缓冲区。二、硬件与环境准备2.1 兼容分支与开发板IDF 版本例程兼容 IDFrelease/v5.4及以上版本分支默认开发板esp32-s3-korvo-2。其他开发板可通过menuconfig → GMF APP Configuration → Target Board选择。仓库内为不同芯片提供了独立的默认配置例如 sdkconfig.defaults.esp32s3启用 SPIRAM、WakeNet 唤醒词模型wn9_hilexin、中文 MultiNet6 命令词模型等、sdkconfig.defaults.esp32p4P4 通过 esp_hosted/esp_wifi_remote 使用外部 Wi-Fi 芯片以及 sdkconfig.defaults.esp32c3 / sdkconfig.defaults.esp32c6使用精简分区表partitions_lite.csv。2.2 自定义开发板接入四步使用自定义开发板时需要完成以下四步在managed_components → tempotian__codec_board → board_cfg.txt中重定义自己开发板相关的 IO pin 和 codec 芯片在managed_components → espressif__gmf_app_utils → Kconfig.projbuild中加上相关的 board 配置在menuconfig → GMF APP Configuration → Target Board中选中自定义的板子在main/board_config.h中加入相关的配置。注意如果使用自定义开发板建议将tempotian__codec_board和espressif__gmf_app_utils两个文件夹复制到components目录下避免被组件管理器重新下载覆盖。2.3 板级参数的底层含义main/board_config.h 是例程适配不同板卡的关键文件。它以编译期宏区分板卡并给出三个核心音频参数BOARD_SAMPLE_RATE采样率默认 16000 HzBOARD_CHANNELS声道数如 korvo-2 为 2 声道BOARD_SAMPLE_BITS采样位深korvo-2 为 32 bit部分板卡为 16 bitINPUT_CH_ALLOCATIONAFEAudio Front End输入声道分配方式例如RMNMR参考回采、M麦克风、N空或MRBOARD_CODEC_REF_MIC参考麦克风/回采通道的位掩码供 AEC 使用。这些宏会直接影响 main/audio_processor.c 中 codec 设备的初始化参数与播放/录音流水线的重采样目标值因此自定义板卡时务必按实际硬件准确填写。三、三种工作模式与芯片支持矩阵3.1 工作模式定义系统目前支持以下三种工作模式普通模式Continuous Mode用户无需使用唤醒词可以直接连续与设备进行语音交互。这是默认启用的工作模式唤醒对话模式Wake Word Mode用户通过唤醒词唤醒设备唤醒后即可进行语音交互。默认唤醒词为Hi 乐鑫可在menuconfig → ESP Speech Recognition → use wakenet → Select wake words中选择按键对话模式Key Press Mode用户通过按键唤醒设备默认按键为REC按住录音、松开结束之后可进行语音交互。三种模式在 main/Kconfig.projbuild 中通过 choice 单选实现config VOICE_WAKEUP_MODE bool Wake Word Mode select SR_WN_WN9_HILEXIN config CONTINUOUS_CONVERSATION_MODE bool Continuous Mode config KEY_PRESS_DIALOG_MODE bool Key Press Mode3.2 芯片支持情况芯片唤醒词模式普通模式按键模式ESP32-S3支持支持支持ESP32-P4支持支持支持ESP32支持支持支持ESP32-C3不支持不支持支持ESP32-C6不支持不支持支持ESP32-C5不支持不支持注 1支持ESP32-S2不支持不支持支持注 1ESP32-C5 的普通模式计划在后续版本中支持。3.3 模式差异在源码中的体现不同工作模式直接影响录音链路与交互逻辑在 main/coze_chat_app.c 的audio_data_read_task()中三种模式的上行逻辑截然不同按键模式先等待BUTTON_REC_READING事件位按键按下后开始读取并发送音频松开时调用esp_coze_chat_send_audio_complete()标记一段语音结束唤醒模式持续读取音频但仅在coze_chat.wakeuped true时才上行发送普通模式持续读取并持续上行发送不做门控。录音流水线结构也不同。在 main/audio_processor.c 的recorder_get_pipeline_config()中普通/唤醒模式非按键模式会经过ai_afe含 AEC/SE/VAD/WakeNet 的前端后再编码按键模式直接使用aud_bit_cvt → aud_rate_cvt → aud_ch_cvt做 PCM 格式转换不加载 AFE 前端这也是按键模式对 ESP32-C3/C6/S2 等低资源芯片也能支持的原因。四、编解码格式与音频链路配置4.1 支持的编解码格式例程当前支持的音频编解码格式包括OPUS、G711AA-law、G711Uμ-law和 PCM上行录音→服务器与下行服务器→播放可分别独立选择。更多格式细节可参考扣子官方双向流式对话事件文档。默认 OPUS 一帧为 60ms。在 main/Kconfig.projbuild 中上行与下行格式各自是一个 choice# 上行Audio Upload Encoding Format config UPLOAD_FORMAT_OPUS # 默认 config UPLOAD_FORMAT_PCM # 不推荐生产使用数据量大 config UPLOAD_FORMAT_G711A config UPLOAD_FORMAT_G711U # 下行Audio Download Decoding Format config DOWNLOAD_FORMAT_OPUS # 默认 config DOWNLOAD_FORMAT_PCM # 不推荐生产使用 config DOWNLOAD_FORMAT_G711A config DOWNLOAD_FORMAT_G711U4.2 上行/下行链路与源码对应关系格式选择在 main/coze_chat_app.c 中映射为esp_coze_chat_audio_type_tESP_COZE_CHAT_AUDIO_TYPE_OPUS / G711A / G711U / PCM并在init_coze_chat()中分别配置uplink_audio_type与downlink_audio_type。对应的编解码实现位于 main/audio_processor.cOPUS 编码recorder_configure_opus_encoder()bitrate 24000、单声道、16000 Hz 采样、enable_vbr falseCBROPUS 解码playback_configure_opus_decoder()frame_duration ESP_OPUS_DEC_FRAME_DURATION_60_MS与默认 60ms 帧对齐G711 编解码recorder_configure_g711_encoder()/playback_configure_g711_decoder()统一配置为 8000 Hz、单声道、16 bitPCMrecorder_configure_pcm_encoder()/playback_configure_pcm_decoder()16000 Hz、单声道、16 bit。实现细节录制流水线根据格式选择不同的 element 组合例如 OPUS 上传时为ai_afe → aud_encG711 上传时为ai_afe → aud_rate_cvt → aud_encPCM 上传时仅ai_afe按键模式下为纯格式转换链。播放流水线固定为aud_dec → aud_bit_cvt → aud_rate_cvt → aud_ch_cvt通过playback_configure_converters()将位深、采样率、声道转换到板卡实际参数BOARD_*宏。五、编译与烧录5.1 环境配置与编译编译本例程前需先配置好 ESP-IDF 环境。若尚未配置请在 ESP-IDF 根目录运行以下脚本设置编译环境./install.sh . ./export.sh随后按如下步骤选择芯片、编译并烧录# 选择编译芯片以 esp32s3 为例 idf.py set-target esp32s3 # 编译程序 idf.py build # 烧录程序并运行 monitor 查看串口输出PORT 替换为实际串口名 idf.py -p PORT flash monitor5.2 分区与烧录配套例程使用自定义分区表见 partitions.csv包含nvs、factory、model存放语音识别/唤醒模型约 5 MB与spiffs_data存放提示音等小文件四个分区低资源芯片则使用精简版 partitions_lite.csv。对应芯片的默认 flash 配置在 sdkconfig.defaults8 MB flash、QIO、80 MHz中统一设定。编译期还会通过 main/CMakeLists.txt 中的spiffs_create_partition_image将spiffs/dingding.wav唤醒提示音打包进spiffs_data分区仅非按键模式构建时生效。5.3 自动化验证仓库提供了对应的嵌入式测试脚本 pytest_coze_ws_app.py以esp32、esp32s3、esp32p4三个目标参数化运行并等待example_connect: Connecting to日志出现以判定例程正常启动。六、运行验证与日志解读6.1 关键日志标记例程开始运行后出现以下关键日志表明与服务端成功建立 WebSocket 连接、已具备对话条件E (1029) COZE_CHAT_WS: Failed to get SPIFFS partition information (ESP_ERR_INVALID_STATE) I (1031) example_connect: Start example_connect. ... I (4830) example_connect: Got IPv4 event: Interface example_netif_sta address: 192.168.3.7 ... I (5054) ESP_COZE_CHAT: wss_url: ws://ws.coze.cn/v1/chat?bot_id748006*********** I (5061) ESP_COZE_CHAT: token: Bearer pat_********************* I (5071) ESP_COZE_CHAT: WEBSOCKET_EVENT_BEGIN I (5677) ESP_COZE_CHAT: WEBSOCKET_EVENT_CONNECTED I (5678) ESP_COZE_CHAT: WS connected I (6500) ESP_COZE_CHAT: Request conversation_id : 74970793******** I (6500) ESP_COZE_CHAT: WS start updata chat其中WEBSOCKET_EVENT_CONNECTED/WS connected表示与扣子服务端的连接已建立Request conversation_id表示会话创建成功随后设备会向服务端发送chat.update例程日志中显示为Update chat。开头的Failed to get SPIFFS partition information (ESP_ERR_INVALID_STATE)属于可忽略提示它来自 main/main.c 中的 SPIFFS 初始化尝试例程对非严重错误做了容错处理不影响后续功能。6.2 chat.update 请求内容解读连接建立后设备发送的chat.update配置决定了本次对话的音频参数日志中的 JSON 是理解整套协议的关键核心字段如下chat_config: { auto_save_history: true, conversation_id: 74970793********, user_id: userid_123, parameters: { custom_var_1: 测试 } }, input_audio: { format: pcm, codec: pcm, sample_rate: 16000, channel: 1, bit_depth: 16 }, turn_detection: { type: server_vad, prefix_padding_ms: 600, silence_duration_ms: 500 }, output_audio: { codec: opus, opus_config: { bitrate: 16000, frame_size_ms: 60, limit_config: { period: 1, max_frame_num: 18 } }, speech_rate: 20, voice_id: 7426720361733144585 }, event_subscriptions: [ conversation.audio.delta, conversation.chat.completed, input_audio_buffer.speech_started, input_audio_buffer.speech_stopped, chat.created, error, conversation.message.delta ]input_audio上行音频为 16 kHz、单声道、16 bit PCM实际编码后的码流按所选格式发送turn_detection采用服务端 VAD 检测说话结束prefix_padding_ms600为语音起始前的缓冲silence_duration_ms500为判定结束的静音时长output_audio下行 OPUSframe_size_ms60与例程默认帧长一致voice_id指定 TTS 音色event_subscriptions订阅的事件集合例程据此接收音频增量、字幕、语音起止等事件。这些参数在 components/esp_coze/include/esp_coze_chat.h 的esp_coze_chat_config_t中均有对应配置项如downlink_bitrate、downlink_frame_size_ms、downlink_limit_period、downlink_max_frame_num、downlink_speech_rate、vad_silence_mode等默认值在ESP_COZE_CHAT_DEFAULT_CONFIG()宏中给出。6.3 AFE 前端初始化日志随后日志进入音频初始化阶段展示 AFEAudio Front End参数例如AFE: AFE Version: (2MIC_V250113) AFE: Input PCM Config: total 4 channels(2 microphone, 1 playback), sample rate:16000 AFE: AFE Pipeline: [input] - |AEC(SR_HIGH_PERF)| - |SE(BSS)| - |VAD(WebRTC)| - [output]这对应 main/audio_processor.c 中recorder_setup_afe_config()的配置aec_init true、vad_init VAD_ENABLE、agc_init true、vad_min_speech_ms 64、vad_min_noise_ms 1000唤醒模式CONFIG_VOICE_WAKEUP_MODE下额外开启wakenet_init true。AFE 流水线依次执行AEC回声消除SR_HIGH_PERF→ SE语音增强BSS 麦克风阵列→ VAD语音活动检测WebRTC为语音识别和上行音频质量提供保障。6.4 工作流程与组件 API 对应从 main/main.c 可以梳理出完整的启动流程nvs_flash_init()初始化 NVSspiffs_filesystem_init()挂载 SPIFFS 分区esp_netif_init()esp_event_loop_create_default()初始化网络栈与事件循环example_connect()连接 Wi-Fi配置见menuconfig → Example Connection Configurationcoze_chat_app_init()完成会话初始化、音频流水线打开与数据收发任务创建。在 main/coze_chat_app.c 内部init_coze_chat()依次调用esp_coze_chat_init()与esp_coze_chat_start()上行任务audio_data_read_task循环调用audio_recorder_read_data()读取编码后音频再经esp_coze_chat_send_audio_data()发送下行音频经audio_callback回调到audio_playback_feed_data()送入播放链路。中断/取消语义通过esp_coze_chat_send_audio_cancel()取消当前轮与esp_coze_chat_send_audio_complete()标记一段语音结束实现按键模式下还配合 ADC 按键main/coze_chat_app.c 中button_adc_config_tADC1 通道 4触发。七、故障排查7.1 自问自答现象问题描述设备出现“自问自答”即设备播放的音频被麦克风重新采集并识别导致系统误触发。问题原因不同硬件平台的麦克风/扬声器型号与物理距离不同采集音频的增益可能过大或过小影响回声消除AEC算法效果。解决方案调整音频增益参数适当修改 main/audio_processor.c 中的DEFAULT_RECORD_DB默认 50.0、DEFAULT_RECOPRD_REF_DB默认 50.0和DEFAULT_PLAYBACK_VOLUME默认 70启用menuconfig → Example Audio Configuration → Enable AEC Debug对应CONFIG_ENABLE_RECORDER_DEBUG将录音数据保存至存储设备进行分析。注意启用 AEC Debug 功能需要硬件设备配备 SD 卡。源码中调试数据会写入/sdcard/rec3.pcm采样 30 秒用于离线分析回采与麦克风信号。7.2 音频数据发送超时问题描述系统日志中出现Audio data send timeout错误信息。问题原因通常由网络连接质量不佳导致数据包无法正常发送至服务器。解决方案改善当前测试环境的网络连接质量调整音频编码方式以降低数据传输量例如将上行格式从 PCM 切换为 OPUS/G711。说明经测试验证偶尔出现几次Audio data send timeout错误不会影响语音识别功能的正常使用。与超时相关的可调参数在esp_coze组件的 Kconfig 中提供ESP_COZE_WS_AUDIO_SEND_TIMEOUT_MS上行input_audio_buffer.append的发送超时默认 20000 ms可通过menuconfig → ESP COZE Chat调整、ESP_COZE_WS_NETWORK_TIMEOUT_MS、ESP_COZE_WS_RECONNECT_TIMEOUT_MS等详见 components/esp_coze/Kconfig。7.3 多模块共用 I2C 总线问题描述当其他模块如 LCD、触摸屏等也需要使用 I2C 总线时可能出现异常现象例如触摸无响应等。原因分析audio_processor默认会初始化 I2C 总线并持有 I2C 句柄若其他模块也初始化或操作同一 I2C 总线可能导致句柄冲突或资源竞争。建议解决方法如果在audio_processor初始化之前已初始化 I2C可在 main/audio_processor.c 的codec_info中直接传入已有的 I2C 句柄I2C_master_handle如果在audio_processor初始化之后需要访问 I2C可通过esp_gmf_app_get_i2c_handle()获取已初始化的 I2C 句柄避免重复初始化和冲突。八、计划功能与后续演进根据例程文档后续计划包括支持多功能形态例如音响设备可实现混音功能围绕该方向esp_coze组件当前已支持 Chat语音文本流式、TTS文本转语音、ASR语音识别三条相互独立的 API 入口见 components/esp_coze/README.md可在对话之外并行开启独立的 TTS/ASR 会话为音响等设备的扩展功能如多音源混音、独立播报提供了组件级基础。赞分享音视频音频处理嵌入式物联网语音【免费下载链接】esp-adfEspressif Advanced Development Framework for Multimedia Applications项目地址https://gitcode.com/gh_mirrors/es/esp-adf点击查看免费下载相关推荐esp-adf 实战基于 Coze WebSocket 双向流式对话的智能语音交互例程coze_ws_app深度解析esp adf 实战基于 Coze WebSocket 双向流式对话的智能语音交互例程coze_ws_app深度解析 本文以 esp adf 仓库中的 c音视频音频处理嵌入式物联网语音ESP-ADF 百度 RTC 语音助手例程实战基于 ESP-GMF 的 AI 音箱对话、双路混音与 3A 音频链路解析ESP ADF 百度 RTC 语音助手例程实战基于 ESP GMF 的 AI 音箱对话、双路混音与 3A 音频链路解析 本篇技术指南以 ESP ADF 仓库中音视频音频处理嵌入式物联网语音ESP-ADF 多媒体示例工程全览从 AI 语音对话到音视频录制的实战指南ESP ADF 多媒体示例工程全览从 AI 语音对话到音视频录制的实战指南 导读 本文以 adf_examples https://link.gitcode音视频音频处理嵌入式物联网语音上一篇Marlin 固件多语言支持实战从 BDF 字库到 language_data 的完整构建流程下一篇Argos Translate 离线翻译 5 分钟上手指南从 pip 安装到第一次出译文创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑