Skip to content

歌词偶尔不显示(重启或切歌后恢复)+ 歌词段落与实际演唱整体错位(Apple Music) #86

Description

@study-png

环境:Win11,主要用 Apple Music(商店版),NSD 2.4.6(issue #77 里那个测试包,2.4.5 也一样复现)

遇到两个歌词相关的问题:

1. 有时候启动后歌词不显示,重启 NSD 或切到下一首就恢复了

媒体控制一切正常,就是没歌词。个人猜测是启动时机的问题:NSD 是开机自启的,第一次轮询到歌曲的时候网络可能还没就绪。看了下代码,WidgetIsland.vue 的 syncMusicStatus 里,fetch_netease_lyrics 只在 isNewTrack 分支里发一次,而 currentBaseInfo 在发请求的同时就被赋值了,之后每 2 秒的轮询看到"还是这首歌"就永远不会重试。Rust 那边三个歌词引擎(QQ → 网易云 → LRCLIB)是串行的、各 4 秒超时,网络冷启动时全超时的话 .catch 直接吞掉,这首歌就没词了。重启 NSD 后 currentBaseInfo 清空,当前歌重新按新歌走一遍流程就又能拉到了,和实际表现一致。

对比了一下,封面那边有 scheduleCoverRetry(5 秒一次最多重试 4 次),歌词没有对应的重试机制,感觉是漏了。

2. 歌词能显示、也是当前这首的词,但显示的段落和实际唱的对不上,整首都是偏的,切下一首可能又正常了

不是串到别的歌,就是同一首歌内部时间轴错位,段落整体超前或滞后。看代码怀疑两个点:

一是歌词版本选错了。music_controller.rs 的 search_song_meta 里,QQ 引擎(第一优先)的匹配条件是 name_match && (artist_match || |时长差|≤3s),也就是说只要歌手对得上就完全不看时长,而且遍历候选时第一个命中就直接返回。同名同歌手的不同版本(Live、专辑版、单曲版、精粹版之类)段落起点经常差十几秒,我在 Apple Music 里放的版本和 QQ/网易云曲库里的版本对不上时,拉回来的 LRC 时间轴整首都是偏的。网易云那边虽然是按时长差最小挑的,但 QQ 先命中就轮不到它。

二是进度推算可能重复计算。fetch_netease_music_info 里 position = SMTC Timeline 的 Position + (now - LastUpdatedTime) 的外推补偿,这个假设是"Position 冻结在 LastUpdatedTime 那一刻";如果播放器实际是"持续刷新 Position、但 LastUpdatedTime 很少更新"的写法,补偿就会重复叠加,position 系统性偏大。前端同歌校准(误差超过 800ms 才校一次,一次拉回 positionMs-250)会不断跟着这个错误值走,于是整首都错位。这个和播放器的 SMTC 实现习惯有关,也解释了为什么时好时坏。

修复建议

  1. 歌词拉取失败时重试,可以直接参考封面 scheduleCoverRetry 的模式;
  2. QQ 引擎把时长校验改成硬条件(歌手命中时也校时长),或者像网易云那样在所有通过初筛的候选里按时长差最小的挑;
  3. 进度外推加保护:比如连续两次轮询发现原始 Position 在前进,就直接用最新 Position、跳过 LastUpdatedTime 外推;或者给外推量设个上限。

感谢!2.4.6 的双屏修复和悬停唤出都很好用👍

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't working

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions