开源代码仓库:https://github.com/wuooo339/xiaozhimusic.git
使用 ESP32S3 平台搭建了智能助手,基于开源项目扩展了音乐播放功能。为解决曲库不足问题,通过调用第三方 API 实现自定义歌曲播放。本文介绍基于 ESP-ADF 的 m4a 解码流实现方案。
实现方案
MCP 接口调用
在 main/mcp_server.cc 增加 API 接口搜索,当播放歌曲时自动调用搜索这个加了关键词的 URL。
API 文档:落月 API
AddTool("test_search_music", "Search and play music by keyword. Use this tool when the user asks to play music, search for songs, or find music. This tool will search for music using the provided keyword and automatically start playing the first result.", PropertyList({ Property("keyword", kPropertyTypeString, "Music search keyword") }), [](const PropertyList& properties) -> ReturnValue {
auto keyword = properties["keyword"].value<std::string>();
ESP_LOGI(TAG, "Searching for music: %s", keyword.c_str());
// 构建搜索 URL(使用 URL 编码)
std::string encoded_keyword = url_encode(keyword);
std::string search_url = "https://api.vkeys.cn/v2/music/tencent?word=" + encoded_keyword + "&choose=1&quality=2";
// 创建 HTTP 客户端搜索音乐
auto& board = Board::GetInstance();
auto network = board.GetNetwork();
auto http = network->CreateHttp(0);
if (http->Open("GET", search_url)) {
std::string response = http->();
http->();
cJSON* root = (response.());
(root) {
cJSON* code = (root, );
((code) && code->valueint == ) {
cJSON* data = (root, );
((data)) {
cJSON* song = (data, );
cJSON* singer = (data, );
cJSON* url = (data, );
((url)) {
std::string music_url = url->valuestring;
(TAG, , (song) ? song->valuestring : , (singer) ? singer->valuestring : );
& audio_service = Application::().();
audio_service.(music_url);
Application::().(kDeviceStateListening);
std::string result = ;
((song)) {
result += song->valuestring;
}
result += ;
((singer)) {
result += singer->valuestring;
}
result += ;
(root);
result;
}
}
}
(root);
}
}
;
});


