新功能(歌词):添加歌词源偏好设置 - #417
Conversation
- add LyricSourcePreference and a dedicated settings page for choosing the default lyric source (automatic / NetEase / Kugou / QQ Music / LRCLIB / AMLL TTML), falling back silently when a source has no match - add a "prefer word-timed lyrics" toggle and thread it through the matcher, playback lyric resolution and the lyrics editor sheet - promote word-timed candidates into their own ranking tier when preferred, and always report hasWordTiming independently of the flag - evict lyric caches when any lyric source setting changes - persist both settings in the playback preference snapshot and sanitize the stored source value
Adding @AutoSettingsSection(order = 66) object lyricSource made AutoSettingsMetadata.sections return 14 entries, which broke the hardcoded 13-entry assertion in AutoSettingsGeneratedTest.generatedMetadataCoversSectionsAndCustomSettings. lyricSource (order 66) sorts between lyrics (65) and network (70). Also assert the new section constant in generatedSectionConstantsCoverSettingsScopes.
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthrough新增逐词歌词偏好和默认歌词来源设置,并将偏好保存到设置存储。歌词匹配会记录逐词时间轴状态,并在启用偏好时调整候选排序。歌词提供器可尝试指定来源,并将结果用于主歌词、翻译和音译查询。播放界面响应偏好变化、显示逐词标记;设置页面新增来源选择和逐词偏好选项。 Priority: ➖ Normal Merge Risk: 🔵 Low · up to With a preferred source selected, lyrics already available for a song may disappear while the app searches online. This is a bounded playback issue to fix or explicitly accept before merging. Security Architecture ReviewSecurity architecture risk: 🟡 Moderate · up to A selected lyric source can be queried before existing per-track lyric decisions are applied. This may disclose song metadata to the selected provider or show lyrics for a track whose downloaded lyrics were cleared. Preference changes may also leave an older lyric result visible briefly. The exposure is limited to this app’s lyric flow; no new service credentials or privileged access were identified. Retained concerns
Security review detailsSecurity Blast Radius
Security Findings and Attack Paths
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 2.63% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 76 functions across 22 files. (9 skipped: 9 unsupported.) Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Note
Quiet mode is enabled, so only the most important comments were posted inline. Other review comments are grouped below.
Caution
Some comments are outside the diff and can’t be posted inline due to GitHub limitations.
⚠️ Outside diff range comments (1)
app/src/main/java/moe/ouom/neriplayer/core/api/lyrics/EditableLyricsMatcher.kt (1)
97-100: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win让
lowConfidenceMatches使用统一结果比较器排序。当
preferWordTimed为true时,当前排序不会比较hasWordTiming;matchLyrics还会先拼接rankedMatches,因此逐词候选可能排在逐行候选之后。请在去重后使用editableLyricMatchResultComparator,并传入normalizedRequest.preferWordTimed、editableLyricMatchSourcePriority和来源兜底排序。这样可以保留现有的置信度、分数、时长及来源排序规则,同时确保逐词候选优先。
🟡 Other comments (2)
app/src/main/java/moe/ouom/neriplayer/core/player/metadata/PlayerLyricsProvider.kt-1028-1041 (1)
1028-1041: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win让
defaultLyricSource作用于 YouTube Music 曲目
LyricSourcePreference定义为播放期间优先使用的歌词来源,但 YouTube Music 分支在调用getYouTubeMusicLyrics后立即返回,完全跳过该设置。请将defaultLyricSource传入该分支,并处理包括AmllTtml在内的可选来源;否则用户选择的来源对 YouTube Music 曲目无效。app/src/main/java/moe/ouom/neriplayer/core/player/metadata/PlayerLyricsProvider.kt-1102-1106 (1)
1102-1106: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win保留
matchHighConfidenceLyricsForSource的排序结果
resolvePreferredLyricSourceEntries已将preferWordTimed传给 matcher。matcher 会用editableLyricMatchResultComparator将逐词歌词置于前面,但这里的automaticExternalLyricMatchComparator()会再次排序,且不检查hasWordTiming。启用逐词偏好时,firstOrNull()可能因此选择逐行歌词。删除此处的二次排序,直接使用 matcher 返回的顺序。
🧹 Nitpick comments (1)
app/src/main/java/moe/ouom/neriplayer/core/player/metadata/PlayerLyricsProvider.kt (1)
1074-1120: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win为默认歌词源匹配结果增加缓存。
当曲目没有本地、已存储或已下载歌词,且使用非网易云默认源时,
getLyrics每次都会调用matchHighConfidenceLyricsForSource。该方法随后会重复执行远程搜索和歌词详情请求。NowPlayingScreen和歌词编辑器的重复调用会增加网络流量,并延迟歌词显示。现有
neteaseLyricsCache和ytMusicLyricsCache不覆盖此路径。请新增专用缓存,缓存键至少包含曲目标识、歌名、歌手、专用来源和preferWordTimed,并将其加入clearLyricsCaches的失效流程。
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: QUIET
Plan: Advanced
Run ID: c1fe85a2-184a-4ab3-8ab7-37a406dff2a6
⛔ Files ignored due to path filters (2)
README.mdis excluded by!**/*.mdREADME_EN.mdis excluded by!**/*.md
📒 Files selected for processing (24)
app/src/main/java/moe/ouom/neriplayer/core/api/lyrics/EditableLyricMatchPolicy.ktapp/src/main/java/moe/ouom/neriplayer/core/api/lyrics/EditableLyricsMatcher.ktapp/src/main/java/moe/ouom/neriplayer/core/player/PlayerManager.ktapp/src/main/java/moe/ouom/neriplayer/core/player/lifecycle/PlayerManagerLifecycleExtensions.ktapp/src/main/java/moe/ouom/neriplayer/core/player/metadata/PlayerLyricsProvider.ktapp/src/main/java/moe/ouom/neriplayer/core/player/persistence/PlayerManagerPersistenceExtensions.ktapp/src/main/java/moe/ouom/neriplayer/data/config/ConfigSettingsSanitizer.ktapp/src/main/java/moe/ouom/neriplayer/data/settings/AutoSettingsSchema.ktapp/src/main/java/moe/ouom/neriplayer/data/settings/LyricSourcePreference.ktapp/src/main/java/moe/ouom/neriplayer/data/settings/PlaybackPreferenceSnapshot.ktapp/src/main/java/moe/ouom/neriplayer/data/settings/SettingsRepository.ktapp/src/main/java/moe/ouom/neriplayer/ui/screen/NowPlayingScreen.ktapp/src/main/java/moe/ouom/neriplayer/ui/screen/tab/SettingsScreen.ktapp/src/main/java/moe/ouom/neriplayer/ui/screen/tab/settings/component/SettingsLyricSourceSection.ktapp/src/main/java/moe/ouom/neriplayer/ui/screen/tab/settings/page/SettingsPage.ktapp/src/main/java/moe/ouom/neriplayer/ui/screen/tab/settings/page/SettingsSearchIndex.ktapp/src/main/res/values-en/strings_lyrics.xmlapp/src/main/res/values-en/strings_settings_general.xmlapp/src/main/res/values-zh/strings_lyrics.xmlapp/src/main/res/values-zh/strings_settings_general.xmlapp/src/main/res/values/strings_lyrics.xmlapp/src/main/res/values/strings_settings_general.xmlapp/src/test/java/moe/ouom/neriplayer/core/api/lyrics/EditableLyricMatchPolicyTest.ktapp/src/test/java/moe/ouom/neriplayer/data/settings/AutoSettingsGeneratedTest.kt
Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.
|
我甚至觉得能直接合并到歌词设置里面 |
我的意思就是合并到歌词设置里 |
There was a problem hiding this comment.
Note
Quiet mode is enabled, so only the most important comments were posted inline. Other review comments are grouped below.
🟡 Other comments (1)
app/src/main/java/moe/ouom/neriplayer/ui/screen/NowPlayingScreen.kt-3226-3239 (1)
3226-3239: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win在偏好歌词匹配完成前保留已有歌词。
启用
shouldLoadPreferredLyrics时,immediateLyricsState和快速阶段都会发布空歌词。后台任务先等待getPreferredLyricSourceResult,只有该调用完成后才进入本地或平台歌词回退流程。网络请求未立即结束时,已有本地歌词会保持不可见。先发布本地或已存歌词。偏好来源命中后再替换;同时为偏好来源匹配设置有界超时,并在超时后执行回退。
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository: cwuom/NeriPlayer/.coderabbit.yaml
Review profile: QUIET
Plan: Advanced
Run ID: 02daaf61-7c0b-487f-a99c-22dd18085d99
⛔ Files ignored due to path filters (2)
README.mdis excluded by!**/*.mdREADME_EN.mdis excluded by!**/*.md
📒 Files selected for processing (25)
app/src/main/java/moe/ouom/neriplayer/core/api/lyrics/EditableLyricsMatcher.ktapp/src/main/java/moe/ouom/neriplayer/core/player/PlayerManager.ktapp/src/main/java/moe/ouom/neriplayer/core/player/lifecycle/PlayerManagerLifecycleExtensions.ktapp/src/main/java/moe/ouom/neriplayer/core/player/metadata/PlayerLyricsProvider.ktapp/src/main/java/moe/ouom/neriplayer/core/player/persistence/PlayerManagerPersistenceExtensions.ktapp/src/main/java/moe/ouom/neriplayer/data/config/ConfigSettingsSanitizer.ktapp/src/main/java/moe/ouom/neriplayer/data/settings/AutoSettingsSchema.ktapp/src/main/java/moe/ouom/neriplayer/data/settings/LyricSourcePreference.ktapp/src/main/java/moe/ouom/neriplayer/ui/screen/NowPlayingScreen.ktapp/src/main/java/moe/ouom/neriplayer/ui/screen/tab/SettingsScreen.ktapp/src/main/java/moe/ouom/neriplayer/ui/screen/tab/settings/component/SettingsLyricSourceSection.ktapp/src/main/java/moe/ouom/neriplayer/ui/screen/tab/settings/component/SettingsLyricsOffsetSection.ktapp/src/main/java/moe/ouom/neriplayer/ui/screen/tab/settings/page/SettingsSearchIndex.ktapp/src/main/res/values-en/strings_lyrics.xmlapp/src/main/res/values-en/strings_settings_general.xmlapp/src/main/res/values-en/strings_settings_playback.xmlapp/src/main/res/values-zh/strings_lyrics.xmlapp/src/main/res/values-zh/strings_settings_general.xmlapp/src/main/res/values-zh/strings_settings_playback.xmlapp/src/main/res/values/strings_lyrics.xmlapp/src/main/res/values/strings_settings_general.xmlapp/src/main/res/values/strings_settings_playback.xmlapp/src/test/java/moe/ouom/neriplayer/core/player/metadata/PlayerLyricsProviderTest.ktapp/src/test/java/moe/ouom/neriplayer/ui/screen/NowPlayingScreenTest.ktapp/src/test/java/moe/ouom/neriplayer/ui/screen/tab/settings/page/SettingsPageTest.kt
Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

描述 / Description
为歌词补全链路增加「歌词源」设置,让用户能表达两种此前无法表达的偏好:
两个设置的默认值都与改造前完全一致(跟随平台 + 优先逐词),因此不改变现有用户的行为。
类型 / Type
修复或解决的问题 / Issues Fixed or Closed by This PR
背景讨论见 #412(歌词源相关),本 PR 是该讨论中「歌词源」方向的具体实现。
未声称修复该 issue 中关于平台侧逐词歌词覆盖率的讨论。
关键实现点
data/settings/LyricSourcePreference.kt(新增):来源枚举 +LyricSourcePreferencePolicy(存储值归一化、旧值别名、非法值回退)。AutoSettingsSchema.kt:新增@AutoSettingsSection(order = 66) lyricSource,登记prefer_word_timed_lyrics(Boolean,默认 true)与default_lyric_source(String,默认 automatic,带 normalizer)。EditableLyricMatchPolicy.kt:RankedEditableLyricMatch增加hasWordTiming,比较器改为先按词级时间分层、再比较原有匹配分。PlayerLyricsProvider.kt:新增resolvePreferredLyricSourceEntries(...),按偏好重排候选;defaultLyricSource贯穿getYouTubeMusicLyrics与loadDurationMatchedExternalLyrics。PlayerManagerLifecycleExtensions.kt:监听两个偏好变化,清理ytMusicLyricsCache、neteaseLyricsCache与 AMLL 缓存,并触发外部蓝牙歌词重新同步,保证切换后立即生效。SettingsPage.LyricSource与SettingsLyricSourceSection,同步补齐中英文字符串与SettingsSearchIndex搜索关键词。风险与兼容性
automatic+prefer_word_timed_lyrics = true与改造前行为一致,老用户升级后无感知变化。default_lyric_source通过 normalizer 兼容历史/别名取值,非法值回退到automatic;配置导入导出与启动快照(PlaybackPreferenceSnapshot、ConfigSettingsSanitizer)已同步。测试方式
./gradlew :app:testDebugUnitTest :app:lintDebug(3227 个单元测试 + lint 通过)./gradlew :app:connectedDebugAndroidTest(模拟器 connected 测试通过)EditableLyricMatchPolicyTest用例覆盖词级时间分层与默认排序回退AutoSettingsGeneratedTest已登记新增的lyricSourcesection清单 / Checklist
其他信息 / Additional Information
新增设置入口位于「设置 → 歌词源」,包含两个设置项:
新增歌词偏好设置,支持自动、网易云、酷狗、QQ 音乐、LRCLIB 和 AMLL TTML。选择具体来源时,应用会优先尝试该来源;未找到符合条件的歌词时,继续使用原有歌词加载流程。偏好来源匹配要求候选歌词与歌曲时长兼容。
开启“优先使用逐词歌词”后,逐词歌词候选优先于普通歌词;关闭后,应用不再为逐词时间轴覆盖已有歌词,也不再使用 AMLL 补充逐词歌词。设置默认值为自动来源和开启逐词优先。歌词来源选项已并入歌词设置。
新增测试覆盖逐词候选排序、来源偏好尝试条件、时长匹配、首选来源歌词状态及设置搜索定位。未提供这些测试的运行结果。