cwuom / NeriPlayer
git clone https://github.com/cwuom/NeriPlayer.git
NeriPlayer-02611a5c.10181316 · 4d ago
A native Android audio player that combines multi-source streaming, local control, rich lyrics, and self-hosted sync. / ✨ 一个把多源在线播放、本地管理、歌词体验和自建同步做进原生 Android 的音频播放器 🎵
+7
stars, 24h · #2,021
+~49
stars, 7 days · #2,536
+~210
stars, 30 days · #2,478
3.8k
★ total · +1% this week
140
forks · 140 open issues
Star history (as recorded here)
LanguageKotlin
LicenseGPL-3.0
Created2025-08-08 (1y ago)
Last pushtoday
Watchers6
OwnerUser
GitHub topics
androidequalizerexoplayerglsljetpack-composekaraoke-lyricslisten-togethermedia3musicnative-appsplayerprivacy-focusedself-hostedshadersusb-exclusivewebdavwebsocket
Links
- GitHub: github.com/cwuom/NeriPlayer
- Homepage: https://neri.kano.kim
- Releases · Issues · Hacker News mentions
README excerpt
English | 中文 NeriPlayer (音理音理!) ✨ 一个把多源在线播放、本地管理、歌词体验和自建同步做进原生 Android 的音频播放器 🎵 本项目的名称及图标灵感来源于《星空鉄道とシロの旅》中的角色「风又音理」。 项目采用原生 Android 开发,支持 Android 9 (API 28) 及以上设备, 围绕「多源探索、在线播放、本地可控、数据自持」持续打磨。 🛠️ Active development / 持续迭代中 > [!WARNING] > 本项目仅供学习与研究使用,请勿将其用于任何非法用途。 > 请只在你拥有权利、授权或第三方平台规则允许的范围内访问、播放或保存内容。 > 本项目不提供媒体内容、密钥、规避付费/DRM/地区限制的方案,也不提供公共媒体代理或再分发服务。 > > 本项目及维护者不接受任何形式的赞助、捐赠或商业资助。 --- > [!NOTE] > NeriPlayer 不提供公共云端曲库或媒体分发服务。 > 在线音频能力依赖用户在第三方平台上的账号授权, > 会员或受限内容仍需遵循原平台规则。 > 文档中提到的 YouTube Music 相关能力仅指账号会话、播放兼容和错误恢复, > 不代表绕过平台限制、复制受保护内容或重新分发媒体。 --- ## 快速定位 / Start here 如果你只是想体验应用,请看 快速体验。 如果你想了解项目能力,请看 项目亮点 和 核心特性。 如果你准备贡献代码,请直接阅读 CONTRIBUTING.md。 如果你要自建一起听服务端,请看 一起听服务端部署。 [code] ## 项目简介 / About NeriPlayer 是一个基于 **Jetpack Compose + Media3** 的原生 Android 音频播放器。它不构建公共云端服务,而是在用户具备第三方平台账号能力的前提下, 整合 **网易云音乐**、**Bilibili** 与 **YouTube Music** 的在线内容, 并提供本地播放、下载、缓存、歌单管理和多种同步/备份能力。 当前定位: - **账号即能力**:通过第三方平台授权启用搜索、播放、歌单和收藏夹访问。 - **本地优先**:播放缓存、下载文件、歌单、历史记录、设置与授权信息默认保存在设备本地。 - **可选同步**:可将歌单、收藏、最近播放、歌曲播放统计、歌单打开统计和 本地歌单播放统计同步到用户自己的 GitHub 仓库(应用内新建时默认使用私有仓库)或 WebDAV 远端文件。 - **尊重隐私与账号安全**:同步策略刻意保持去中心化, 数据写入用户自己控制的 GitHub/WebDAV 远端,而不是上传到项目维护者的中心化服务。 应用并非没有能力把播放历史回写到第三方音乐平台;但中心化音乐平台的客户端 通常存在风控与行为采样机制,直接上报历史播放数据可能触发异常登录、异常播放 或账号冻结等风险。出于保护账号安全的考虑,NeriPlayer 暂不向这些平台上传 本地播放历史和播放统计。 - **Compose 主界面**:`MainActivity` 承载主导航与播放界面, UI 由 Compose `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 播放兼容有多级回退**: 登录态会保留有效身份 Cookie,并与匿名 visitor 分别维护 bootstrap 和 PoToken 会话;Cookie 轮换、会话参数、`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、蓝牙歌词和歌词编辑 也复用同一条播放数据链路。 - **完整的本地歌曲管理链路**: `LocalAudioImportManager` 支持外部分享/打开导入、授权文件夹扫描、 设备媒体库扫描和常见音频格式识别,并会处理附近的 `lrc/txt` 歌词与 `cover/folder/front` 封面;大批量扫描会先给出快速预览,再在后台补全 更完整的歌名、歌手、专辑和封面信息;`LocalPlaylistRepository` 负责本地系统歌单、普通歌单、收