xiaomusic 同步网易云歌单实战:从歌单 ID 到小爱音箱语音播放
2026/9/15 15:37:57 网站建设 项目流程

xiaomusic 同步网易云歌单实战:从歌单 ID 到小爱音箱语音播放

【免费下载链接】xiaomusic使用小爱音箱播放音乐,音乐使用 yt-dlp 下载。项目地址: https://gitcode.com/GitHub_Trending/xia/xiaomusic

本篇技术指南聚焦 xiaomusic 的“网易云歌单同步”主题:讲解如何借助独立工具netease-playlist通过网易云歌单 ID 下载歌曲或生成 xiaomusic 可识别的歌单配置,并深入剖析官方推荐的替代实现——自定义口令插件方案,让你彻底读懂"歌单 ID → 歌单数据 → 小爱音箱播放"的完整链路。读完本文,你将掌握配置自定义口令、编写 Python 插件拉取歌单、以及调用 docs/issues/269.md 中社区验证过的getmy_playlist插件的完整实战能力。

一、方案概览:三条通往网易云歌单的路径

在 xiaomusic 中接入网易云歌单,社区验证过的主要有下面三种方式:

方案实现形态适合场景
netease-playlist独立工具独立模块,可 Docker 部署一次性/批量下载歌曲,或离线生成歌单配置
自定义口令插件将插件代码挂在exec#口令下语音实时拉取歌单并播放,可配合米家自动化
网络歌单 JSON(官方原生)在设置页配置歌单 JSON / JSON URL电台、m3u8、B 站等在线流媒体歌单

三条路径并非互斥:你完全可以用netease-playlist把歌单导出成 自定义网络歌单格式 后填入设置页,也可以用插件方案实现"把歌曲扔进网易云歌单 → 喊一句口令 → 小爱音箱随机播放"的实时同步体验。

二、独立工具 netease-playlist:歌单 ID 驱动下载与配置生成

Issue 312 的核心内容是推广独立模块netease-playlist。它的能力可以用一句话概括:

通过网易云音乐歌单 ID,下载歌曲,或生成 xiaomusic 可用的歌单配置。

2.1 在 xiaomusic 体系中的定位

原文档明确说明了两点定位:

  1. 独立模块,可 Docker 部署——它不修改 xiaomusic 本体,不依赖 xiaomusic 的插件机制;
  2. 可作为不用插件的另外实现方式——如果你不想维护插件代码,可以只靠这个工具完成任务。

也就是说,netease-playlist与 xiaomusic 的耦合点是"歌单 ID"与"歌单配置 JSON",前者是输入,后者是输出。

2.2 它生成的歌单配置长什么样

netease-playlist生成的目标格式,就是 xiaomusic 原生支持的自定义网络歌单 JSON。参考 docs/issues/78.md 中官方给出的结构:

[ { "name": "歌单1", "musics": [ { "name": "歌名1", "url": "http://.../index.m3u8", "type": "radio" }, { "name": "歌名2", "url": "https://.../64k.mp3" } ] } ]

要点:

  • 顶层是歌单数组,每个元素含name(歌单名)与musics(歌曲数组);
  • 每首歌含nameurl两个必填字段;
  • typeradio时表示电台流,会一直播放当前源,不切下一首;
  • url可以是直链、m3u8 电台地址,也可以是self:///api/proxy/plugin-url?data=开头的在线音乐插件代理链接(v0.4.15 起支持,需配合 OnlineSearch 的 JS 插件并开启“网络歌曲过代理”开关)。

拿到这份 JSON 后,有两种落地方式:

  • 直接粘贴到 xiaomusic 设置页的歌单 JSON 输入框
  • 把 JSON 上传到 gist / GitHub / Gitee 等可直链分享的地址,在JSON URL 输入框里填入 raw 链接,点击“获取”按钮自动填充。

三、配置生成的两种入口:设置页与 config 文件

官方在 docs/issues/105.md 中明确提示:“建议通过插件实现或者新增一个页面工具把歌单导出 json,歌单的 json 格式见 /issues/78”

对应的配置字段在config-example.json中体现为三个相关项:

"music_list_url": "", "music_list_json": "", "custom_play_list_json": ""

其中music_list_json/custom_play_list_json即歌单 JSON 的注入位置,music_list_url则是 JSON 文件的远程地址。设置页上对应的就是“歌单 JSON 输入框”与“JSON URL 输入框”。

需要注意的是,社区在实战中反馈:最好在setting.json里配置,网页端配置有时会出现匹配不上的情况(见 Issue 269 评论 13)。所以一个稳妥的做法是:先用设置页在线验证歌单可用,再把最终 JSON 固化进配置文件。

四、进阶方案:用自定义口令插件实现实时歌单同步

netease-playlist是离线/半离线方案,做不到"往歌单扔歌 → 音箱马上能播"。社区验证过的实时方案是自定义口令插件。这正是 Issue 105 讲解的功能,也是 Issue 312 中"不用插件"的另一面。

4.1 自定义口令的运行原理

从源码看,整个链路是这样的:

  1. 配置注入:在config.pyConfig模型中,user_key_word_dictkey_word_dict都是独立的配置字段(config.py)。调用init()时,append_user_keyword()会把user_key_word_dict中每个k: v合并进key_word_dict,并追加进key_match_order匹配优先级表(config.py);
  2. 口令解析command_handler.py中,无论完全匹配还是模糊匹配,只要opvalueexec#开头,就把#之后的部分当作可执行代码返回(command_handler.py);
  3. 插件执行XiaoMusic.exec()拿到代码后调用plugin_manager.execute_plugin(code)(xiaomusic.py);
  4. 代码校验PluginManager先用ast.parse校验代码必须是“直接调用插件函数的表达式”,支持字符串/数字/布尔/None/列表/元组/字典作为参数,不支持关键字参数(plugin.py);
  5. 动态加载:启动时PluginManager遍历plugins/包内所有模块,动态导入并取出"与文件名同名"的函数注册进_funcs(plugin.py)。因此code1对应 plugins/code1.py,httpget对应 plugins/httpget.py;
  6. 同步/异步兼容execute_plugin通过inspect.iscoroutinefunction判断,异步函数await调用,同步函数直接调用(plugin.py)。

4.2 最小可运行配置

以官方插件示例code1为例,配置user_key_word_dict即可(会自动插入key_word_dict):

{ "user_key_word_dict": { "测试自定义口令": "exec#code1(\"hello\")", "测试链接": "exec#httpget(\"https://github.com/hanxi/xiaomusic\")" } }

同时必须在active_cmd中配上口令对应的动作值用于唤醒:

"active_cmd": "play,set_random_play,playlocal,play_music_list,play_music_list_index,stop_after_minute,stop,测试自定义口令"

active_cmd的作用(见 Issue 105 评论 20):决定在 xiaomusic 未播放时,哪些命令可以唤醒 xiaomusic 接管处理。从 command_handler.py 看,当设备未在播放且非控制面板来源时,若opvalueopkey都不在active_cmd_arr中,该命令会被忽略。

插件本体放在plugins/目录下,文件内的函数名必须与文件名一致。仓库自带的官方示例 plugins/code1.py 展示了如何拿到用户语音原文并让音箱回读:

async def code1(arg1): global log, xiaomusic log.info(f"code1:{arg1}") did = xiaomusic.get_cur_did() await xiaomusic.do_tts(did, "你好,我是自定义的测试口令") query = xiaomusic.command_handler.last_cmd.strip() await xiaomusic.do_tts(did, f"你说的是: {query}")

关键点:

  • global log, xiaomusic是插件运行时的约定注入变量(由PluginManager._load_plugins注入模块命名空间);
  • xiaomusic.get_cur_did()获取当前说话设备(xiaomusic.py);
  • xiaomusic.command_handler.last_cmd保存了最近一次语音输入原文(command_handler.py),插件内部自行做前缀切割即可实现“口令 + 参数”的玩法;
  • do_tts(did, value)让指定设备说话(xiaomusic.py),早期版本签名是do_tts(value),重构后必须传did(Issue 105 评论 3 正是这个报错)。

httpget则演示了"用语音触发一次 HTTP 请求",可用来对接任意 REST 服务:

import requests def httpget(url): global log response = requests.get(url, timeout=5) # 增加超时以避免长时间挂起 response.raise_for_status() # 如果响应不是200,引发HTTPError异常 log.info(f"httpget url:{url} response:{response.text}")

容器部署时需将plugins/目录挂载出来,才能让自定义插件文件生效。

五、社区验证的完整方案:getmy_playlist 插件

Issue 269 的评论 13 给出了经过真机验证的完整方案:一个名为getmy_playlist.py的插件,通过 NeteaseCloudMusicApi 拉取歌单并注入 xiaomusic 内存,让"网易云歌单"直接变为"语音歌单"。

5.1 它的工作方式

插件核心逻辑(要点提炼自 Issue 269 中的完整代码):

  • 支持两种入参:uid(拉取该用户全部歌单)与playlist_id(拉取单个歌单);
  • 通过{api_host}/user/playlist?uid={uid}获取用户歌单列表,再对每个歌单调用{api_host}/playlist/detail?id={id}获取曲目;
  • 对每首歌构造播放地址{api_host}/song/url?id={id}&br=350000&realIP=...&proxy=...
  • 写入三个关键数据结构:
    • xiaomusic.all_music[name] = url:把歌曲名映射到播放地址;
    • xiaomusic.all_music_tags[name] = {...}:写入标题、歌手、专辑、封面等元数据(picturemusic['al']['picUrl']);
    • xiaomusic.music_list[list_name] = one_music_list:把歌单名映射到歌曲名列表;
  • 最后调用xiaomusic.try_save_tag_cache()保存标签缓存。

5.2 关键参数与接线方式

setting.json中用user_key_word_dict绑定口令(注意 Issue 269 中演示的口令动作值是exec#getmy_playlist(playlist_id=12758992225)):

"user_key_word_dict": { "获取歌单": "exec#getmy_playlist(playlist_id=12758992225)" }

同时在active_cmd末尾追加获取歌单(示例完整active_cmd见 Issue 269 评论 13)。部署要点如下:

事项说明
API 服务本地/局域网运行 NeteaseCloudMusicApi(可用gnehs/neteasecloudmusicapi-docker镜像部署)
播放地址song/url接口按歌曲 ID 换直链;proxy=HTTP:%2F%2F127.0.0.1:8080参数配合 UnblockNeteaseMusic 解锁灰色歌曲
触发方式对小爱音箱说"获取歌单",或将此口令挂到米家"我回来了"智能场景自动触发
局限性歌曲地址时效性强;网易侧 API 变动可能导致取不到播放地址(见 Issue 269 评论 15-17),此时可退化为"用 yt-dlp 全量下载后本地播放"

5.3 为什么推荐"生成 JSON 再提交"

Issue 269 的作者 hanxi 在评论 5 中的评价值得注意:直接改接口强改歌单保存逻辑不太通用,更通用的做法是生成 JSON,再用现有接口提交 JSON。这与 Issue 312 中netease-playlist"生成歌单配置"的思路完全一致——把 xiaomusic 当作消费方,而不是去改它的内部逻辑。

六、常见问题与避坑清单

综合 Issue 312 / 269 / 105 的社区反馈,整理以下实战避坑点:

  1. 口令不触发:检查active_cmd是否已包含该口令对应的值或口令本身(评论多次确认"需要在 active_cmd 里配一下才能正常唤醒");
  2. 自定义口令无法覆盖默认口令user_key_word_dict只能以插入方式添加,不能删除系统默认口令(如"播放歌曲");如需改动,去网页后台设置页改(Issue 105 评论 14-17);
  3. 插件函数卡死整个服务:插件内不要写阻塞型死循环;长任务用asyncio.sleep让步,并另写一个口令杀掉对应 task(Issue 105 评论 25-29);
  4. do_tts报缺少value参数:旧版本签名问题,升级到修复后的版本即可;
  5. 拿不到播放地址:网易 API 变动会导致song/url失效,需要更新 API 服务或改用下载方案(Issue 269 评论 15-17);
  6. Docker 部署注意:插件目录要挂载;ARM 设备需确认镜像是否提供对应架构(Issue 269 评论 19-21);
  7. 歌曲时长获取不到:部分 m4a / 流媒体格式无法解析时长,会影响自动切歌,可配合remove_id3tagconvert_to_mp3等配置规避(Issue 78 评论 7-13)。

七、总结

围绕"网易云歌单同步"这一需求,xiaomusic 生态给出了从轻到重的完整方案谱系:

  • 只想下载/离线播放,用独立工具netease-playlist(Issue 312 推荐);
  • 想要实时同步、语音可控,写一个自定义口令插件(Issue 105 + 269 的getmy_playlist是经过真机验证的参考实现);
  • 播放电台、m3u8 或在线流媒体,直接用网络歌单 JSON原生能力(Issue 78)。

无论选哪条路,其底层都共享同一套契约:把歌单数据规整为"歌单名 → 歌曲名 → 播放地址"结构,要么通过配置文件、要么通过all_music/music_list等内存结构注入 xiaomusic。理解这条契约,你就能把 QQ 音乐、Apple Music 等任何平台歌单用同样的思路接入小爱音箱。

相关参考:

  • 插件运行机制源码
  • 口令匹配源码
  • 配置合并源码
  • 官方示例插件 code1 / httpget
  • 歌单 JSON 格式说明

【免费下载链接】xiaomusic使用小爱音箱播放音乐,音乐使用 yt-dlp 下载。项目地址: https://gitcode.com/GitHub_Trending/xia/xiaomusic

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询