cwuom/NeriPlayer
A native Android audio player that combines multi-source streaming, local control, rich lyrics, and self-hosted sync. / ✨ 一个把多源在线播放、本地管理、歌词体验和自建同步做进原生 Android 的音频播放器 🎵
About cwuom/NeriPlayer
cwuom/NeriPlayer is an open-source project on GitHub, mainly written in Kotlin. A native Android audio player that combines multi-source streaming, local control, rich lyrics, and self-hosted sync. It currently holds 3,950 stars and 149 forks with 0 open issues, and was last pushed on an unknown date (repository created unknown).
Project Overview
Git Homed tracks it on the Today's Trending board, currently at rank #17 with 34 new stars today.
GitHub Repository Details
README
NeriPlayer (音理音理!)
✨ 一个把多源在线播放、本地管理、歌词体验和自建同步做进原生 Android 的音频播放器 🎵
本项目的名称及图标灵感来源于《星空鉄道とシロの旅》中的角色「风又音理」。
项目采用原生 Android 开发,支持 Android 9 (API 28) 及以上设备, 围绕「多源探索、在线播放、本地可控、数据自持」持续打磨。
🛠️ Active development / 持续迭代中
[!WARNING]
本项目仅供学习与研究使用,请勿将其用于任何非法用途。
请只在你拥有权利、授权或第三方平台规则允许的范围内访问、播放或保存内容。
本项目不提供媒体内容、密钥、规避付费/DRM/地区限制的方案,也不提供公共媒体代理或再分发服务。
> 本项目及维护者不接受任何形式的赞助、捐赠或商业资助。
---
[!NOTE]
NeriPlayer 不提供公共云端曲库或媒体分发服务。
在线音频能力依赖用户在第三方平台上的账号授权,
会员或受限内容仍需遵循原平台规则。
文档中提到的 YouTube Music 相关能力仅指账号会话、播放兼容和错误恢复,
不代表绕过平台限制、复制受保护内容或重新分发媒体。
---
快速定位 / Start here
如果你只是想体验应用,请看 快速体验。 如果你想了解项目能力,请看 项目亮点 和 核心特性。 如果你准备贡献代码,请直接阅读 CONTRIBUTING.md。 如果你要自建一起听服务端,请看 一起听服务端部署。
NeriPlayer
├── 多源在线播放:网易云 / Bilibili / YouTube Music
├── 本地优先数据:缓存、下载、歌单、历史、统计、设置
├── 可选自有同步:GitHub / WebDAV 元数据同步
├── 丰富播放体验:Media3、歌词、音效、流体背景、桌面小组件、启动器快捷方式、悬浮/状态栏歌词
└── 可恢复运行:安全模式、崩溃日志、ANR 记录、调试探针
项目简介 / About
NeriPlayer 是一个基于 Jetpack Compose + Media3 的原生 Android 音频播放器。它不构建公共云端服务,而是在用户具备第三方平台账号能力的前提下, 整合 网易云音乐、Bilibili 与 YouTube Music 的在线内容, 并提供本地播放、下载、缓存、歌单管理和多种同步/备份能力。
当前定位:
- 账号即能力:通过第三方平台授权启用搜索、播放、歌单和收藏夹访问。
- 本地优先:播放缓存、下载文件、歌单、历史记录、设置与授权信息默认保存在设备本地。
- 可选同步:可将歌单、收藏、最近播放、歌曲播放统计、歌单打开统计和
- 尊重隐私与账号安全:同步策略刻意保持去中心化,
- Compose 主界面:
MainActivity承载主导航与播放界面,
NavHost、动态底栏、Mini Player 与 Now Playing 覆盖层组织。
- 启动与恢复链路:正常启动流程为
Loading -> Disclaimer -> Onboarding -> Main;
如果上次启动发生崩溃或系统 ANR,会先进入 Safe Mode。
- 测试护栏:下载存储、同步合并、YouTube 播放兼容、一起听、歌词解析、
---
项目亮点 / Why it stands out
- 本地优先,也认真做脱机体验:
NetworkStatusMonitor 基于系统默认网络承载自动识别脱机状态,
offlineCachedImageRequest 会在脱机时阻断远程图片请求并优先使用缓存;
首页、探索、播放页、歌词页、歌单和下载列表都会接收 offlineMode,
网络断开时仍能围绕本地文件、已下载音频、播放缓存、缓存封面和本地歌单继续使用。
- 多源播放不是简单入口堆叠:
PlayerManager 负责音源解析、队列和失败恢复;网易云不可播、无可用播放结果或
只返回试听片段时,会先尝试音质降级;启用 Bilibili 兜底后,再由
PlayerManagerNeteaseAutoSourceSwitch 按歌名、歌手和时长评分自动匹配
Bilibili 音源兜底;播放异常时还会刷新当前链接,连续失败再跳过或停止。
- YouTube 播放兼容有多级回退:
player.js 和挑战结果会优先复用缓存,失效的
player.js 或被平台拒绝的播放候选会进入 EJS/HLS 回退,避免在同一候选上反复重试。
- GLSL/AGSL 高性能流体背景:
BgEffectPainter 加载
assets/shaders/hyper_background_effect.glsl 并通过 RuntimeShader 逐帧渲染;
shader 内部基于封面取色、动态色块和轻量颗粒噪声生成流体背景,
并接入 uMusicLevel / uBeat 做音频响应,不是简单把封面做高斯模糊。
- 仿 Apple Music 的深度歌词体验:
SyncedLyricsView 与 AdvancedLyricsView 支持逐行、逐词/逐字 LRC(含行尾
时间和方括号逐字时间戳)以及 YRC/TTML 歌词的高亮、翻译歌词、
音译显示、歌词偏移、点击跳转、长按分享、景深模糊、边缘渐隐和全屏歌词;
歌词页只显示当前歌曲可用的译/音选项,切歌后待歌词判定完成再渐入;
点击可在翻译、音译和关闭之间循环;
LyricShareSheet 可选择歌词行,复制文本、分享歌曲或生成 1080px 歌词卡片;
歌词页遇到含假名的日语原文时,会为翻译行额外留出间距,避免日文字形和译文挤在一起;
悬浮歌词、状态栏歌词、SuperLyric、Lyricon、蓝牙歌词和歌词编辑
也复用同一条播放数据链路。
B 站来源的歌曲可以使用视频自带的 CC 字幕作为歌词:播放页的 CC 字幕面板
可以关闭字幕歌词、选择具体字幕轨道,并按需回退到自动生成的字幕;
默认偏移量里为这一来源保留了独立偏移。
- 完整的本地歌曲管理链路:
LocalAudioImportManager 支持外部分享/打开导入、授权文件夹扫描、
设备媒体库扫描和常见音频格式识别,并会处理附近的 lrc/txt 歌词与
cover/folder/front 封面;大批量扫描会先给出快速预览,再在后台补全
更完整的歌名、歌手、专辑和封面信息;LocalPlaylistRepository
负责本地系统歌单、普通歌单、收藏、排序、去重、备份和同步触发。
- 批量词图管理(词图管理):
ar/al/ti 标签;
封面优先读取同目录 cover/folder/front/album 图片,其次使用与歌词同一曲目的在线封面,
可压缩为 500/1000 px JPEG,写入前预估空间增量并支持逐首核对、切换候选与失败重试。
标准歌词字段会降级为逐行 LRC 以兼容车机和蓝牙设备,完整逐字歌词保留在 NeriPlayer 私有字段。
分区存储下读取文件夹图片需要授权一次文件夹,修改其他应用创建的媒体文件会集中申请一次系统授权。
- 媒体库已经有“分类浏览”的骨架:
Library 不只是歌单列表,本地内容可在歌单/歌手之间切换,
LocalArtistSummary 会按展示艺术家自动聚合歌曲、拆分常见合作歌手写法、
生成稳定身份和封面;
网易云歌曲还能进入艺术家详情页,查看热门歌曲和专辑;网易云歌手、B 站 UP 主和
YouTube 创作者都可关注到收藏页,按网易云 / B 站 / YouTube 分类浏览。
网易云和 YouTube Music 分类支持登录后手动拉取账号关注的歌手,保留已有本地关注。
- 大屏和日常操作都在补手感:
Mini Player 支持横向滑动切到上一首/下一首,常用播放控制不用每次展开全屏;
桌面小组件提供 4x1 横条、2x2 迷你播放器和 4x2 播放卡片;使用封面取色的
Material You 圆角卡片,支持明暗主题、横竖屏和尺寸自适应。宽卡片显示歌曲、
封面、进度、收藏和桌面歌词入口;窄尺寸也保留上一首、播放与下一首,复用播放服务的控制链路;
启动器快捷方式可直接继续播放、打开探索、打开媒体库或随机播放我喜欢的音乐;
平板主标签使用可打断的居中缩放和淡入淡出,手机保留按标签顺序横向换页;转场中会同时保留出场与入场页面,
避免玻璃背景、滚动位置和页面状态在快速切换时闪断;
播放页长按封面可打开沉浸式大图预览,支持双指缩放、拖动与下载封面。
- 听感也能细调:
Equalizer;
「设置 → 音效与倍速」提供 29 种内置音效、10 段均衡器、参数均衡、AutoEQ 导入、
低音/高音、虚拟低音、人声、空间、混响、压缩、扬声器优化和防爆音限幅,
也支持按输出设备分别记忆音效、按歌曲实时响度均衡、
声道平衡、32-bit 高解析普通输出、淡入淡出、交叉淡入淡出、
蓝牙断连暂停、USB 独占播放和音频焦点策略。
USB 独占会由 native 驱动接管兼容 USB 音频设备,避免系统音和其他应用共用 USB 通道;
当前面向 UAC1.0 和兼容 UAC2.0 Type I PCM 设备,设备选择、
采样率/位深/缓冲策略、32-bit PCM、PCM float 软件转换、后台运行提醒、
UAC2 时钟拓扑与显式反馈端点解析、启动看门狗、前后台健康审计、
动态传输扩缩容和卡死自动恢复也都补齐了;前后台切换会按网络或本地来源选择
唤醒策略,USB 独占播放可在回到前台后恢复;长调度间隙后会重新捕获反馈时钟,
避免继续使用陈旧的速率估计。比特完美音量模式保持软件增益为 0 dB,交给 DAC
硬件控制音量。
- 下载链路已从“能下”进化到“能恢复”:
DownloadManager,而是用共享 OkHttpClient、
可调并发、工作文件和 sidecar 元数据管理完整落盘流程;
直接 HTTP 传输、平台需要显式 Range 的传输和 HLS 都有对应续传策略,网络策略暂停后可继续,
启动时会恢复未完成队列,已落盘的缓存命中会直接结算,
手动取消则会清理半成品,语义边界很清楚;下载完成后即使标签写入失败,已落盘
音频仍会保留。
- 存储占用能看清,也能有边界地清理:
StorageUsageAnalyzer 会把音频缓存、图片缓存、下载暂存、分享暂存、
平台歌单缓存、下载内容、日志、崩溃报告和核心应用数据分组统计;
清缓存支持只清可再生成的缓存,不会把用户主动下载的歌曲当作缓存删掉。
- 去中心化同步与播放统计:
PlaybackStatsRepository 按歌曲稳定身份记录播放次数、
收听时长、最近播放和每日桶,并参与同步合并;播放和流量统计采用延迟批量写入,
在关键生命周期阶段 flush;播放累计与日桶不再按数量淘汰,流量统计保留自己的窗口策略。
远端同步快照读取时会兼容旧字段和异常缺字段数据,过滤缺少可解析歌曲身份的记录。
- 流量管理不是事后看数字:
TrafficStatsRepository 会区分播放流量、下载流量、Wi‑Fi、移动网络、
漫游和缓存命中;批量或单曲下载在高风险网络下还能主动弹出提示,
避免把“省流量”只做成设置页里的摆设;统计写入同样使用批量累积和生命周期 flush。
- 高个性化,不只是换主题色:
AutoSettingsSchema 管理,覆盖动态取色、种子色、
主题风格、自动/浅色/深色模式、UI 缩放、自定义背景、歌词字号、
歌词模糊、播放页流体背景、两级高级模糊、连贯反馈、首页卡片开关、默认启动页、触感反馈,
以及歌曲自定义名称、歌手和封面等细粒度选项。
应用内 UI 缩放默认 1.0x,手机范围为 0.6-1.2x,车载模式为 0.6-1.5x,步进为 0.05x。
平板上限按设备最小宽度动态计算,放大后仍保留至少 600dp,并向下取到 0.05x 档位,例如最小宽度 800dp 的平板最高为 1.3x。
升级后或首次安装完成引导后,会询问一次是否启用预览版主题;启用后立即生效,
也可随时在主题设置中切换,已启用或已作出选择后不再重复询问。
「界面风格」可选择默认的 Material You 或预览版「简洁(Clean)」;后者提供独立的明暗配色、
连续曲率圆角和控件样式,并可开启底栏与迷你播放器的液态玻璃效果。
OnePlus 的高密度屏幕(系统 densityDpi >= 500)会自动叠加 0.95x UI 修正,
普通密度机型不触发修正,用户手动设置值仍会作为额外乘数参与计算。
“进阶高级模糊”和“连贯反馈”默认关闭;关闭连贯反馈时,歌单等详情页使用抽屉式展开;
“预测性返回预览”默认关闭,所有系统均可手动开启;
进阶高级模糊仅在 Android 13+ 且父级高级模糊开启时可用;
它会增强屏幕级顶部 Tab、底部 Tab 和设置结构卡片的实时玻璃材质,
并提供 12-64 dp 的模糊度调节,不改变文字、图标、布局与点击区域。
模糊质量可独立选择“超低、低、默认、高”:超低和低保持与默认相同的模糊范围,
通过局部区域渲染、动态下采样和 RenderNode 硬件缓存降低渲染开销。
检测到天玑 SoC 且尚未保存过选择时默认使用“超低”;前后台切换或更改质量时会
重建局部缓存,避免恢复后出现异常背景。“高”需要先开启进阶高级模糊。
- ANR、崩溃和安全模式都纳入诊断闭环:
AnrWatchdog 会读取 Android ApplicationExitInfo.REASON_ANR 并保存系统
ANR trace;ExceptionHandler 与 NativeCrashHandler 分别记录 JVM 和
Native 崩溃。上次启动异常时,SafeModeManager 可跳过完整应用初始化,
直接进入安全模式预览、复制或导出日志。
- 一起听不是“同步一个进度条”这么简单:
---
快速体验 / Getting Started
a. 下载 Release 版本(推荐)
1. 前往 GitHub Releases 2. 如何选择版本?
- 大部分手机请选择
arm64-v8a - 老旧 32 位设备请选择
armeabi-v7a x86/x86_64主要用于模拟器、英特尔设备或 Chromebook
[!IMPORTANT]
Release 渠道不是严格意义上的稳定通道。版本通常在完成一批功能后手动发布,
仍可能包含未充分暴露的问题。
b. 下载 CI 版本
1. 前往 GitHub Actions 下载最近一次成功构建的 Artifacts 并解压。 2. 或访问 NeriPlayer CI Builds。
master 分支 CI 默认上传 arm64-v8a APK;手动 Release 流程会构建多 ABI APK。
c. 本地构建
1. 克隆仓库并初始化子模块:
git clone --recursive https://github.com/cwuom/NeriPlayer.git
cd NeriPlayer
2. 安装 JDK 17,并使用 Android Studio 最新稳定版打开项目、同步依赖;
建议将 Gradle JDK 设为 17;运行 :playback:runtime JVM 测试或全量模块门禁时,另需可被 Gradle 发现的 JDK 21,生产字节码仍以 17 为目标。
3. 构建调试版:
./gradlew :app:assembleDebug
4. 安装 APK:
adb install -r app/build/outputs/apk/debug/app-debug.apk
5. 首次启动时先阅读免责声明并完成启动引导;引导页会说明通知与本地音乐权限,
仅在你主动点按后申请,跳过不影响继续使用。
6. 如需调试工具,在设置页连续点击 版本号 7 次启用开发者模式,
底栏会出现独立 Debug 页面。
DEBUG 构建仅用于测试,性能和体积不代表发布版。
DEBUG 包使用moe.ouom.neriplayer.debug和橙色启动图标,应用名称带有DEBUG标记,启用系统主题图标时也能区分;可与 Release 共存,应用数据各自独立。
DEBUG 分享的一起听邀请使用 neriplayer-debug://,避免打开正式版;仍可在应用内粘贴普通邀请链接加入。
完成启动引导后会提示 DEBUG 构建风险;确认后不再提醒,更新保留该状态,清除数据或重新安装后会再次提示。
在 Android Studio 中运行时,选择 app 运行配置,并确认 Build Variants 中
:app 使用 debug。更新包名配置或切换到包含该变更的分支后,先执行
Sync Project with Gradle Files;仅重新构建 APK 不会刷新 IDE 缓存的启动包名,
可能导致安装 DEBUG 包后仍启动已安装的正式版。运行窗口中的启动组件应为
moe.ouom.neriplayer.debug/moe.ouom.neriplayer.activity.MainActivity。
发布版构建与签名流程请参阅 CONTRIBUTING.md。
---
核心特性 / Key Features
- 🎧 多源探索与播放:
- 🏠 首页推荐与继续播放:
- 🗂️ 媒体库分类浏览:
Library 提供本地、收藏、网易云、YouTube Music、Bilibili 等入口;
可在“设置 > 通用”中完全禁用 YouTube,关闭后不会展示相关入口或执行后台预热;
本地页支持歌单/歌手切换、搜索、歌手排序,收藏页支持歌单/歌手/热点切换,
网易云页支持歌单/专辑切换,Bilibili 页区分创建收藏夹、订阅收藏夹和合集。
- 🔍 分层搜索能力:
Explore 使用网易云 / Bilibili / YouTube Music 按平台独立搜索;
网易云支持歌曲、歌单和歌手分类,网易云与 Bilibili 搜索结果可在列表触底后
自动加载下一页;“链接识别”可直接粘贴链接或含标题、短链接的整段分享文案,
识别网易云歌曲/歌单/歌手、Bilibili 视频/收藏夹/合集/UP 主及 YouTube
视频/歌单/频道。项目已有详情页的类型可直接打开,暂无详情页的类型会明确提示;
Bilibili 链接会尽量保留 p / cid 分 P 和 season_id 合集上下文,
分享合集时可直接解析到对应合集列表。
搜索框下方会显示本地搜索历史,默认记录防抖搜索过的关键词;
可在“设置 > 通用”关闭探索页搜索历史,关闭后不显示也不再记录新关键词,
已有记录不会被自动删除,重新开启后仍可显示;
播放页元数据补全使用网易云 / QQ 音乐,并接入 LRCLIB 外部歌词来源;
歌词编辑器可选择酷狗、网易云、QQ 音乐、AMLL TTML、LRCLIB 和
YouTube Music 后手动匹配歌词,逐字歌词优先但不隐藏普通歌词,并会自动清理
标题、制作信息等非歌词行。
- 🧠 Media3 播放核心:
PlayerManager 管理音源解析、队列、随机/循环、状态恢复、失败重试、
播放链接刷新、YouTube 预取与平台特殊请求策略。
随机播放会先生成真实乱序队列,再按该队列顺序播放、持久化和展示。
- YouTube 登录态会保留有效 Cookie,并支持 Cookie 轮换、匿名播放会话、bootstrap/
player.js/PoToken 缓存和优先级预取;签名或播放候选被拒时可回退 EJS/HLS。
- ⏩ 可选 BilibiliSponsorBlock 自动跳过:默认关闭。开启后仅向公开接口发送当前
intro、outro、sponsor、
music_offtopic、filler、padding 片段并在本地跳转;不会上传账号、播放历史或新片段。一起听期间保持关闭,
避免房间播放状态漂移。
- ⏭️ Bilibili 自定义跳过区间:可从正在播放的更多选项或 Bilibili 收藏夹/合集条目
BVID + CID 本地持久化,并通过 GitHub/WebDAV
同步。播放页可使用设为开始/结束、前后 5 秒及播放/暂停辅助定位;一起听期间不应用本地自动跳过,避免房间状态漂移。
- 🔁 网易云播放兜底:
- 🧯 播放失败兜底:
- 🎚️ 播放音效:
- 🎛️ 细粒度播放行为:
resumePositionMs 参与本地与可选同步,不代表第三方平台播放历史。
- 🔌 USB 独占播放:
USB_DEVICE_ATTACHED 事件可单独关闭,
用于避免不想接管 DAC 时反复唤起应用;
跟随歌曲采样率时会先按 USB 描述符尝试源采样率,精确格式不可用且兼容策略开启时,
再尝试设备上报的兼容采样率,此时用 Kaiser 窗 sinc 多相重采样(阻带约 -90 dB),
不再用线性插值;只有多声道模式的声卡会把立体声送到前两个声道、其余补零;
UAC2 终端经时钟选择器或倍频器连接时钟源时(如 XMOS 方案),会按选择器当前输入
走到最终时钟源再设置采样率;
对需要异步显式反馈的 UAC1/UAC2 设备,会解析时钟链和反馈端点(UAC1 同步端点按
bSynchAddress 匹配),根据设备反馈调度音频包,并在长调度间隙后重新进入反馈时钟捕获;
打开时会把播放路径上的 DAC 硬件静音解除、硬件音量设为 0 dB,关闭时写回原值,
避免 DAC 沿用系统留下的衰减;设置采样率后若回读暂时不一致,会等待时钟锁定再确认;
播放启动卡住、Native 传输背压卡住或前后台切换异常时,会通过原地重配置、
协调式 AudioSink 重建、动态传输扩缩容和软恢复尽量拉回,
必要时回退到系统播放避免整条链路卡死;播放器会按网络或本地来源选择唤醒策略,
前后台切换后可恢复 USB 独占;音量键、锁屏和系统音量面板都调节普通媒体音量,
原生输出即时跟随。开启比特完美输出时按音源采样率和位深申请 DAC 格式,
软件增益固定为 0 dB,不做音效、淡入淡出和重采样,DAC 带硬件音量时音量键改为调节
DAC 硬件音量,状态页会如实显示是否因 DAC 不支持音源格式而未达成比特完美。
高速显式反馈设备每个传输覆盖约 8 ms,USB 侧约有 128 ms 在途音频,后台调度抖动
不会直接断流;反馈值格式与总线速度不符时会像 Linux snd-usb-audio 一样自动校正;
传输运行后每次缓冲回调都会把 PCM 队列补到水位,高采样率音源不会因播放线程按
动态调度休眠而慢于实时。
设置页会显示后台行为是否受电池优化或后台权限限制;服务端播放保持时,后台音频锚点
跟随系统默认路由,只在路由到内置扬声器时写入零均值载波,不会把载波当作用户可听内容。
- 💾 可配置流媒体缓存:
SimpleCache + LRU 缓存音频,默认上限 1 GB,
支持分别清理音频缓存、图片缓存、分享暂存和平台歌单缓存,
清理面板会先扫描分类容量,完成后刷新占用并显示实际释放空间。
清理音频和封面时,通过 0–1000 首、步进 50 首的滑块保留最近播放的不同歌曲,音频与封面共用名单;
两类缓存和合计的预计可清理容量会随选择平滑更新,计算中或无法估算时显示占位,并同时列出实际占用。
详情统计目录物理占用;预计释放排除当前歌曲(含暂停)、保留缓存和索引文件,缓存实例不可读取时不会误报为 0。
0 表示不保留历史歌曲缓存,当前播放的音频仍受保护,不会为保留名单补下载。
开启保留时,无法确认歌曲归属的旧缓存会保守保留,实际留下的缓存可能多于 X 首。
“其他缓存”目前可清理歌词分享卡片;同步、备份恢复、下载续传和未知用途文件单独列为受保护数据。
下载暂存包含续传与恢复凭据,由下载恢复管理;已下载歌曲、歌词和封面不会被普通缓存清理删除。
- 🛰️ 脱机模式:
- ⬇️ 应用内下载与管理:
- 📁 可迁移下载目录:
- 🎵 本地音频导入与扫描:
VIEW / SEND / SEND_MULTIPLE 的 audio/*,
也支持扫描设备本地音乐、按授权文件夹定向扫描,
并自动识别附近歌词与封面 sidecar 文件;大批量扫描会先快速预览,
可按“已有元信息”过滤预览结果,再在后台补全更完整的本地元信息;SAF 空目录结果
不会误清理已有目录索引。
- 👤 本地歌手分类与详情:
feat.、with、和/与、
顿号、分号和常见斜杠分隔;本地歌手页支持播放全部、多选、
导出为歌单,以及对在线来源歌曲发起批量下载。
- 🩷 本地歌单与收藏:
- 🧑🎤 网易云艺术家详情:
- 🧺 网易云歌单详情缓存:
- 📖 歌曲百科:
- ☁️ GitHub / WebDAV 同步:
WorkManager 做延迟与周期同步,数据保存在用户自己的远端。
- 📊 播放统计:
- 📶 流量统计与高风险提示:
- ♻️ 备份与恢复:
- 🎧 一起听:
REQUEST_SET_TRACK 只能选择当前队列歌曲,并继续校验稳定
曲目键和服务端时钟。
- 🌈 个性化与主题:
12-64 dp 间调节,父级关闭时会保留
子级选择和模糊度但停止进阶绘制。模糊质量可独立选择超低、低、默认或高;
低和超低保持默认覆盖范围,以局部渲染、动态下采样和硬件缓存减轻开销,
天玑设备在未保存偏好时默认超低,并会在前后台恢复或切换质量后重建缓存。
- ✨ 播放页动效与歌词:
RuntimeShader / GLSL 流体背景、音频反应式动态背景、封面模糊背景、
仿 Apple Music 歌词、高级歌词、逐词歌词、翻译歌词、歌词偏移、
音译显示、歌词长按分享、歌词卡片生成、歌词编辑、歌词字体调节,
且封面页与歌词页的歌词 / 翻译字号可分别调节,
歌词触感反馈和 Lyrics 全屏页。封面页逐行歌词与底部 Dock 工具栏可以分别关闭;
窄屏或高缩放的竖屏会自动切换为紧凑布局,并将操作按钮收缩到稳定的触控槽位。
歌词分享支持逐行点选和从起点到目标行的长按范围选择。RuntimeShader 动态背景仅在 Android 13+
启用;封面模糊需要 Android 12+,高级模糊需要 Android 13+,低版本会降级。
- 👆 迷你播放器手势:
- 🧩 桌面小组件:
- 🚀 启动器快捷方式:
- 🪟 悬浮歌词与状态栏歌词:
- 🔌 外部歌词/设备联动:
- ColorOS 锁屏岛歌词(实验性):
- 🚗 车载播放:
- 🛠️ 开发者模式与调试工具:
Debug 页,
包含 YouTube / Bili / Netease / Search / Listen Together 探针、
普通日志与崩溃日志查看器。
- 🧾 登录与日志更友好:
- 🛟 安全模式与崩溃日志:
---
平台现状 / Platform Status
- 网易云音乐:
- Bilibili:
season_id 或视频详情恢复合集上下文;
播放页评论支持热门(默认)和最新排序,以及登录后的点赞和取消点赞;最新列表及后续分页可能需要登录。
评论楼号按当前列表顺序显示,支持楼中楼分页、长按复制,以及登录后的发评论和回复。
同样支持按登录会话隔离的缓存优先显示和后台静默核对。
- YouTube Music:
- QQ 音乐:
- 本地音频:
---
实现概览 / Implementation Notes
构建与版本
compileSdk = 37targetSdk = 36minSdk = 28- Java 17 / Kotlin JVM 17;Kotlin
2.4.10/ KSP2.3.10 - AGP
9.4.1/ Gradle9.6.1 - NDK
27.0.12077973 - CMake
3.22.1,由 Android 构建脚本固定指定 - 版本名格式:
<git短哈希>. - Release APK 文件名:
NeriPlayer-[-abi].apk - 默认 Release APK 只打包
arm64-v8a;多 ABI 输出需加
-PbuildAllReleaseAbis=true
.github/workflows/android_native_ci.yml会在 Native 相关变更时运行
-Werror、ASan+UBSan、TSan 三组 host CTest,并单独编译
arm64-v8a、armeabi-v7a、x86、x86_64 四个 Android ABI。
模块结构
自有 Android 库按业务域组织,由 gradle/owned-modules.txt 统一登记,共 14 个。一级领域使用 modules/<领域>,播放和下载保留规则与运行实现两个独立构建边界。远程音乐、歌词和元数据来源集中在 :platform,api 表达同库内部的请求协议职责;公共能力契约由模型和宿主接口表达。
:common:共享工具、日志、文案、图标、语言能力和测试夹具。:network:通用 HTTP、Range、网络解析和 Web 登录基础能力。:model:按业务分类的数据模型、枚举和跨模块状态契约,不依赖项目实现。:database:Room 数据库、实体、DAO、历史 schema 与版本升级。:native:Native 崩溃处理、DSP 音效、USB 协议与 PCM 计算、独占传输和第三方 libusb,生成并打包lib_neri.so。:playback:logic:播放 policy、状态协调 runtime、PCM/audio 和队列 queue 规则,保持包级隔离。:playback:runtime:Media3 引擎、播放服务、音源解析、USB 输出、Native DSP 接入、浮窗与蓝牙歌词及宿主接入。:download:logic:下载准入、状态迁移、重试、调度、传输槽位、所有权、提交与元数据规则。:download:runtime:下载执行、Room 队列、受管文件、迁移与恢复,以及 Worker 和 JobService。:lyrics:LRC/YRC/TTML 解析、转换、时间轴、翻译对齐、时间偏移,以及词幕(Lyricon)和 SuperLyric 接入。:platform:Bilibili、网易云、YouTube 的协议、账号、缓存和业务能力,跨平台评论,以及歌词来源、元数据搜索、匹配与回退。:local:本地设置、媒体、歌单、历史与统计、备份、流量、存储统计与缓存清理,以及 Android 同步宿主适配。:sync:GitHub/WebDAV 传输、加密凭据状态、会话、兼容编解码、合并、并发保护与 Worker 策略。:listentogether:一起听协议、HTTP/WebSocket 传输、身份规则、会话、连接恢复、控制与播放同步。
:app 维护 Android 入口、Compose 页面和跨领域依赖组装。设置项生成由 :ksp-annotations / :ksp-processor 维护,上游歌词子模块为 :accompanist-lyrics-core / :accompanist-lyrics-ui;:hidden-api 只为播放运行模块提供编译期接口桩,不随应用打包;build-logic 提供构建逻辑。np-submodule/NeriPlayer-LTW 是一起听 Cloudflare Workers 服务端,np-submodule/miuix 是未参与主应用构建的上游源码与文档树。这些不计入 14 个自有 Android 库。
依赖按实际职责维护,不由目录分类推导层级。:model 不依赖项目实现,:common 不依赖业务领域;数据库、存储计算、歌词解析与播放/下载规则不得反向依赖仓库或 Android 运行实现。:platform 内的业务仓库消费对应协议,API 不反向读取账号仓库、Room 或播放器状态,各平台仍保持包级依赖边界。:local 消费数据库与领域服务,客户端的账号、凭据刷新和存储能力通过窄接口注入。所有库禁止依赖 app 或形成循环。
:playback:logic 的 policy 只包含 audio、command、offload、pending、progress、service、skip、storage、wake 九个叶子包,不引用 runtime、audio 或 queue 实现;USB policy 仍归 :playback:runtime。:platform 依赖并公开 :lyrics 的解析能力;歌词来源仓库、匹配和回退留在平台,:lyrics 不依赖平台。词幕 SDK、位置推送与异步请求代次由歌词库维护,播放器通过窄加载端口提供歌词、偏好快照和生命周期输入。
共享业务契约统一放入 modules/model,沿用 data.model.<业务> 等既有包名;页面私有状态随 UI 维护,Room 实体随数据库维护,私有算法中间状态随算法维护。物