xiaomusic 歌单直连音箱:基于 LX Sync Server 实现平台歌单到小爱音箱的在线播放
【免费下载链接】xiaomusic使用小爱音箱播放音乐,音乐使用 yt-dlp 下载。项目地址: https://gitcode.com/GitHub_Trending/xia/xiaomusic
导读
本文围绕 GitHub 项目 xiaomusic 中 Issue #807「是否能实现平台歌单到音箱的播放」 的需求展开,系统讲解如何借助 LX Sync Server(洛雪同步服务)把网易云、QQ 音乐等平台的歌单直接接入 xiaomusic,无需再手动下载歌曲、上传云盘再挂载目录,即可在小爱音箱上按口令在线播放整张歌单。读完本文,你将掌握 LX Server 对接配置、洛雪歌单同步(pull)与转换(convert)、自动转换定时任务以及语音搜歌单的完整链路,并了解其背后的源码实现。
一、需求背景:从“本地下载播放”到“在线歌单播放”
在 docs/issues/807.md 中,用户提出了一个典型场景:服务器以 Docker 方式部署 xiaomusic 并通过公网访问,本地挂载目录存放已下载的歌曲,同时自建了 LX Sync Server 服务,且已验证“在线音乐搜索”功能可用。但用户面临一个痛点:
如果发现好听的歌单,都是通过一些软件把歌曲下载下来,然后上传云盘,再在服务器内通过脚本下载对应歌曲,挂载目录到容器内……步骤很繁琐。
即:平台歌单 → 本地下载 → 上传云盘 → 服务器脚本下载 → 挂载目录 → 音箱播放,链路冗长且依赖本地存储。用户希望直接借助“在线音乐搜索”生成可播放的在线歌单,在音箱上播放,并提出了两种猜想:
- 通过歌单转换工具,利用 LX Sync Server 将平台歌单转为可识别的在线歌单配置;
- 直接通过 LX Sync Server 获取账号下的歌单列表,在音箱播放。
作者 hanxi 在评论中确认:当时“缺少一个歌单转换工具,现在网络歌单的基建是支持的”,并明确“LX Sync Server 已经提供了获取用户歌单列表信息的接口,但还没对接。先只对接了基础的搜索歌曲+播放链接的接口。后续可以加上获取洛雪歌单的功能,以及将洛雪歌单转为 xiaomusic 网络歌单的功能。”评论 10 最终宣布该需求落地:
已支持,请升级到作者发布的 v0.5.1 及后续版本。
这意味着:从 v0.5.1 起,平台歌单 → LX Sync Server → xiaomusic 在线歌单 → 小爱音箱播放 的完整链路已经成为现实功能,下文将基于仓库源码逐一拆解其实现与用法。
二、核心链路总览:洛雪歌单如何流向音箱
结合 xiaomusic/online_music.py 与 xiaomusic/js_plugin_manager.py 的源码,这条链路由四个阶段组成:
洛雪音乐客户端(登录平台账号) │ 同步歌单到 LX Sync Server ▼ LX Sync Server (/user/list 获取用户歌单) │ pull_lxserver_playlist() 拉取 ▼ plugins-config.json (lx_server_info.music_list_json) │ convert_lxserver_playlist() 转换 ▼ setting.json (music_list_json 中的 _online_lx_* 歌单) │ gen_all_music_list() 生成播放列表 ▼ 小爱音箱播放(语音口令搜索歌单 / 前端歌单页)- 同步(Pull):从 LX Server 的
/user/list接口拉取当前账号的「我喜欢的音乐」「默认歌单」以及全部自定义歌单(userList); - 转换(Convert):将洛雪歌单中的歌曲转换为 xiaomusic 的
music_list_json条目,生成以_online_lx_前缀命名的网络歌单; - 播放(Play):转换后的歌单进入本地音乐列表体系,音箱即可通过口令点播,播放时通过代理接口实时解析在线链接。
三、前置条件与 LX Server 配置
3.1 前置条件
在开始前需满足:
- 部署并运行 xiaomusic(Docker 或源码运行均可);
- 自建可访问的 LX Sync Server 服务,并保证 xiaomusic 所在环境能够访问其
base_url; - 洛雪音乐客户端已登录目标音乐平台账号,并开启歌单同步;
- xiaomusic 版本不低于 v0.5.1(歌单对接能力自此版本加入,后续版本持续完善)。
3.2 配置项说明
LX Server 的配置存储在插件配置文件plugins-config.json中,仓库提供了模板 xiaomusic/plugins-config-example.json,核心结构如下:
{ "lx_server_info": { "base_url": "", "x-user-name": "", "x-user-token": "", "auto_convert": false, "platforms": { "tx": "小秋音乐", "kg": "小枸音乐", "kw": "小蜗音乐", "wy": "小芸音乐", "mg": "小蜜音乐" }, "box_play_platform": "all" } }| 配置项 | 含义 | 说明 |
|---|---|---|
base_url | LX Sync Server 服务地址 | 例如http://127.0.0.1:23331,留空时在线搜索会返回“LX Server接口未配置!” |
x-user-name | LX Server 用户名 | 与x-user-token一起用于构建请求认证头 |
x-user-token | LX Server 用户令牌 | 由 js_plugin_manager.py 的_build_lx_server_headers组装为认证请求头 |
auto_convert | 自动转换开关 | 开启后由后台定时任务周期性「同步+转换」洛雪歌单 |
platforms | 可用平台字典 | key 为平台标识(如tx/kg/kw/wy/mg),value 为平台展示名,用于聚合搜索与歌单搜索 |
box_play_platform | 语音口令平台偏好 | 语音播放/搜歌单时优先使用的平台,all表示不限定 |
注意:仓库中该示例的平台名“小秋音乐”等是示例占位,实际平台以 LX Sync Server 返回为准。
3.3 后台 API 配置接口
除直接编辑配置文件外,前端设置页也提供了完整的配置入口,对应路由见 xiaomusic/api/routers/plugin.py:
GET /api/lxServer/test:测试 LX Server 接口连通性(调用/music/config);GET /api/lxServer/load:读取当前 LX Server 配置;POST /api/lxServer/toggle:切换接口开关;POST /api/lxServer/updateUrl:更新base_url;POST /api/lxServer/updatePlatforms:更新平台列表;POST /api/lxServer/updateAuth:更新用户名与 Token(x-user-name/x-user-token)。
配置完成后即可在前端测试连通性。后端通过OnlineMusicService(xiaomusic/online_music.py)统一调度:当api_type=2或插件管理器判定使用 LX Server 时,搜索歌曲、搜索歌单、获取歌单详情、获取播放直链、获取歌词全部走 LX Server 接口,否则回退到 MusicFree 插件体系。
四、同步洛雪歌单:Pull 用户歌单数据
LX Sync Server 提供/user/list接口,返回当前账号下的三类歌单数据:loveList(我喜欢的音乐)、defaultList(默认歌单)、userList(自定义歌单列表)。
4.1 同步入口
后端同步逻辑实现在pull_lxserver_playlist()(xiaomusic/js_plugin_manager.py L1706-L1815),通过GET {base_url}/user/list携带认证头获取数据,处理要点如下:
- 对空歌单做清理:
loveList、defaultList为空数组时直接从结果中移除; - 对
userList中的每个歌单统计歌曲数量并写入songCount字段,过滤掉空歌单; - 将处理后的完整歌单数据以 JSON 字符串形式写入
lx_server_info.music_list_json,并回写plugins-config.json; - 返回同步结果摘要,例如“拉取成功,共 N 个歌单”,日志中会列出每个歌单的歌曲数量。
前端同步按钮对应GET /api/lxServer/pullPlaylist路由(xiaomusic/api/routers/plugin.py L307-L313)。前端实现可参考 xiaomusic/static/onlineSearch/setting-lxserver.js,它会先请求GET /api/lxServer/userList展示本地缓存的歌单列表,再通过“同步LX歌单”按钮拉取最新数据。
4.2 本地歌单读取
get_local_lxserver_user_list()(xiaomusic/js_plugin_manager.py L459-L477)负责读取已缓存的music_list_json,若尚未同步会返回提示“请先点击「同步LX歌单」获取歌单数据”。该接口由GET /api/lxServer/userList暴露给前端渲染歌单选择界面。
五、转换洛雪歌单为 xiaomusic 网络歌单
5.1 转换规则
convert_lxserver_playlist(target_playlists)(xiaomusic/js_plugin_manager.py L1817-L1916)完成「洛雪歌单 → xiaomusic 歌单」的转换:
- 读取本地缓存的
music_list_json; - 读取 xiaomusic 配置文件
setting.json中的music_list_json,并剔除所有以_online_lx_前缀开头的旧歌单(避免重复叠加); - 转换三类歌单并命名:
loveList→ 歌单名_online_lx_我喜欢的音乐defaultList→ 歌单名_online_lx_默认歌单userList中每个自定义歌单 → 歌单名_online_lx_{歌单名称}
target_playlists传None时全量转换;传入歌单名称列表(我喜欢的音乐、默认歌单或 userList 中的歌单名)时只转换指定歌单;- 转换结果写回
setting.json的music_list_json,更新内存配置,并调用music_library.gen_all_music_list()重新生成播放列表。
对应的 HTTP 接口为:
GET /api/lxServer/convertPlaylist?playlists=歌单A,歌单B其中playlists参数可省略,省略时全量转换(xiaomusic/api/routers/plugin.py L316-L330)。
5.2 与用户设想的对应
Issue 评论 2 中 dishuo183 曾建议“网络歌单改为从指定文件夹内的 json 文件导入,本地歌曲和网络歌单存放在一起,不再需要修改 setting.json”。当前实现采用的仍是「写入 setting.json 的music_list_json」方案,但通过_online_lx_前缀与本地歌曲歌单在同一个列表中并存、互不冲突,配合“清空 xiaomusic 中所有_online_lx_前缀歌单”的接口(POST /api/lxServer/clearXiaomusicPlaylists)与“删除指定歌单”接口(POST /api/lxServer/deletePlaylists),可实现对网络歌单的批量管理与重建,效果上等价于“批量导入网络歌单”,且不需要歌单合并工具。
六、自动同步与转换:让歌单保持最新
为避免歌单过期或新增歌曲无法播放,系统提供了自动转换能力。_auto_convert_loop()(xiaomusic/js_plugin_manager.py L1918-L1949)是一个后台定时任务循环:
- 按固定间隔(
_auto_convert_interval)休眠; - 读取配置中的
auto_convert开关,关闭则停止循环; - 校验 LX Server 认证信息(
x-user-name/x-user-token)是否已配置; - 依次执行
pull_lxserver_playlist()(同步)与convert_lxserver_playlist()(转换); - 任一环节失败仅记录告警日志,不影响下一轮重试。
用户只需在设置页开启“自动转换”开关(POST /api/advanced-config/update中的auto_convert字段,见 xiaomusic/api/routers/plugin.py L426-L439),即可保持音箱中的网络歌单与洛雪账号歌单同步更新。
七、语音搜歌单:小爱音箱按口令播放网络歌单
7.1 语音指令链路
转换完成的_online_lx_*歌单已进入统一的播放列表体系,用户可直接对小爱说“播放歌单 XXX”等口令。语音搜歌单的核心实现在online_playlist_play()(xiaomusic/online_music.py L1055-L1128),流程如下:
- 解析语音口令中的歌单关键词;
- 确定搜索平台:取“口令平台偏好”(
box_play_platform),若为all则自动取 LX Server 配置的第一个平台或第一个启用的插件; - 调用
get_playlist_online()搜索歌单(LX Server 走/music/songList/search); - 通过
pick_best_playlist()从候选歌单中挑选最优歌单; - 调用
get_playlist_detail_online()获取歌单全量歌曲(LX Server 走/music/songList/detail); - 将歌曲推送到
_online_iwebplayer_search歌单并立即播放。
7.2 语音搜单策略
高级配置中提供voice_playlist_strategy策略(xiaomusic/plugins-config-example.json L33-L36):
| 取值 | 含义 |
|---|---|
default | 取搜索结果第一条 |
max_songs | 取歌曲数最多的歌单 |
max_plays | 取播放量最高的歌单 |
random | 随机选取 |
八、播放原理:代理链接与在线解析
8.1 在线歌单的 URL 形态
Issue 原文中作者曾引述关键提示:
url是self:///api/proxy/plugin-url?data=开头的,需要配合【OnlineSearch】在线音乐里的 JS 插件使用。
这正是 xiaomusic 在线播放的机制:_get_plugin_proxy_url()(xiaomusic/online_music.py L1282-L1288)将歌曲的插件源数据 JSON 序列化后做 Base64 编码,拼接为
self:///api/proxy/plugin-url?data={base64数据}播放时由后端代理接口解码data,调用对应插件(或 LX Server)实时解析出真实播放地址,从而做到“只要在线音乐服务正常运行,歌单就能一直正常播放”,无需担心下载链接失效。
8.2 播放直链解析与音质降级
当后端判定为 LX Server 时,播放 URL 由_execute_lx_server_music_url()及其下游方法(xiaomusic/online_music.py L219-L366)负责,具有三层保障:
- 缓存检查:先请求
/music/cache/check,命中服务端缓存直接返回; - 音质降级:按
LX_QUALITY_PRIORITY = ["master", "flac24bit", "flac", "320k", "192k", "128k"]优先选择偏好音质,解析失败时自动降低音质重试; - 自动换源:原平台解析失败时,依据歌曲名+歌手名+时长(误差 5 秒内)跨平台搜索同曲,从其他已配置平台(
platforms中除原平台外的项)寻找替代源播放。
此外,_normalize_lx_server_url()会把 LX Server 返回的相对路径 URL 拼接为完整可播放地址(xiaomusic/online_music.py L620-L627)。
8.3 歌单数据的格式转换
_convert_song_list_to_music_items()(xiaomusic/online_music.py L1251-L1280)将外部歌曲条目转换为 xiaomusic 内部music_item格式:优先使用条目自带url,否则回退为插件代理 URL;歌曲名统一为“歌名-歌手”;并在写入前通过_deduplicate_song_list()按“歌名+歌手”去重,避免同歌多版本重复入单。
九、配套的歌单管理接口
转换出的网络歌单与本地歌单共用同一套管理接口(xiaomusic/api/routers/playlist.py):
| 接口 | 作用 |
|---|---|
GET /curplaylist | 查看设备当前播放列表 |
POST /playmusiclist | 播放指定歌单 |
POST /playlistadd/POST /playlistdel | 新增 / 移除歌单 |
POST /playlistupdatename | 修改歌单名称 |
GET /playlistnames | 获取所有自定义歌单 |
POST /playlistaddmusic/POST /playlistdelmusic | 歌单增删歌曲 |
POST /playlistupdatemusic | 更新歌单歌曲 |
GET /playlistmusics | 获取歌单内全部歌曲 |
后端通过OnlineMusicService.get_playlist_online()(xiaomusic/online_music.py L106-L141)同时支持 MusicFree 插件(api_type=1,走/music/songList/search之外由插件自身实现的歌单搜索)与 LX Server(api_type=2)两条歌单搜索通道,前端“在线音乐”页面的搜歌单功能即基于此。
十、FAQ 与注意事项
- 必须升级到 v0.5.1 及以上版本:歌单同步/转换、语音搜歌单等能力自该版本起提供,Issue 作者在评论中明确“已支持,请升级到作者发布的 v0.5.1 及后续版本”。
- LX Server 需能被 xiaomusic 访问:若使用 Docker 部署并配合公网/内网穿透,需确保
base_url指向可达地址,认证头由x-user-name与x-user-token组成(参考 Issue 评论 8 中“内网穿透 HTTPS 分别反代 LXServer 和 xiaomusic 容器端口”的部署实践)。 - 首次使用务必先同步再转换:转换依赖本地缓存的
music_list_json,未同步会返回“请先点击「同步LX歌单」获取歌单数据”。 _online_lx_前缀为系统保留:手动创建歌单时避免使用该前缀,否则可能在转换时被覆盖或清理。- 在线播放依赖服务可用性:播放时实时解析在线链接,只要 LX Server 与音乐平台源正常工作即可持续播放;同时后端已内置缓存、音质降级与自动换源,最大化播放成功率。
结语
从 docs/issues/807.md 的“能否实现平台歌单到音箱播放”的疑问,到 v0.5.1 之后逐步落地的“LX Server 歌单同步 → 格式转换 → 语音口令播放”完整能力,xiaomusic 将原本繁琐的“下载-上传-挂载”流程收敛为一条纯在线的歌单播放链路。对于希望彻底摆脱本地下载、随听随播的用户而言,配置好 LX Sync Server 并在 xiaomusic/static/onlineSearch/index.html 的在线音乐设置页中完成对接,即可让音箱直接播放来自各大平台的整张歌单。
【免费下载链接】xiaomusic使用小爱音箱播放音乐,音乐使用 yt-dlp 下载。项目地址: https://gitcode.com/GitHub_Trending/xia/xiaomusic
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考