一个基于 Kotlin、Jetpack Compose 与 Rust 的原生 Android 工具,用于:
- 解密网易云音乐
.ncm文件为常见音频格式(如mp3/flac) - 为音频文件补全元数据(标题 / 艺术家 / 专辑)
- 可选补全歌词与封面
UI 风格:深色 Tech 风,Material 3(支持动态配色)
- Rust NCM 核心:原生解析 NCM 头信息并流式解密音频内容
- 元数据增强:自动查询网易云接口并写入标签、歌词、封面
- 双入口导入:
- 选择文件夹(SAF)
- 直接多选文件(SAF)
- 并发处理:支持
1~8线程转换 - 会话恢复:持久化上次选择的目录/待处理文件(含 URI 持久权限)
- 自动输出目录:
- 文件夹模式:输出到
输入目录/unlocked - 多选文件模式:输出到
Android/data/<package>/files/unlocked
- 文件夹模式:输出到
- 点击 选择 NCM 文件 或 选择文件夹
- 等待扫描完成(状态栏会显示进度状态)
- 调整线程数(
Threads滑块) - 点击 开始转换
- 查看输出目录中的结果文件
- Kotlin + Jetpack Compose / Material 3
- Rust + JNI(NCM 解析、AES 与流式解密)
- MVVM(
MainActivity+MainViewModel) - Coroutines / StateFlow / LiveData
- jAudioTagger(音频标签读写)
- OkHttp(网易云接口请求)
- DocumentFile / SAF(Android 分区存储文件访问)
app/src/main/java/top/xihale/unncm/
├── MainActivity.kt # UI 交互、文件选择、状态恢复
├── MainViewModel.kt # 扫描与并发转换调度
├── FileConverter.kt # 单文件处理总入口(NCM / 普通音频)
├── NativeNcmCore.kt # Rust JNI 边界
├── AudioMetadataProcessor.kt # 标签/歌词/封面写入
├── NeteaseApiService.kt # 网易云搜索、歌词、封面 API
├── MediaMetadataRetrieverHelper.kt # 轻量元数据检测
├── MusicMetadata.kt
├── FileAdapter.kt
└── utils/
├── FastScanner.kt # SAF 流式扫描
└── Logger.kt
core/
├── Cargo.toml
└── src/ # NCM 解析、解密与 JNI 导出
- Android Studio(建议最新稳定版)
- Android SDK 34
- JDK 21
- Rust stable、
cargo-ndk 4.1.2 - Android NDK
28.2.13676358 - Rust Android targets:
armv7-linux-androideabi、aarch64-linux-android
首次构建前安装 Rust 目标与构建器:
rustup target add armv7-linux-androideabi aarch64-linux-android
cargo install cargo-ndk --version 4.1.2 --locked./gradlew :app:assembleDebugGradle 会先运行 Rust release 构建,并把两个 ABI 的 libunncm_core.so 自动打入 APK。
Rust 核心测试:
cargo test --manifest-path core/Cargo.toml --lockedAPK 默认输出:
app/build/outputs/apk/debug/
项目使用 Git Tag 自动发布(GitHub Actions):
- 工作流:
.github/workflows/release-on-tag.yml - 触发规则:push tag
v* - Tag 格式要求:
vMAJ.MIN.PATCH
# 或
vMAJ.MIN.PATCH-(alpha|beta|rc|release).N
示例:
v1.4.0v1.4.0-alpha.1
UNNCM_RELEASE_STORE_FILE_BASE64:签名.jks的 base64 内容UNNCM_RELEASE_STORE_PASSWORDUNNCM_RELEASE_KEY_ALIASUNNCM_RELEASE_KEY_PASSWORD
- 扫描逻辑目前基于 SAF 子项查询,默认只扫描所选目录当前层级(不递归深层子目录)
- 元数据增强依赖网络接口,请确保联网
- 歌曲匹配策略是“关键词搜索首条结果”,极少数歌曲可能匹配不准
本项目仅用于学习与个人用途,请遵守当地法律法规及平台服务条款,尊重音乐版权。