Skip to content

feat: status bar lyrics#232

Merged
roitium merged 3 commits into
devfrom
feat/status-bar-lyrics
Feb 28, 2026
Merged

feat: status bar lyrics#232
roitium merged 3 commits into
devfrom
feat/status-bar-lyrics

Conversation

@roitium
Copy link
Copy Markdown
Collaborator

@roitium roitium commented Feb 28, 2026

Closes #231

Summary by CodeRabbit

发布说明

  • 新功能

    • 添加状态栏歌词功能(实验性),可在状态栏中实时显示歌词
    • 新增歌曲导出功能
  • 文档

    • 更新歌词设置文档,新增状态栏歌词安装说明和使用指南
    • 重新组织歌词相关设置文档结构
  • 版本更新

    • 版本升级至 2.4.0

Copilot AI review requested due to automatic review settings February 28, 2026 10:36
@roitium roitium added the enhancement New feature or request label Feb 28, 2026
@safedep
Copy link
Copy Markdown

safedep Bot commented Feb 28, 2026

SafeDep Report Summary

Green Malicious Packages Badge Green Vulnerable Packages Badge Green Risky License Badge

No dependency changes detected. Nothing to scan.

This report is generated by SafeDep Github App

@vercel
Copy link
Copy Markdown

vercel Bot commented Feb 28, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
bbplayer-docs Ready Ready Preview, Comment Feb 28, 2026 10:53am

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 28, 2026

Warning

Rate limit exceeded

@roitium has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 14 minutes and 8 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 84e22fe and b86080a.

📒 Files selected for processing (5)
  • apps/mobile/index.js
  • apps/mobile/src/app/settings/lyrics.tsx
  • apps/mobile/src/utils/player.ts
  • packages/orpheus/android/src/main/java/expo/modules/orpheus/service/OrpheusMusicService.kt
  • packages/orpheus/docs/API-Methods.md

Walkthrough

此变更为移动应用新增状态栏歌词功能,集成SuperLyricApi库。包括文档更新、Android原生模块扩展(StatusBarLyricsManager类、存储管理)、UI设置界面和播放器逻辑调整,以及配置和依赖更新。

Changes

Cohort / File(s) Summary
文档更新
apps/docs/docs/guides/lyrics.md, apps/docs/docs/guides/settings.md
将歌词设置路径调整、新增"状态栏歌词"部分说明与安装指引、将歌词相关选项组织到独立的"歌词设置"章节。
移动应用配置和版本
apps/mobile/package.json, apps/mobile/app.config.ts, apps/mobile/CHANGELOG.md
版本号从2.3.2升至2.4.0;Android minSdkVersion设为26;ProGuard配置新增SuperLyricApi规则;CHANGELOG新增状态栏歌词和导出歌曲两项。
移动应用UI与播放器逻辑
apps/mobile/src/app/settings/lyrics.tsx, apps/mobile/src/utils/player.ts
新增状态栏歌词UI开关及其启用/禁用逻辑;优化桌面歌词设置流程以立即应用当前曲目;调整payload构建方式支持同步推送至statusBarLyrics;缩减防抖延迟从1000ms至300ms。
Android原生存储和工具类
packages/orpheus/android/src/main/java/expo/modules/orpheus/util/GeneralStorage.kt, packages/orpheus/android/build.gradle
新增isStatusBarLyricsEnabled存储和访问方法;gradle依赖新增SuperLyricApi库(2.4版本)。
Android原生管理器
packages/orpheus/android/src/main/java/expo/modules/orpheus/manager/StatusBarLyricsManager.kt
全新StatusBarLyricsManager类,管理状态栏歌词与SuperLyric服务的同步,包含歌词排序、时间同步、行索引跟踪、SuperLyricData构建及推送、节流日志等逻辑。
Android原生服务与模块导出
packages/orpheus/android/src/main/java/expo/modules/orpheus/service/OrpheusMusicService.kt, packages/orpheus/android/src/main/java/expo/modules/orpheus/ExpoOrpheusModule.kt, packages/orpheus/src/ExpoOrpheusModule.ts
OrpheusMusicService新增statusBarLyricsManager字段及其初始化、生命周期集成;ExpoOrpheusModule新增isStatusBarLyricsEnabled、isSuperLyricApiEnabled属性及setStatusBarLyrics异步方法;TypeScript导出层同步新增对应属性与方法声明。

Sequence Diagram(s)

sequenceDiagram
    participant User as 用户
    participant UI as 设置UI
    participant Bridge as Orpheus Bridge
    participant Service as OrpheusMusicService
    participant Manager as StatusBarLyricsManager
    participant SuperLyric as SuperLyricApi

    User->>UI: 启用状态栏歌词开关
    UI->>Bridge: setStatusBarLyricsEnabled(true)
    Bridge->>Service: 更新enable状态
    Service->>Manager: enabled = true
    
    Note over UI: 获取当前播放曲目
    UI->>Bridge: setStatusBarLyrics(lyricsJson)
    Bridge->>Manager: setLyrics(parsedData)
    Manager->>Manager: 按时间戳排序歌词
    
    Note over Service: 播放中...
    Service->>Manager: updateTime(currentSeconds)
    Manager->>Manager: 计算当前行索引
    Manager->>Manager: 构建SuperLyricData
    Manager->>SuperLyric: onSuperLyric(data)
    SuperLyric->>SuperLyric: 状态栏显示歌词
    
    User->>UI: 禁用状态栏歌词开关
    UI->>Bridge: setStatusBarLyricsEnabled(false)
    Bridge->>Manager: enabled = false
    Manager->>SuperLyric: onStop()
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • feat: desktop lyrcis #122: 修改了相同的setDesktopLyrics逻辑和payload处理流程,涉及播放器utilities的核心改动
  • feat: native player #97: 扩展了Orpheus原生模块集成,此PR的新增API导出与Native层改动直接相关联

Poem

🐰 状态栏绽放歌词光,
SuperLyric通道已开放,
播放跳转实时更新忙,
防抖减速反应更敏,
梦想的歌词在屏顶唱!🎵

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.56% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR标题清晰简洁,准确概括了主要变更内容:添加状态栏歌词功能。标题与changeset内容高度相关,是最重要的变更点。
Linked Issues check ✅ Passed PR实现了issue #231中请求的状态栏歌词功能,集成了SuperLyric以在状态栏显示歌词,包括Android端完整实现和前端UI集成。
Out of Scope Changes check ✅ Passed 所有变更都与状态栏歌词功能相关,包括文档更新、Android依赖添加、UI实现和版本更新,均在PR目标范围内。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/status-bar-lyrics

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Android status-bar lyrics support by integrating with the SuperLyric Xposed module, exposing new native module APIs/properties and wiring them into the mobile app’s lyrics pushing + settings UI.

Changes:

  • Introduce StatusBarLyricsManager and push timed lyric updates to SuperLyric (Android).
  • Add new Orpheus native module properties/APIs (isStatusBarLyricsEnabled, isSuperLyricApiEnabled, setStatusBarLyrics) and persist the enable flag.
  • Update mobile app to toggle status-bar lyrics and push lyrics payload to either/both desktop overlay and status bar.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/orpheus/src/ExpoOrpheusModule.ts Adds TS surface for new status-bar lyrics flags/API.
packages/orpheus/android/src/main/java/expo/modules/orpheus/util/GeneralStorage.kt Persists config_status_bar_lyrics_enabled in MMKV.
packages/orpheus/android/src/main/java/expo/modules/orpheus/service/OrpheusMusicService.kt Creates/updates StatusBarLyricsManager on playback tick and lifecycle events.
packages/orpheus/android/src/main/java/expo/modules/orpheus/manager/StatusBarLyricsManager.kt New manager that maps lyric timing → SuperLyric push calls.
packages/orpheus/android/src/main/java/expo/modules/orpheus/ExpoOrpheusModule.kt Exposes enable flag, SuperLyric active flag, and setStatusBarLyrics to JS.
packages/orpheus/android/build.gradle Adds SuperLyricApi dependency.
apps/mobile/src/utils/player.ts Pushes lyrics payload to desktop overlay and/or status bar; reduces debounce delay.
apps/mobile/src/app/settings/lyrics.tsx Adds status-bar lyrics toggle and “push immediately” behavior.
apps/mobile/package.json Bumps mobile app version to 2.4.0.
apps/mobile/app.config.ts Raises Android minSdk to 26 and adds R8 keep rule for SuperLyricApi.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/orpheus/android/build.gradle
Comment thread apps/mobile/app.config.ts
Comment thread apps/mobile/src/utils/player.ts Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
apps/docs/docs/guides/lyrics.md (1)

61-74: 建议在章节标题中显式标注 Android 平台限制。

当前正文虽提到 Xposed/LSPosed,但标题层面仍可能让 iOS 用户误解。建议改为“状态栏歌词 (Android)”以提升可发现性与预期管理。

✏️ 建议修改
-## 状态栏歌词 (Status Bar Lyric) {`#status-bar-lyric`}
+## 状态栏歌词 (Android) (Status Bar Lyric) {`#status-bar-lyric`}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/docs/docs/guides/lyrics.md` around lines 61 - 74, 把章节标题“## 状态栏歌词 (Status
Bar Lyric) {`#status-bar-lyric`}”改为显式标注 Android 平台,例如“## 状态栏歌词 (Status Bar Lyric)
(Android) {`#status-bar-lyric`}”或“## 状态栏歌词(Android) (Status Bar Lyric)
{`#status-bar-lyric`}”,以避免 iOS 用户误解;保留原有锚点 {`#status-bar-lyric`} 和正文中关于
Xposed/LSPosed 的说明,无需修改链接或正文其他内容。
packages/orpheus/android/src/main/java/expo/modules/orpheus/service/OrpheusMusicService.kt (1)

66-68: 考虑移除或降级开发调试日志。

这些 Log.vLog.d 调用在开发阶段很有用,但在发布版本中可能造成日志冗余。建议在功能稳定后移除或使用 BuildConfig.DEBUG 条件包裹。

Also applies to: 473-473, 489-496

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/orpheus/android/src/main/java/expo/modules/orpheus/service/OrpheusMusicService.kt`
around lines 66 - 68, 在 OrpheusMusicService.kt 中的调试日志(例如
android.util.Log.v/Log.d 调用,包含 player?.playbackState 的 Runnable 以及文件中其他位于大约 473
和 489-496 行的 Log 调用)应在发布版中移除或受条件控制;请将这些 Log.v/Log.d/Log.w 调用用 if
(BuildConfig.DEBUG) { ... }
包裹(或直接删除不再需要的调试日志),以保留开发时输出但避免在生产构建中产生冗余日志,确保修改涵盖所有类似调用点(包括引用
player?.playbackState 的 Runnable)。
packages/orpheus/android/src/main/java/expo/modules/orpheus/ExpoOrpheusModule.kt (1)

820-834: 实现正确,错误处理完善。

JSON 解析和歌词设置的逻辑与 setDesktopLyrics 保持一致。安全调用 instance?.statusBarLyricsManager 正确处理了服务未就绪的情况。

小建议:第 831 行的 e.printStackTrace() 可以移除,因为 Log.e 的第三个参数已经包含了异常堆栈信息。

♻️ 移除冗余的 printStackTrace 调用
             } catch (e: Exception) {
                 Log.e("StatusBarLyrics", "[Module] setStatusBarLyrics parse error: ${e.message}", e)
-                e.printStackTrace()
             }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/orpheus/android/src/main/java/expo/modules/orpheus/ExpoOrpheusModule.kt`
around lines 820 - 834, Remove the redundant e.printStackTrace() call in the
AsyncFunction("setStatusBarLyrics") catch block; keep the existing
Log.e("StatusBarLyrics", "[Module] setStatusBarLyrics parse error:
${e.message}", e) which already logs the exception and stack trace, so delete
the line calling e.printStackTrace() after the Log.e to avoid duplicate stack
output while leaving
OrpheusMusicService.instance?.statusBarLyricsManager?.setLyrics(...) and the
rest of the error handling intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/mobile/src/utils/player.ts`:
- Around line 293-305: The two native calls are in the same try/catch so one
failure prevents the other from running; split them into independent try/catch
blocks: keep the existing check and call to Orpheus.setDesktopLyrics inside its
own try/catch and log errors with toastAndLogError('设置歌词失败:', e, 'Utils.Player')
if it throws, then do the same separately for Orpheus.setStatusBarLyrics guarded
by Orpheus.isStatusBarLyricsEnabled so each can fail without preventing the
other; locate the calls by the identifiers Orpheus.isDesktopLyricsShown,
Orpheus.setDesktopLyrics, Orpheus.isStatusBarLyricsEnabled, and
Orpheus.setStatusBarLyrics.

In `@packages/orpheus/android/build.gradle`:
- Line 53: Add the JitPack repository so the GitHub-hosted dependency
implementation 'com.github.HChenX:SuperLyricApi:2.4' can be resolved: insert a
repositories block containing a maven entry for the URL https://jitpack.io into
the same build.gradle that contains the implementation line, and place that
repositories block before the dependencies block to ensure dependency resolution
succeeds.

---

Nitpick comments:
In `@apps/docs/docs/guides/lyrics.md`:
- Around line 61-74: 把章节标题“## 状态栏歌词 (Status Bar Lyric)
{`#status-bar-lyric`}”改为显式标注 Android 平台,例如“## 状态栏歌词 (Status Bar Lyric) (Android)
{`#status-bar-lyric`}”或“## 状态栏歌词(Android) (Status Bar Lyric)
{`#status-bar-lyric`}”,以避免 iOS 用户误解;保留原有锚点 {`#status-bar-lyric`} 和正文中关于
Xposed/LSPosed 的说明,无需修改链接或正文其他内容。

In
`@packages/orpheus/android/src/main/java/expo/modules/orpheus/ExpoOrpheusModule.kt`:
- Around line 820-834: Remove the redundant e.printStackTrace() call in the
AsyncFunction("setStatusBarLyrics") catch block; keep the existing
Log.e("StatusBarLyrics", "[Module] setStatusBarLyrics parse error:
${e.message}", e) which already logs the exception and stack trace, so delete
the line calling e.printStackTrace() after the Log.e to avoid duplicate stack
output while leaving
OrpheusMusicService.instance?.statusBarLyricsManager?.setLyrics(...) and the
rest of the error handling intact.

In
`@packages/orpheus/android/src/main/java/expo/modules/orpheus/service/OrpheusMusicService.kt`:
- Around line 66-68: 在 OrpheusMusicService.kt 中的调试日志(例如 android.util.Log.v/Log.d
调用,包含 player?.playbackState 的 Runnable 以及文件中其他位于大约 473 和 489-496 行的 Log
调用)应在发布版中移除或受条件控制;请将这些 Log.v/Log.d/Log.w 调用用 if (BuildConfig.DEBUG) { ... }
包裹(或直接删除不再需要的调试日志),以保留开发时输出但避免在生产构建中产生冗余日志,确保修改涵盖所有类似调用点(包括引用
player?.playbackState 的 Runnable)。

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9b44845 and 84e22fe.

📒 Files selected for processing (13)
  • apps/docs/docs/guides/lyrics.md
  • apps/docs/docs/guides/settings.md
  • apps/mobile/CHANGELOG.md
  • apps/mobile/app.config.ts
  • apps/mobile/package.json
  • apps/mobile/src/app/settings/lyrics.tsx
  • apps/mobile/src/utils/player.ts
  • packages/orpheus/android/build.gradle
  • packages/orpheus/android/src/main/java/expo/modules/orpheus/ExpoOrpheusModule.kt
  • packages/orpheus/android/src/main/java/expo/modules/orpheus/manager/StatusBarLyricsManager.kt
  • packages/orpheus/android/src/main/java/expo/modules/orpheus/service/OrpheusMusicService.kt
  • packages/orpheus/android/src/main/java/expo/modules/orpheus/util/GeneralStorage.kt
  • packages/orpheus/src/ExpoOrpheusModule.ts

Comment thread apps/mobile/src/utils/player.ts
}

dependencies {
implementation 'com.github.HChenX:SuperLyricApi:2.4'
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== 查找 SuperLyricApi 依赖声明 =="
rg -n --glob '**/*.gradle' --glob '**/*.gradle.kts' 'SuperLyricApi'

echo ""
echo "== 查找 JitPack 仓库配置 =="
rg -n --glob '**/*.gradle' --glob '**/*.gradle.kts' 'jitpack\.io|https://jitpack\.io'

Repository: bbplayer-app/BBPlayer

Length of output: 213


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== 查找 Gradle 配置文件 =="
fd -e gradle -e 'gradle.kts' --type f | head -20

echo ""
echo "== 检查 settings.gradle 文件 =="
fd -n 'settings.gradle*' --type f

echo ""
echo "== 查看 build.gradle 前60行(仓库配置部分)=="
head -60 packages/orpheus/android/build.gradle

echo ""
echo "== 查看 build.gradle 的 repositories 配置 =="
rg -n --glob '**/*.gradle' 'repositories\s*\{' -A 10

Repository: bbplayer-app/BBPlayer

Length of output: 449


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== 查看 packages/orpheus/android/build.gradle 的 repositories 配置 =="
cat -n packages/orpheus/android/build.gradle | head -80

echo ""
echo "== 搜索所有 repositories 块 =="
rg -n 'repositories\s*\{' -A 15 --glob '**/*.gradle'

Repository: bbplayer-app/BBPlayer

Length of output: 3269


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== 查找项目根目录的 build.gradle 文件 =="
fd 'build.gradle' --maxdepth 2 --type f

echo ""
echo "== 查看根目录 build.gradle (如存在) =="
if [ -f "build.gradle" ]; then
  head -100 build.gradle
elif [ -f "build.gradle.kts" ]; then
  head -100 build.gradle.kts
else
  echo "根目录未找到 build.gradle"
fi

echo ""
echo "== 查看 android 目录下的 build.gradle =="
if [ -f "android/build.gradle" ]; then
  head -100 android/build.gradle
else
  echo "android/build.gradle 不存在"
fi

echo ""
echo "== 列出项目结构 =="
ls -la | head -30
</parameter>

Repository: bbplayer-app/BBPlayer

Length of output: 2192


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== 查找 ExpoModulesCorePlugin.gradle =="
fd 'ExpoModulesCorePlugin.gradle' --type f

echo ""
echo "== 查找所有 build.gradle 文件并检查 repositories =="
fd 'build.gradle' --type f -x grep -l 'repositories' {}

echo ""
echo "== 查看 packages/orpheus 目录结构 =="
find packages/orpheus -name '*.gradle*' -type f

echo ""
echo "== 搜索 jitpack 关键词(不限扩展名)=="
rg -i 'jitpack|mavencentral|maven\s*\{' --glob '**/*.gradle' --glob '**/*.kts' -n

Repository: bbplayer-app/BBPlayer

Length of output: 146


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== 检查 packages/orpheus/android/build.gradle 完整内容 =="
wc -l packages/orpheus/android/build.gradle

echo ""
echo "== 查看 build.gradle 最后部分 =="
tail -20 packages/orpheus/android/build.gradle

echo ""
echo "== 搜索其他 Android 模块的 build.gradle =="
find packages -name build.gradle -type f | head -10

Repository: bbplayer-app/BBPlayer

Length of output: 1266


需要添加 JitPack 仓库配置以解决依赖解析失败。

com.github.HChenX:SuperLyricApi:2.4 是 GitHub 托管的依赖,必须声明 JitPack 仓库才能成功解析。在 packages/orpheus/android/build.gradle 中添加以下配置:

repositories {
    maven { url "https://jitpack.io" }
}

将此块放在 dependencies 块之前。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/orpheus/android/build.gradle` at line 53, Add the JitPack repository
so the GitHub-hosted dependency implementation
'com.github.HChenX:SuperLyricApi:2.4' can be resolved: insert a repositories
block containing a maven entry for the URL https://jitpack.io into the same
build.gradle that contains the implementation line, and place that repositories
block before the dependencies block to ensure dependency resolution succeeds.

@roitium roitium merged commit deef3f4 into dev Feb 28, 2026
4 of 6 checks passed
@roitium roitium deleted the feat/status-bar-lyrics branch February 28, 2026 12:32
@coderabbitai coderabbitai Bot mentioned this pull request Mar 24, 2026
@coderabbitai coderabbitai Bot mentioned this pull request Apr 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] 状态栏歌词

2 participants