init: dec-music 项目初始化

This commit is contained in:
2026-05-23 12:55:48 +08:00
commit 21045d0aad
50 changed files with 3662 additions and 0 deletions
+155
View File
@@ -0,0 +1,155 @@
# dec-music
## 作为库使用
模块路径:`jsuse.com/dev/dec-music`
对外包名:`music`
### API(与历史版本兼容)
```go
import "jsuse.com/dev/dec-music"
// 批量解密目录(递归子目录)
err := music.DecryptProcess(inputDir, outputDir, noSubOutput, onProcess)
// 解密单个文件
err := music.DecryptFile(inputFile, outputDir, noSubOutput, onProcess)
```
| 符号 | 说明 |
|------|------|
| `music.DecryptProcess` | 遍历 `inputDir` 下媒体文件并解密到 `outputDir` |
| `music.DecryptFile` | 只处理一个文件 |
| `music.OnProcess` | 可选回调 `func(src, dst, err string)``err` 为空表示成功 |
| `music.ErrNoDecoder` | 无可用解密器时的错误文案常量 |
`noSubOutput == false` 时,输出目录会保留相对子目录结构;为 `true` 时所有文件平铺在 `outputDir` 下。
### 示例
```go
package main
import (
"fmt"
"jsuse.com/dev/dec-music"
)
func main() {
err := music.DecryptProcess(`D:\Music\encrypted`, `D:\Music\decrypted`, false,
func(src, dst, errMsg string) {
if errMsg != "" {
fmt.Println("失败:", src, errMsg)
return
}
fmt.Println("成功:", src, "->", dst)
})
if err != nil {
panic(err)
}
}
```
## 命令行工具(本地测试)
CLI 位于 `cmd/dec-music`,依赖 `urfave/cli`,与库分离。
**不要在仓库根目录**对 `.` 执行 `go build -o xxx.exe`:根目录是 `package music`(库),没有 `main`。那样即使生成名为 `.exe` 的文件,也不是 Windows 可执行程序,运行会提示“不是有效的 Win32 应用”等。
```bash
# 正确:编译命令行程序
go build -o dec-music.exe ./cmd/dec-music
# 根目录仅校验库能否编译(不会在目录里生成可运行的 exe)
go build .
```
无参数运行 `dec-music.exe` 会打印用法(等同 `--help`)。
### 用法
```text
dec-music [选项] [输入路径]
选项:
-i, --input <路径> 输入文件或目录(默认当前目录)
-o, --output <路径> 输出目录(默认与输入相同)
--no-sub-output 输出文件不保留子目录结构
--skip-noop 跳过已是明文的音频(mp3/flac 等透传解码器)
--overwrite 覆盖已存在的输出文件
--supported-ext 列出支持的加密扩展名并退出
--qmc-mmkv <文件> macOS QQ 音乐 MMKV 密钥库路径
--qmc-mmkv-key <密钥> 加密 MMKV 的 AES 密钥(可选)
```
### 示例
```bash
# 解密当前目录到 ./out
dec-music -i . -o ./out
# 解密单个文件
dec-music -i song.ncm -o ./out
# 查看支持的扩展名
dec-music --supported-ext
# macOS QQ 音乐:指定 MMKV(可选)
dec-music -i ~/Music --qmc-mmkv "/path/to/MMKVStreamEncryptId"
```
成功时终端会打印彩色行:`操作成功: 源 -> 目标`(由 `log` 包输出)。
## 支持的格式
| 平台 | 常见扩展名 |
|------|------------|
| 网易云 | `.ncm` |
| QQ / 腾讯 | `.qmc0` `.qmc3` `.qmcflac` `.mgg` `.mflac` `.tkm` 等 |
| 酷狗 | `.kgm` `.kgma` `.vpr` |
| 酷我 | `.kwm` |
| 喜马拉雅 | `.x2m` `.x3m` `.xm` |
| 虾米等 | `.xm` `.wav` `.mp3`(部分) |
完整列表以 `--supported-ext``decrypt.SupportedExtensions()` 为准。
## 项目结构
```text
dec-music/
├── decrypt.go # package music:对外 API
├── decrypt/ # 各平台解密实现(内部)
├── mmkv/ # QQ Mac MMKV 密钥(内部,darwin
├── internal/
│ ├── crypto/ # AES 等
│ ├── sniff/ # 输出格式嗅探
│ └── fileutil/ # 媒体文件判断
├── log/ # 可选彩色日志(CLI 使用)
└── cmd/dec-music/ # 命令行
```
## 依赖说明
| 模块 | 用途 |
|------|------|
| (根模块库) | 仅标准库;`internal/tea` 为 QQ 密钥派生(源自 golang.org/x/crypto/teaBSD |
| `cmd/dec-music` | 额外需要 `github.com/urfave/cli/v2` |
MMKV 的 protobuf 线格式解析已内置在 `mmkv/internal`,不依赖 `google.golang.org/protobuf`
## 开发
```bash
go build .
go test ./decrypt/...
go build ./cmd/dec-music
```
## 许可
与项目原有许可保持一致。`internal/tea` 摘自 golang.org/x/cryptoBSD),见该目录内源文件注释。
D:\Media\Kugou\Download\KugouMusic\张蔷 - 夜猫.kgma