今天在 GitHub Trending 上看到一个有意思的项目:NeriPlayer,这是一个把多源在线播放、本地管理、歌词体验和自建同步做进原生 Android 的音频播放器,采用 Jetpack Compose + Media3 架构,为用户提供极致的音乐播放体验。
一、项目概述
NeriPlayer 是一个原生 Android 音频播放器,不构建公共云端服务,而是在用户具备第三方平台账号能力的前提下,整合网易云音乐、Bilibili 与 YouTube Music 的在线内容,并提供本地播放、下载、缓存、歌单管理和多种同步/备份能力。
核心定位
- 账号即能力:通过第三方平台授权启用搜索、播放、歌单和收藏夹访问
- 本地优先:播放缓存、下载文件、歌单、历史记录、设置与授权信息默认保存在设备本地
- 可选同步:可将歌单、收藏、最近播放和播放统计同步到用户自己的 GitHub 仓库或 WebDAV 远端文件
- 尊重隐私与账号安全:数据写入用户自己控制的 GitHub/WebDAV 远端,而不是上传到中心化服务
主要特性
- 🎧 多源探索与播放:支持网易云音乐、Bilibili、YouTube Music 与本地音频播放
- 🧠 Media3 播放核心:PlayerManager 管理音源解析、队列、随机/循环、状态恢复、失败重试
- 🔁 网易云自动换源:无权限或试听片段时,自动匹配 Bilibili 音源兜底
- 💾 可配置流媒体缓存:使用 SimpleCache + LRU 缓存音频,默认上限 1 GB
- ⬇️ 应用内下载与管理:支持多平台音频下载,保存歌词、封面、元数据和音频标签
- ☁️ GitHub / WebDAV 同步:可选同步本地歌单、收藏歌单、最近播放和播放统计
- 🌈 个性化与主题:支持自动/浅色/深色模式、动态取色、UI 缩放、自定义背景图
二、技术原理
架构设计
项目采用 单 Activity + Compose 架构,MainActivity 是唯一对外入口,UI 由 Compose NavHost、动态底栏、Mini Player 与 Now Playing 覆盖层组织。
启动与恢复链路
正常启动流程为 Loading -> Disclaimer -> Onboarding -> Main;如果上次启动发生崩溃或系统 ANR,会先进入 Safe Mode。
模块结构
:app:主 Android 应用:ksp-annotations/:ksp-processor:设置项自动登记与生成:accompanist-lyrics-core/:accompanist-lyrics-ui:歌词解析与 Compose 歌词 UI 子模块build-logic:统一 Gradle convention pluginnp-submodule/NeriPlayer-LTW:一起听 Cloudflare Workers 服务端
核心技术栈
- 构建配置:compileSdk = 37, targetSdk = 36, minSdk = 28
- 语言与工具:Java 17 / Kotlin JVM 17, NDK 27.0.12077973, CMake 3.28.0+
- 播放核心:Media3 ExoPlayer,由 PlayerManager 统一管理
- UI 框架:Jetpack Compose,支持平板/横屏自适应布局
关键技术实现
多源播放机制
PlayerManager 负责音源解析、队列和失败恢复;网易云不可播、无直链或只返回试听片段时,会先尝试音质降级,再由 PlayerManagerNeteaseAutoSourceSwitch 按歌名、歌手和时长评分自动匹配 Bilibili 音源兜底。
YouTube 取流多级回退
登录态会保留有效身份 Cookie,并与匿名 visitor 分别维护 bootstrap 和 PoToken 会话;Cookie 轮换、签名/n 参数、player.js 和挑战结果会优先复用缓存,失效的 player.js 或被 CDN 拒绝的直链会进入 EJS/HLS 回退。
GLSL/AGSL 高性能流体背景
播放页动态背景由 BgEffectPainter 加载 assets/shaders/hyper_background_effect.glsl 并通过 RuntimeShader 逐帧渲染;shader 内部基于封面取色、动态色块和轻量颗粒噪声生成流体背景,并接入 uMusicLevel / uBeat 做音频响应。
USB 独占播放
支持 UAC1.0 和兼容 UAC2.0 Type I PCM 的 USB DAC 设备,支持设备选择、采样率/位深/缓冲策略、32-bit PCM、PCM float 软件转换、后台运行提醒、UAC2 时钟拓扑与显式反馈端点解析。
数据流分析
本地优先数据管理
- 播放缓存、下载文件、歌单、历史记录、设置保存在设备本地
- NetworkStatusMonitor 基于系统默认网络承载自动识别脱机状态
- offlineCachedImageRequest 会在脱机时阻断远程图片请求并优先使用缓存
去中心化同步
- GitHub/WebDAV 同步只在用户自己的远端保存歌单、收藏、最近播放和播放统计等元数据
- PlaybackStatsRepository 按歌曲稳定身份记录播放次数、收听时长、最近播放和每日桶
- 播放和流量统计采用延迟批量写入,在关键生命周期阶段 flush
三、安装与快速开始
环境要求
- Android 9 (API 28) 及以上设备
- 推荐使用 arm64-v8a 版本(大部分现代手机)
- 老旧 32 位设备请选择 armeabi-v7a 版本
- x86 / x86_64 主要用于模拟器、英特尔设备或 Chromebook
安装步骤
方式一:下载 Release 版本(推荐)
- 前往 GitHub Releases
- 根据设备架构选择对应 APK
- 安装并启动应用
- 首次启动时阅读免责声明并完成启动引导
方式二:下载 CI 版本
- 前往 GitHub Actions 下载最近成功构建的 Artifacts
- 或访问 NeriPlayer CI Builds Telegram 频道
方式三:本地构建
# 克隆仓库并初始化子模块
git clone --recursive https://github.com/cwuom/NeriPlayer.git
cd NeriPlayer
# 使用 Android Studio 打开项目并同步依赖
# 构建调试版
./gradlew :app:assembleDebug
# 安装 APK
adb install -r app/build/outputs/apk/debug/app-debug.apk
最简运行示例
首次启动流程:
- 阅读并同意免责声明
- 完成启动引导(Android 13+ 会申请通知权限)
- 选择音乐平台并登录(网易云 / Bilibili / YouTube Music)
- 开始搜索和播放音乐
如需调试工具,在设置页连续点击 版本号 7 次启用开发者模式,底栏会出现独立 Debug 页面。
四、使用方法与实战
基础用法
音乐搜索与播放
- 在 Explore 页面使用网易云 / Bilibili / YouTube Music 按平台独立搜索
- 点击歌曲即可播放,支持查看歌词、封面和元数据
- Mini Player 支持横向滑动切换上一首/下一首
歌单管理
- Library 提供本地、收藏、网易云、YouTube Music、Bilibili 等入口
- 本地页支持歌单/歌手切换、搜索、歌手排序
- 支持创建、重命名、删除、排序普通本地歌单
下载管理
- 支持多平台音频下载,默认下载并发为 6(可在设置中调整,最高 8)
- 下载队列会持久化,应用重启后可恢复未完成任务
- 支持自定义下载目录和文件名模板
进阶用法
GitHub / WebDAV 同步
- 在设置中配置 GitHub 仓库或 WebDAV 服务器
- 选择要同步的内容:歌单、收藏、最近播放、播放统计
- 手动或自动触发同步
- 数据保存在用户自己的远端,完全掌控
一起听功能
- 创建房间或加入他人房间
- 通过 WebSocket 实时同步播放状态
- 支持房主/听众权限、成员控制、循环/随机模式同步
- 支持邀请链接和深链加入
歌词体验
- 支持逐词/逐字高亮、翻译歌词、音译显示、歌词偏移
- 支持悬浮歌词、状态栏歌词、SuperLyric、蓝牙歌词
- 支持歌词卡片生成和分享
实际项目示例
场景一:多平台音乐管理
用户在网易云音乐有收藏歌单,在 Bilibili 有订阅收藏夹,通过 NeriPlayer 可以:
- 登录网易云和Bilibili 账号
- 在 Library 中查看两个平台的歌单
- 统一管理播放列表
- 支持跨平台搜索同一首歌曲
场景二:离线播放
- 下载喜欢的歌曲到本地
- 在脱机模式下仍可播放已下载音频
- 自动使用本地缓存和下载文件
- 网络恢复后自动同步播放统计
场景三:自定义音效
- 在播放页打开音效控制面板
- 调节倍速、音调、均衡器
- 开启响度均衡、声道平衡
- 使用 USB 独占播放获得更高音质
五、常见问题与解决方案
安装失败
问题:APK 安装失败,提示"未安装应用"
解决方案:
- 检查是否开启了"允许安装未知来源应用"
- 卸载旧版本后再安装新版本
- 确认下载的是正确架构的 APK(arm64-v8a)
运行时错误
问题:播放失败或卡顿
解决方案:
- 检查网络连接状态
- 尝试切换音源(网易云 → Bilibili)
- 清理应用缓存后重试
- 查看开发者模式中的日志
问题:登录失败
解决方案:
- 使用二维码登录(网易云/Bilibili)
- 检查账号是否被封禁或限制
- 尝试使用网页登录兜底
性能问题
问题:应用卡顿或内存占用高
解决方案:
- 清理音频缓存和图片缓存
- 减少下载并发数
- 关闭高级模糊效果
- 关闭歌词模糊效果
问题:耗电快
解决方案:
- 关闭后台播放
- 减少同步频率
- 使用本地文件而非在线流媒体
兼容性
问题:某些设备上功能不可用
解决方案:
- Android 13+ 才支持 RuntimeShader 动态背景
- Android 12+ 才支持封面模糊
- 部分 USB DAC 设备需要开启兼容性开关
- 魅族状态栏歌词仅部分设备可用
问题:歌词显示异常
解决方案:
- 手动编辑歌词偏移
- 检查歌词文件格式(LRC/TXT)
- 尝试使用其他歌词源(LRCLIB)
六、总结
NeriPlayer 是一个功能强大、设计精良的 Android 音频播放器,它突破了传统音乐应用的限制,实现了多平台整合、本地优先、隐私保护的完美结合。项目采用现代化的 Jetpack Compose + Media3 架构,代码质量高,功能完善,适合学习 Android 高级开发和音乐播放器实现。
项目亮点:
- 多源播放不是简单入口堆叠,而是智能换源和失败恢复机制
- 本地优先设计理念,脱机体验完善
- 丰富的歌词体验和个性化选项
- 完整的同步和备份能力
- USB 独占播放支持高解析度输出
适用场景:
- 多平台音乐爱好者统一管理播放列表
- 注重隐私的用户自建同步服务
- 追求高音质的音频发烧友
- 学习 Android 高级开发的开发者
项目持续迭代中,欢迎关注 GitHub 仓库 获取最新更新。