Administrator
发布于 2025-12-28 / 3 阅读
0
0

16.【重大BUG】XiaoMusic 使用者必看

如果你列表刷新后看到这个~~~(证明前面的部署很成功,但是,你用小爱音箱播放唤醒的时候,会发现必须手动点击一次相关专辑/列表中的歌曲,下一次,小爱音箱才能准确捕获这个专辑名称)

基本原理是没有首次播放,小爱音箱的轮询,找不到继续播放歌曲的地址

所以你们得手动点击播放专辑里面的任意一首歌,或者用语音 本地播放专辑里面的一首歌(用全名 精准匹配),下一次就能找到这个专辑了~~ 具体解释如下:


这是 XiaoMusic v0.3.102 版本的一个代码逻辑 Bug

你的分析完全正确:因为是新上传的专辑,playlist2music(播放进度记忆字典)里没有这个专辑的记录,而代码在执行“语音播放列表”指令时,没有做“找不到记录就从头播放”的容错处理,直接报错 KeyError 崩溃了。

这就导致了所谓的“必须点一下才能用”——因为点一下(或者播放该专辑任意一首歌)就会生成这条记录。

要实现你想要的**“一蹴而就,默认自动锁定第一首”,最彻底的办法是修复这行代码**。鉴于你是 NAS Docker 部署,这里有两个解决层级:

方案一:硬核修复(彻底解决,推荐)

既然你已经能看日志了,我相信你有能力运行一条命令。我们可以通过修改 Docker 容器内的 Python 代码,把这个 Bug 补上。

这个修复会让系统逻辑变成:“如果有播放记录就续播,如果没有记录(KeyError),就默认从头播”。

操作步骤:

  1. 进入 Docker 终端

    在你的 NAS SSH 或者 Docker 管理界面(如 Portainer / 群晖 Docker 终端)中,打开 xiaomusic 容器的 终端 (Terminal / sh)。

  2. 执行修复命令

    在容器的终端里,直接复制粘贴运行下面这行命令(这行命令的作用是把代码中的 [list_name] 强制读取方式改为 .get(list_name) 安全读取方式):

    Bash

    sed -i "s/music_name = self.device.playlist2music\[list_name\]/music_name = self.device.playlist2music.get(list_name)/" /app/xiaomusic/xiaomusic.py
    
  3. 重启容器

    修复完成后,重启一下 XiaoMusic 容器让代码生效。

验证效果:

重启后,上传一个全新的专辑(比如《魔杰座》),直接喊 “小爱同学,播放列表 魔杰座”。

  • 修复前: 报错 KeyError

  • 修复后: 代码获取到的进度是 None,通常后续逻辑会自动识别为“从第1首开始”,系统不再崩溃,直接播放。


方案二:迂回战术(如果不方便改代码)

如果你不想动代码,或者上面的命令无效,你只能改变“第一次交互”的习惯。

不要喊“播放列表”,改喊“播放歌曲”。

  • 逻辑: “播放列表 [专辑名]” 这个指令会触发断点续播逻辑(也就是导致崩溃的逻辑)。

  • 新习惯: 每次上传完新专辑,第一次听的时候,对小爱说:

    “播放歌曲 [该专辑的第一首歌名]”

    • 例如:上传《魔杰座》后,喊 “播放歌曲 龙战骑士”

只要这一首歌播放成功,XiaoMusic 就会在后台生成《魔杰座》的播放记录。哪怕只播了一秒,你下次再喊“播放列表 魔杰座”,它就有记录可查,不会再报错了。

总结

你遇到的问题不是配置能解决的,是程序容错率低导致的。

建议使用 方案一,一条命令一劳永逸,以后上传新专辑直接喊列表名即可,系统会自动因为找不到记录而从第一首播起。


这是一个非常清晰的 代码逻辑 Bug,直接定位到了问题的核心。

问题诊断:为什么会报错?

根据你提供的日志:

KeyError: '叶惠美' 出现在 music_name = self.device.playlist2music[list_name] 这一行。

通俗解释:

  1. 当你喊“播放列表 叶惠美”时,XiaoMusic 的逻辑是:“好的,我去看看《叶惠美》这个列表上次播放到哪首歌了,我要继续播放。”

  2. 它去读取 playlist2music(播放进度记忆字典)这个小本本。

  3. 但是! 因为《叶惠美》是你刚上传的新专辑,你在网页上从没点过它,所以这个小本本里没有“叶惠美”的记录。

  4. 代码里缺少了“如果找不到记录,就默认从第一首播”的容错逻辑,导致程序直接崩溃(KeyError)。

简单来说:它想“断点续播”,但因为它没播过,所以它崩了。


一蹴而就的解决办法(3选1)

既然这是代码逻辑漏洞,我们得用“侧面突围”的方法来初始化这个记录。

方法一:改变第一次的语音指令(最推荐,无需改代码)

不要直接喊“播放列表”,而是先点播该专辑的任意一首单曲

  • 错误指令(第一次): “小爱同学,播放列表 叶惠美” -> 崩溃(因为它在找历史记录)。

  • 正确指令(第一次):

    “小爱同学,播放歌曲 以父之名”

    • 注:《以父之名》是该专辑的第一首。

  • 原理: “播放歌曲”走的是另一套逻辑,它找到歌后会播放,并顺手把“叶惠美”这个专辑和“以父之名”这首歌写入到那个记忆小本本里

  • 之后: 一旦播出了声,下次你再喊“播放列表 叶惠美”,它就能找到记录了,也就不会崩了。

方法二:API 自动化初始化(彻底自动化)

如果你是写脚本上传文件的,可以在上传完成后,用 API 强制“初始化”一下这个专辑的播放进度。

你需要构造一个请求,告诉系统:“把《叶惠美》的当前歌曲设为第一首”,但不需要真的播放出来(或者顺便播放)。

你需要调用 /cmd?cmd=play_music&arg=... 接口。

假设你的第一首歌路径是 music/叶惠美/01.以父之名.mp3。

你可以运行这个命令(或在浏览器打开):

Plaintext

http://192.168.5.178:5678/cmd?cmd=play&arg=以父之名

(注意:这里用 play 模糊搜索歌曲是最简单的,只要能命中该专辑内任意一首歌即可)

方法三:修改 setting.json (不推荐,太麻烦)

这个方法就是你在 image_ef5148.png 里看到的文件。手动在 playlist2music 里加一行:

"叶惠美": "周杰伦-以父之名"

(极度不推荐,因为容易改坏 JSON 格式,且无法自动化)。


总结

这个问题不是你的错,是 0.3.102 版本对新上传文件夹的“断点续播”逻辑没写完善

以后上传新专辑后的标准动作:

  1. 上传文件。

  2. 喊:“小爱同学,刷新列表”。

  3. 喊:“小爱同学,播放歌曲 [该专辑第一首歌名]”(只需第一次这么做)。

  4. 以后就可以随意喊“播放列表 [专辑名]”了。


评论