【DigiKey好物畅享】M5Stack-CoreS3 基于语音控制的音乐播放器(三)
一、前言
本项目是基于M5Stack CoreS3硬件平台搭建的,整合了esp32-xiaozhi嵌入式智能对话终端系统。最花心思的地方,一是把交互界面做了深度定制,用着更顺手;二是把音频播放功能优化整合,不管是触摸还是语音控制,都能流畅响应,整体用下来体验挺不错的。
二、项目亮点
1. 定制交互界面
之前小智的SpiLcdDisplay类不够灵活,我就把它扩展重构了,做成了CustomLcdDisplay类,基于LVGL弄出了全新的主界面,还加了动态控件和动画效果,看着更生动。顶部是状态栏,网络、电池电量、通知这些关键信息一眼就能看到;中间是聊天区域,用户和助手的消息用气泡式展示,左右对齐,特别清晰,而且只会保留最新的3条消息,旧消息会自动移除,不会显得杂乱;底部专门加了上一首、播放/暂停、下一首的控制按钮,操作起来很直观。
2. AudioPlayerUnit IDF 驱动
AudioPlayerUnit器件官方只给了Arduino的相关资源,但项目需要基于IDF框架开发,没有合适的驱动,音频控制根本没法落地。所以我专门开发了一套AudioPlayerUnit IDF驱动套件,架构设计上花了不少心思:通过UART协议和音频模块通信,还开了专门的FreeRTOS任务处理UART事件,协议帧里包含命令、长度、数据、逆码和校验和,用信号量实现主线程和音频控制的同步,这样效率更高。
3. 项目运行模式
这个播放器能通过AudioPlayerUnit类和硬件播放器的UART通信,控制方式有两种:一种是触摸屏幕,直接点界面上的控制按钮就行,直观又简单;另一种是语音控制,喊唤醒词“nihao, Xiaozhi”就能启动对话功能,之后说对应的命令就行。
另外,我还在McpComplex类的构造函数里,通过MCP服务器注册了音频播放器控制工具,这样小智聊天机器人这类外部系统,就能通过MCP协议控制播放器了。不同的语音命令对应不同的功能,比如想切下一首就说“外部播放器,播放下一首歌曲”,想调大音量就说“外部播放器,音量增大一点”,只要包含“下一首”“增大”这类核心关键词,系统就能精准识别。
语音命令与功能匹配
| 工具函数 | 自然语言命令示例 | 核心关键词 |
|---|---|---|
| current_songs | “外部播放器,现在正在播放哪首歌?” | “正在播放”, “哪首歌”, “第几首” |
| total_songs | “外部播放器,总共有多少首歌?” | “总共”, “多少首”, “音乐库” |
| set_volume | “外部播放器,音量设置为15。” | “音量设置为”, “设置为” |
| get_volume | “外部播放器,现在音量是多少?” | “音量是多少”, “现在音量” |
| decrease_volume | “外部播放器,音量减小一点。” | “减小”, “调低” |
| increase_volume | “外部播放器,音量增大一点。” | “增大”, “调高”, “声音大一点” |
| play_song | “外部播放器,开始播放音乐。” | “播放”, “开始播放” |
| stop_song | “外部播放器,停止播放。” | “停止”, “停止播放” |
| previous_song | “外部播放器,播放上一首歌曲。” | “上一首”, “前一首” |
| next_song | “外部播放器,播放下一首歌曲。” | “下一首”, “下一个” |
三、使用方法
两种启动方式都很便捷:要么直接喊“你好, 小智”,用语音唤醒对话功能;要么点击顶部的状态栏,通过触摸唤醒语音命令。或者直接摸屏幕上的控制按钮,要么用语音发命令,比如“开始播放音乐”“音量设置为15”,系统都能快速响应。
1. 项目架构
smart_audio_player/
├── components/ # 项目组件
│ ├── AudioPlayerUnit/ # 音频播放器驱动
│ ├── McpComplex/ # MCP 协议集成
│ └── CustomLcdDisplay/ # 自定义显示类
├── main/ # 主程序
│ ├── app_main.cpp
│ └── CMakeLists.txt
├── components.mk # 组件配置
├── CMakeLists.txt # 项目配置
└── README.md # 项目说明
2. 核心类
核心类就四个,各司其职:AudioPlayerUnit负责音频播放器控制,CustomLcdDisplay管自定义显示,McpComplex处理MCP协议集成,CoreS3Board专门适配M5Stack CoreS3硬件,配合起来特别顺畅。
3. 编译与运行
开发环境准备
-
设置目标芯片:
idf.py set-target esp32s3 -
配置项目:
idf.py menuconfig -
选择开发板:
Xiaozhi Assistant → Board Type → m5stack-core-s3 -
配置 PSRAM:
Component config → ESP PSRAM → SPI RAM config → Mode (QUAD/OCT) → QUAD Mode PSRAM
- 编译、烧录和监控:
idf.py build flash monitor
四、心得体会
项目初期,最大的卡点是官方仅提供Arduino资源,缺乏适配IDF框架的音频驱动——这直接制约了核心功能落地,毕竟播放控制、状态反馈都依赖驱动支撑。
只好自己弄一套AudioPlayerUnit IDF驱动,反复调试后采用UART通信+FreeRTOS任务+信号量同步方案,交互设计上,增设触摸按键、保留语音控制,还优化消息展示避免杂乱。
此外,xiaozhi-esp32开源项目帮我省去了基础功能的重复开发,让我能专注定制化优化。未来我计划新增本地播放、在线搜索等功能,完善文件管理与语音指令。此次项目深化了我对ESP32-S3和UART通信的理解,也学会了平衡技术与体验,这些经验会成为后续开发的重要积淀。
项目代码 点击跳转 源码


