☰
Mac上QMC格式转换:qmcflac/mflac解密还原flac与mp3实战
2026/10/10 7:43:14 网站建设 项目流程

简介:面向macOS用户的QQ音乐QMC格式转码工具,能将qmcflac转为flac、qmc0/qmc3转为mp3,并支持mflac、mflac0等变体转flac,附带完整源码与Xcode工程配置。它解决QQ音乐加密音频无法在普通播放器直接使用的问题,适合音频处理爱好者、计算机相关专业学生作为课程设计或毕设项目的实践参考。压缩包共34个文件,核心为9个Swift源文件,涵盖QMCKeyDecoder密钥解码、QMCipher及TeaCipher解密等模块,另有11张演示截图、GIF效果图、JSON/plist配置以及工程管理文件,整体约946KB,结构紧凑。资源以Xcode工程形式呈现,目录清晰,便于按模块定位功能代码。目前已有1406人学习下载,实用价值获众多用户验证。源码包含QMCDecodeTests测试与README文档,可直接运行调试,也可基于现有模块二次开发,深入理解QMC格式的解析思路与Swift编码实践。

1. 一个Mac用户的真实困境:QQ音乐下载的flac,出了播放器就变砖

在Mac上把QQ音乐的无损文件导进自己的播放器,是我折腾过最憋屈的一件事。下载时客户端里明明写着SQ无损,缓存目录里却是 .qmcflac、.mflac 这类加密后缀,拖到 IINA、VLC 里全部提示无法解码。文件后缀看着像 flac,内容却被套了一层壳,这就是 QMC 格式转换要解决的问题。这个 zip 包专跑 macOS:把 qmcflac、mflac、mflac0 解密还原成真正的 flac,把 qmc0、qmc3 还原成 mp3。适合下载了会员歌曲、想在 Mac 本地播放器或音频库里正常使用的用户。下面我从加密原理、落地脚本到翻车点一次讲完。

2. 认识QMC格式家族:qmcflac、qmc0、qmc3、mflac的两代加密差异

2.1 两代加密:QMC1固定密钥表、QMC2在文件头里藏密钥

QMC 不是一个算法,而是 QQ音乐对本地缓存文件的统称。按客户端更新节奏,它实际上分了两代,解密路径完全不同。第一代是 QMC1,对应 qmcflac、qmc0、qmc3 这类后缀。它的做法是把一段固定密钥表写死在客户端里,用 RC4 流对音频数据做异或加密,所以同一批老客户端下载的文件,解密时只需要拿到那一套密钥表,一个工具就能通吃。劣势也非常明显:密钥表是全局共享的,只要被提取出来,整个加密体系对社区来说就没有秘密,所以后来 QQ音乐换掉了方案。

第二代是 QMC2,对应 mflac、mflac0。密钥不再是全局固定,而是写进每个加密文件自己的头部结构里。解密第一步是读文件头部,找到密钥段,解析出密钥长度和实际密钥内容,再做流式异或。因此转换工具必须明确区分两条解密路径:看到 qmc 前缀走固定密钥表,看到 mflac 前缀先拆头部取密钥。如果你搜过同类问题,会发现网上很多人把 qmcflac 和 mflac 混为一谈,这会导致解密到一半开始出乱码,输出文件时长不对或爆音,属于原理层面的踩坑。

这套加密方案对音频数据本身没有做压缩或重编码,它只是做了一层流式异或,所以解密后的数据在理论上和原始文件逐字节一致。这一点很重要,意味着转换是无损的,不需要重编码,转换速度取决于磁盘 IO 和 RC4 解开的吞吐,而不是 CPU 编码速度。很多刚接触格式转换的人以为转 flac 要像转 aac 那样跑一遍编码器,其实这里没有编码动作,只有解码和搬运。解密程序本身黑匣子一样的地方在于密钥表的来源和 QMC2 头部偏移的组织方式,这也是后面避坑章里各种怪问题的根源。

2.2 终端三件套:file、xxd、ffprobe 判断文件是否加密、属于哪一代

把文件丢进 Finder 看不到任何编码信息,Mac 的"显示简介"也不会告诉你里面是不是真 flac。我一般先在终端里跑三个命令摸底:

cd ~/Music/QQMusic file *.qmcflac *.mflac *.qmc0 *.qmc3 2>/dev/null xxd -l 128 "测试.qmcflac" xxd -l 128 "测试.mflac"

file 对正常 flac 会输出 "FLAC audio bitstream data",对加密后的文件基本只能输出 "data";如果它输出 "MPEG ADTS" 反而是好事,说明这个文件没有加密或者已经被还原过。xxd 看的是文件头,正常 flac 前 4 字节是 fLaC 这个可见签名,qmcflac 加密后前面 128 字节基本看不到任何可读签名,mflac 因为头部带密钥结构,看起来像一段乱码里夹杂少量可辨识的长度段。我这里不给你背固定偏移,原因很简单:不同客户端产出的文件头部偏移并不统一,与其对照十六进制,不如直接看被加密后 file 能不能认出这个文件。

ffprobe -v error -show_format "测试.mflac" 2>&1 | head -5

这条命令如果直接报 "Invalid data found when processing input",说明文件没被识别成任何已知封装,基本可以确定是加密状态。ffprobe 是 ffmpeg 套件里的探针工具,后文还要反复用到,macOS 上装一个很值:brew install ffmpeg会连它一起装上。注意 -v error 只输出严重错误,不会刷一大屏日志;head -5 是防止报错信息太长。

这套判断方法只依赖文件本身,不需要网络、不需要登录账号,也不依赖客户端版本,所以我把它放在转换前面,当成固定流程。早期社区流传过一张表,说 qmcflac 的文件头在某个偏移有什么标记,我用它批量判断翻过车。原因是不同版本的客户端对文件头做了不同处理,尤其 mflac 系变体,头部会有额外字段。现在我的习惯改成:后缀 + ffprobe 两条判断。后缀决定用哪条解密路径,ffprobe 决定解密有没有成功,这个组合比盲目读 hex 可靠得多。

2.3 先摸清你的文件规模:按扩展名统计再决定批量策略

动手转换之前,建议先按扩展名统计一下手上文件的规模,免得写了一下午脚本,最后发现只有两个文件要转。也可以避免另一个极端:五千个文件一次性塞进命令行参数,让 shell 直接卡死。下面这条命令按扩展名分组计数:

find ~/Music/QQMusic -type f \( -name "*.qmcflac" -o -name "*.mflac" -o -name "*.mflac0" -o -name "*.qmc0" -o -name "*.qmc3" \) | awk -F. '{ext=$NF; count[ext]++} END {for (e in count) print e, count[e]}' | sort

awk 的 -F. 把文件名按点拆开,取最后一列当扩展名,count[ext] 做累加,最后统一输出。这里有个小坑:文件名如果带多个点,比如 "周杰伦.七里香.qmcflac",-F. 取的 $NF 依然是最后一个点后的字段,所以没问题。

统计完你会得到类似 qmcflac 240、qmc0 86、mflac 22 的数字。这个数字决定了两件事:第一,要不要写批处理脚本,少于 10 个文件的话,手动敲单条命令反而省事;第二,给后面 xargs 的并发数定上限,文件越碎、单文件越小,并发越可以开大。如果你发现一批 .mgg 后缀,那属于 QMCv2 新变体,部分老工具不支持,别指望这一个 zip 全包,后面避坑章还会提到一次。统计完后,把可疑的、后缀被改坏的文件单独挪到一个"未知"目录,交给转换工具按内容探测,不要手工乱改名。

3. 在macOS上跑通转换:环境准备、Gatekeeper、单文件验证

3.1 先把环境补齐:Command Line Tools、ffprobe

为什么坚持终端流程而不是找个图形界面的转换 App?因为 QMC 转换属于典型的"文件多、单文件小、报错信息藏在深处"的批量场景。图形工具一次拖几百个文件进去,你根本不知道哪个失败、为什么失败,日志窗口往往是面子工程。命令行脚本的每一步都有输出,失败文件能被单独标记,这比在界面里等一个转圈按钮踏实得多。

macOS 自带 unzip、bash、zsh,但转换完你总得验证结果,所以 ffprobe 几乎是必装。先检查已有环境:

xcode-select -p which ffprobe

第一条如果输出 /Library/Developer/CommandLineTools 说明命令行工具已装;如果提示找不到,运行xcode-select --install会弹窗引导安装。第二条看 ffprobe 在不在 PATH 里,没输出就说明没装或没链接。ffprobe 可以通过 Homebrew 装,也可以直接装 ffmpeg 一整套:brew install ffmpeg。我不建议为了省空间只装 ffprobe,因为后面的避坑场景里你还可能用到 ffplay 试听和 ffmpeg 抽封面。

3.2 解压 zip 包,顺手处理 Gatekeeper 隔离属性

解压和查看结构是第一步:

cd ~/Downloads unzip -o "QQ音乐QMC格式转换*.zip" cd QQ音乐QMC格式转换*/ ls -la file ./qmc-decoder 2>/dev/null

file 那一行会打印这是一个 Mach-O 可执行文件,这是 macOS 的二进制格式;如果显示 "ELF" 说明下错包了,那是 Linux 版本,Mac 跑不了。

接下来是每个 Mac 用户都会遇到的那道坎:从互联网下载的 zip 压缩出来的程序,会被打上 com.apple.quarantine 隔离属性,直接双击或者第一次执行,系统会弹"无法验证开发者,因为未签名"。这个 zip 里的命令行工具大概率没有苹果开发者签名,所以终端执行前先把隔离属性摘掉:

xattr -d com.apple.quarantine ./qmc-decoder 2>/dev/null || true

这里我把可执行文件统一写成 qmc-decoder 占位名,每个包的实际命令名不一定叫这个,以你解压目录里真实文件名和 README 为准。xattr -d 删除指定属性,2>/dev/null 把"属性不存在"的报错吞掉,|| true 保证即使失败脚本也不中断。如果这个包的执行文件不止一个,建议对所在目录逐个操作,或者干脆xattr -dr com.apple.quarantine .,-r 递归,注意别在别的目录乱用。

操作之前还有一道保险:把原始文件复制到一个只读工作目录再转,避免原地覆盖。下载目录里的 qmcflac 就当存档留着,直到整批文件验证通过再清理。我吃过亏,密钥表版本对不上时,手里没有原始文件就等于没有后悔药。

3.3 单文件转换跑通:先用最小样本验证

批量之前一定先单文件,不要上来就五万个文件怼给脚本。我一般挑一个刚才统计出来的普通样本:

./qmc-decoder -i "测试.qmcflac" -o "测试.flac"

这是假定的命令行参数风格,实际参数名以 README 为准:-i 指向输入文件,-o 指向输出路径。跑完后立刻验证:

ffprobe -v error -show_streams -select_streams a:0 -of default=noprint_wrappers=1 "测试.flac"

如果能看到 codec_name=flac、sample_rate=44100 这类输出,说明文件已经被解开。如果 ffprobe 还是报错,先不要怀疑工具坏了,把输出文件用 xxd 看前四字节,能看到 fLaC 就说明解了一半、封装有问题,看不到则说明解密路径没走对。

这一步只花两分钟,能省掉后面批量转换时的所有不确定性。跑通过的输出文件也不要删,把它当作基线。后面批量转换时如果某些文件产出不对,拿基线的 ffprobe 输出和失败文件对比,能很快定位是这个文件本身损坏,还是工具在这个变体上翻车。

4. 批量转换脚本与参数调优:qmcflac转flac、qmc0转mp3的完整落地

4.1 按扩展名映射输出格式:写一个 zsh/bash 批处理脚本

单文件跑通后,批量只是把逻辑重复起来。格式映射关系是核心:qmcflac、mflac、mflac0 全部落 flac,qmc0、qmc3 落 mp3。写成脚本:

#!/bin/zsh tool="$HOME/qmc-tool/qmc-decoder" out_dir="$HOME/Music/QMC_Converted" mkdir -p "$out_dir" [[ -x "$tool" ]] || { echo "工具不存在,请检查 tool 路径"; exit 1; } declare -A map=( [qmcflac]=flac [mflac]=flac [mflac0]=flac [qmc0]=mp3 [qmc3]=mp3 ) if [[ $# -lt 1 ]]; then echo "用法: $0 <文件或通配符> ..." exit 1 fi for f in "$@"; do [[ -f "$f" ]] || { echo "跳过不存在: $f"; continue; } ext="${f##*.}" target="${map[$ext]}" if [[ -z "$target" ]]; then echo "跳过未知扩展名[$ext]: $f" continue fi base="${f%.*}" out="$out_dir/$(basename "$base").$target" "$tool" -i "$f" -o "$out" \ && echo "[OK] $f -> $out" \ || echo "[FAIL] $f" done

这段的逻辑分三段看。第一段是环境准备,tool 指向解压出来的可执行文件实际路径,如果你的工具名不一样,改这一行就行;out_dir 是输出目录,mkdir -p 保证它存在。第二段是映射表,declare -A 定义关联数组,这是 bash 4 的特性,macOS 自带的 bash 是 3.2,默认会报 "declare: -A: invalid option",所以脚本第一行我直接写成 #!/bin/zsh,zsh 原生支持关联数组,macOS 的 zsh 版本也够新,这是最省事的绕坑方案。

第三段是循环主逻辑。${f##.} 是去掉最长前缀后取扩展名,${f%.} 是去掉后缀取主干,这两个参数展开式在处理带空格、带多点文件名时比 cut 命令稳。整个脚本对每个文件做一次映射判断,映射不到的扩展名直接跳过,不会影响其他文件。调用方式:

chmod +x convert_qmc.sh ./convert_qmc.sh ~/Music/QQMusic/*.qmcflac ~/Music/QQMusic/*.qmc0 ~/Music/QQMusic/*.qmc3

如果文件多到命令行参数超限,几千个文件时常见,改用 find 配合 xargs:

find ~/Music/QQMusic -type f \( -name "*.qmcflac" \) -print0 | xargs -0 ./convert_qmc.sh

4.2 并发调优:M系列芯片开几路最合适

批量转换本质是 IO 加轻量解密,CPU 不会吃满,但你开太多并发,内存会先爆。8GB 内存的 M1 机器我一般开 2 到 3 路,16GB 或 32GB 的 M2、M3 开 4 到 6 路比较稳。用 xargs 控制并发最省事,直接把文件喂给上一个脚本,让并发参数决定同时跑几个脚本进程:

find ~/Music/QQMusic -type f \( -name "*.qmcflac" -o -name "*.mflac" \) -print0 \ | xargs -0 -P 4 -I{} ./convert_qmc.sh "{}"

-P 4 代表同时最多起 4 个脚本进程;-I{} 是占位符,每次把读到的文件名替换到 {} 位置。这样不用关心 bash -c 引号转义,中文和空格文件名也能安全传递。如果转完发现磁盘一直响但 CPU 占用很低,说明瓶颈在 IO,把 -P 降一档反而整体更快,这个要靠现场压测看。

还有个容易撞上的同名覆盖问题:同一首歌可能同时有 qmcflac 和 mflac 两个版本,base 名一样,先转的会被后转的覆盖。我的习惯是输出文件名保留原扩展名线索,比如把输出命名为 歌名.qmcflac.flac,虽然丑,但不会丢文件。你如果介意,可以按原文件的相对目录重建 out_dir 结构。

4.3 参数边界:不重采样、保留元数据和封面的正确姿势

转换工具的默认行为应该是"原样解密",不重采样、不重编码。你唯一可能要改的,是输出目录、并发数和是否保留原文件名。不要试图在转换时把 96kHz/24bit 的 flac 顺手转成 alac 或 aac,那是另一层工作。很多人在这一步上当:以为工具能解密就能顺便转码,结果 flac 96kHz 24bit 转换 alac 失败,回头怪工具。QMC 转换的目标是把加密壳去掉,不是做音频转码头。如果你手里的原始文件是 mflac,但播放器只收 mp3,正确的做法是先让工具输出 flac,再用 ffmpeg 二压 mp3,别的什么都别动。mflac 转 mp3 是两步,不是一步。

元数据方面,老工具往往只还原音频流,不保证保留内嵌封面。想要封面的,转换后用 ffmpeg 抽:

ffmpeg -i "输出.flac" -an -vcodec copy cover.jpg

这条命令从 flac 里把封面帧单独拷出来;如果输出为空,说明原文件就没内嵌封面,跟工具无关。

另外,整个下载目录如果混着 ncm 格式的网易云文件,或者酷狗 kgg 转换 mp3 的文件,那是完全不同的加密体系,不要试图用这个工具去解,脚本只会把未知扩展名安静地跳过。同样的道理,想搜"QQ音乐下载mgg转换为mp3"的人,也得先确认手里的 mgg 是不是这个 zip 支持的版本,新客户端产物经常和老工具脱节。

5. QMC转换避坑指南:我翻过车的5个典型场景

5.1 解压后双击闪退,终端执行报"无法验证开发者"

现象:zip 解出来的工具第一次跑就闪退,或者终端里执行直接弹 "killed"。

原因:macOS Gatekeeper 给所有网络下载文件加了隔离属性,未签名的命令行程序不经过右键打开会被直接拦截;M 系列芯片上还可能叠加架构不匹配的问题,Intel 版二进制在 Apple Silicon 上需要 Rosetta 2 才能跑。

解决:先执行xattr -d com.apple.quarantine ./qmc-decoder摘掉隔离属性;如果还闪退,用file ./qmc-decoder检查是 Mach-O 64-bit x86_64 还是 arm64。Intel 版在 Apple Silicon 上要么装 Rosetta 2,要么找原生 arm64 的构建,这个在下载时就要看清说明。

5.2 转出来的 flac 有几十 MB,播放器里时长却是 0:00

现象:文件大小正常,拖进 IINA 显示时长 0,进度条不能拖,播放器直接卡住。

原因:解密路径选错了,最常见于把 QMC2 的 mflac 文件走 QMC1 固定密钥表去解。解出来的是从错误偏移开始的二进制流,头部损坏,播放器无法计算时长。mflac 和 mflac0 的头段解析在部分工具里混着用,也会出现类似问题。

解决:确认扩展名后缀没被改过;如果确实是 mflac,看工具 README 是否明确声明支持 QMC2,不支持就换一个维护更新一些的替代工具。这一条没太多参数可调,属于原理性限制,靠调参数救不回来。

5.3 Apple Music 认不出输出 flac,96kHz/24bit 转 ALAC 又失败

现象:转出来的 flac 在 Finder 里 QuickTime 能预览,但 Music 应用里导入显示不识别。

原因:Apple Music 的原生曲库不读 flac,这是产品限制,不是转换失败。如果你想进曲库,只能先转成 ALAC,而 96kHz/24bit 的高采样 flac 用 macOS 自带的音频转换组件经常报错,这个错误在社区里已经是大面积存在的现象。

解决:plist 层面没有后悔药,我一般就是不改动,直接用 IINA 或 VLC 播放 flac,或者把 flac 放进支持它的第三方播放器;非要进曲库,用 ffmpeg 手动转 alac,同时把采样率降到 48kHz 以内,可以避开大多数失败。

5.4 中文文件名带空格,批量跑一半报 unable to open output file

现象:大部分文件成功了,个别中文名或带空格的文件失败,报找不到输出文件或输出路径。

原因:脚本里变量没有加双引号,路径里的空格和中文在传给工具时被 shell 拆成了多个参数,工具拿着半截路径去创建文件,自然就失败。

解决:所有引用变量的地方都写成 "$f" "$out",参数展开式不要省引号;如果已经翻车,用 find -print0 配 xargs -0 的方式传参,空字符分隔保证文件名原样传递,这是应对"文件名里什么都有"的批量场景最稳的一套组合。

5.5 qmc3 转出来的 mp3 有杂音或沙沙声

现象:转换成功、可以播放,但声音像加了噪声,尤其前几秒最明显,越往后越乱。

原因:QMC1 的密钥表存在多个版本,旧客户端下载的文件用的是老密钥表,工具内置的新密钥表解出来对不上,流式解密错位。同一个扩展名、不同年份下载的文件,解出来的效果可能完全不一样,这块很玄学。

解决:看工具 README 是否带多个密钥表或者类似 -m qmc1_v2 的版本参数,有就换着试;没有的话只能找维护更全的工具。遇到这类文件,我一般会先保留原始文件,等找到匹配的工具版本再解,而不是拿新工具硬压。

提示:转换前永远留一份只读原文件,输出目录单独建。密钥表版本对不上或者变体识别错误时,原始文件就是你的后悔药。

6. 转换结果验证:用ffprobe确认还原本真,顺手把封面抽出来

6.1 逐文件核对编码参数

批量转完,我习惯跑一条汇总验证,把输出目录里所有音频的编码信息打出来:

find ~/Music/QMC_Converted -type f \( -name "*.flac" -o -name "*.mp3" \) -print0 \ | xargs -0 -I{} ffprobe -v error -show_entries stream=codec_name,sample_rate,channels,bits_per_raw_sample -of default=noprint_wrappers=1:nokey=0 "{}"

输出会按文件顺序打印 codec_name=sample_rate=channels=bits_per_raw_sample 组合,比如 flac=44100=2=16。真实无损下载对应该组合;如果看到 flac=96000=2=24,说明这是高解析度版本,也是正常的。对不上的文件,单独挑出来重新检查原扩展名和工具版本,别带着疑问进入下一步。

6.2 试听和封面核对

参数对完再试听一首,用 ffplay 可以直接播:

ffplay -nodisp -autoexit "输出.flac"

最后把封面抽出来看一眼是否完整:ffmpeg -i "输出.flac" -an -vcodec copy cover.jpg,封面缺失不影响听感,但如果你要整理曲库封面墙,这一步就别省。

我现在养成的习惯是:转换前先跑一次文件统计和 ffprobe 留底,转换后再对一次输出目录,两次对不上就去翻工具版本,不硬解。这个流程看起来多花两分钟,但能避免整批文件解错后才发现的大返工。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询