ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

macOS 上 QMC 音频解密与批量转换:qmcflac/mflac 转 FLAC 实战

macOS 上 QMC 音频解密与批量转换:qmcflac/mflac 转 FLAC 实战 简介面向苹果系统macOS用户的QQ音乐QMC格式转换工具完整源码支持将qmcflac、mflac等加密音频无损还原为flac格式也能将qmc0、qmc3等转成mp3有效解决离线音乐受播放器限制的问题。项目以Xcode工程形式交付共计三十四个文件核心为九个Swift源文件涵盖解密算法、界面控制、窗口交互与测试用例另配有十一张界面展示图、plist与json配置文件、项目说明文档等压缩包仅约946KB体积轻巧且目录规整方便导入后直接编译。该源码适合计算机、数学、电子信息等专业用于课程设计、期末大作业或毕业设计也可作为编程新手理解音频保密算法、掌握Swift应用开发的实战范例。已有1405人学习浏览代码可直接运行既能作为即用工具处理手头音频也便于深入调试进一步扩展格式支持或自定义界面。整体工程结构清晰从界面到核心解码逻辑层次分明适合循序渐进地学习和复用。1. 先把 QMC 这个词说透为什么下载到的是 qmcflac 而不是 flac你在 QQ 音乐里下载会员无损本地多出来的不是.flac而是.qmcflac、.qmc0、.qmc3、.mflac、.mflac0这一串看起来像乱码的后缀。这些文件技术上属于同一个家族QMC 加密音频。所谓「QMC 格式转换为普通格式」绝大多数情况下做的不是转码而是解密——qmcflac解密后本身就是一段标准 FLACqmc0/qmc3解密后本身就是标准 MP3。这也是很多新手第一次动手时最反直觉的地方拿到一个 macOS 工具包以为要设置一堆码率参数其实核心操作只有两步——把文件解开把后缀改对。这篇笔记就按这个思路走一遍怎么识别手里的文件属于哪一代加密、怎么在 macOS 上批量解开、解完怎么验证没翻车以及那些只有实际跑过才会遇到的坑。2. QMC 家族的五种后缀怎么分从文件头魔数判断旧版静态密钥与新版动态密钥QMC 不是一种算法而是两代方案的合称。macOS 上的通用解密器之所以要分别处理qmcflac、qmc0、qmc3和mflac、mflac0就是因为这两代方案的解密路径完全不同。2.1 旧版 qmcflac / qmc0 / qmc3一把固定的“锁”旧版加密对应qmcflac、qmc0、qmc3这三种后缀用的是静态密钥方案。所谓静态就是所有客户端共享同一套固定的密钥数据加密侧把明文字节按密钥表做逐字节置换或异或解密侧拿同一张表反向操作一遍就能还原。这种方案实现非常简单客户端里藏一张表就行运行开销也小。代价是安全性弱只要有人从客户端二进制里把密钥表提取出来全版本的文件都能解。社区里流传的绝大多数 QMC 解密脚本核心逻辑就是拿这张固定表对整段文件逐字节处理所以qmcflac解密速度非常快一份 30MB 的无损文件都是毫秒级完成根本不涉及重编码。需要理解的是qmcflac和qmc0/qmc3虽然后缀不同但加密骨架是同一套区别只在内部承载的音频容器。qmcflac承载的是 FLAC 流qmc0、qmc3承载的是 MP3 流。这也是为什么“qmcflac 转 flac、qmc0/qmc3 转 mp3”这种说法在社区里流传最广——解密算法一样按容器补对后缀即可。2.2 新版 mflac / mflac0密钥不在全局在文件里新版加密对应mflac和mflac0以及同门容器mgg方案换成了动态密钥。每个文件的密钥内容都不一样且密钥数据被藏进文件本身——有的放在文件头部区域有的放在文件尾部带标志的片段里而且按0x8000字节分块的解密逻辑也不同前若干块走静态映射后续块用流式密钥处理。这就让解密器的工作从“读表异或”变成了“先解析密钥区再按分段规则解密”。社区实现之间最大的差异就在密钥区的定位上解析偏移差一个字节解密出来的文件就是废的。所以你会看到很多解密工具对mflac的支持晚于qmcflac不是开发者懒而是新版的定位逻辑确实要花时间逆向。mflac与mflac0的关系也常被误解两者承载的都是 FLAC 流区别在密钥存放位置不同解密器内部会有两套解析分支但最终输出都是标准 FLAC。标题里写的“mflac,mflac0等转flac”说的就是这条路径解密然后补.flac后缀不重编码。2.3 用 xxd 看文件头三行命令判断加密世代拿到文件先别急着拖进工具终端里看一眼文件头比什么都有用。macOS 自带xxd直接十六进制查看前几行xxd 林俊杰 - 修炼爱情.qmcflac | head -4标准 FLAC 文件的头四个字节是固定的66 4C 61 43也就是 ASCII 的fLaC标准 MP3 则通常以49 44 33ID3开头。如果文件还处于加密态前四字节必然对不上这两个值——旧版文件头会是一段固定的魔数不同版本客户端提取出来的魔数略有差异新版文件头则是一段描述字段或直接是乱码。判断逻辑很简单#!/usr/bin/env bash # 判断一个音频文件是否处于 QMC 加密态 f$1 head -c 4 $f | xxd -p对比输出664c6143是fLaC说明这文件是明文 FLAC不需要解密494433开头说明是明文 MP3。其余值一律按加密态处理。我一般会把这个命令写成一个 5 行的 shell 函数批量扫描目录时先筛一遍免得把已经解过的文件再解一次输出损坏文件。2.4 解密后到底是 FLAC 还是 MP3先认容器再定方案后缀和最终输出格式的对应关系整理成一张表会清楚很多源后缀内部承载容器解密后的目标格式处理方式.qmcflacFLAC.flac解密 补后缀.mflacFLAC.flac解密解析动态密钥 补后缀.mflac0FLAC.flac解密解析动态密钥 补后缀.qmc0MP3.mp3解密 补后缀.qmc3MP3.mp3解密 补后缀.mggOGG 容器视情况转码解密后用 ffprobe 确认实际编码再决定是否二次转码这张表最核心的结论是前五行的“转换”不损失任何音质因为压根没有重编码只有mgg这类从 OGG 容器里拆出来的流才可能需要用 FFmpeg 做一次真正的转码。搞清楚这一点你就不会再对着“qmcflac 转 flac”去设置什么比特率了——那一步没有参数可调调了反而是二次有损。提示解密前先备份原始加密文件尤其是 mflac 系列。解密器的密钥区解析偶尔会因客户端版本差异而偏移保留原件是唯一的后悔药。3. 在 macOS 上跑通批量转换从 zip 解压到输出 FLAC/MP3 的完整命令标题里的工具包标注“仅支持 macOS”这类包落地时第一个坑往往是架构第二个坑才是解密命令本身。这一章按实际执行顺序写选对版本、跑通单文件、扩展到批量、最后验证。3.1 先看芯片再选工具arm64 与 x86_64 的坑macOS 工具包如果自带编译好的可执行文件通常会区分 Apple Silicon 和 Intel 两个版本。选错版本的表现不是“不能运行”而是终端直接报Exec format error或提示没有权限。先确认当前机器架构# 确认当前 macOS 的 CPU 架构 uname -m # arm64 Apple SiliconM1/M2/M3/M4 # x86_64 Intel Mac再检查工具包里的可执行文件是什么架构# 假设 zip 已经解压到 ~/qmc-tool cd ~/qmc-tool file ./bin/qmc_decode # 输出里会明确写 architecture: x86_64 或 arm64如果包里只有一个 x86_64 版本而你用的是 Apple Silicon可以试着用 Rosetta 2 兜底arch -x86_64 ./bin/qmc_decode -h但如果arch命令都提示二进制无法加载就别折腾了找对应 arm64 版本的工具才是正路。做这一步时我通常还会顺手看一眼二进制是否有执行权限ls -l ./bin/qmc_decode chmod x ./bin/qmc_decode # 没有 x 权限时执行zip 解压出来的文件经常不带执行位这是 macOS 上最常见的第一道拦截跟工具本身无关。3.2 解密这一步qmcflac、mflac 批量转 FLAC 的最小脚本假设你下载的 zip 里是一个命令行工具名字可能是qmc_decode之类以你实际解压出来的文件名为准。单文件解密先跑通./bin/qmc_decode -i 测试.qmcflac -o 测试.flac因为解密是逐字节还原源文件多大输出就多大过程非常快。跑通单文件后就可以上批量脚本了#!/usr/bin/env bash # qmc_batch.sh 批量解密 QMC 家族文件到指定输出目录 set -euo pipefail DECODER./bin/qmc_decode # 换成你 zip 里解压出的实际可执行文件路径 SRC_DIR$1 # 第一个参数源目录 OUT_DIR$2 # 第二个参数输出目录 mkdir -p $OUT_DIR find $SRC_DIR -type f \( -iname *.qmcflac -o -iname *.qmc0 \ -o -iname *.qmc3 -o -iname *.mflac -o -iname *.mflac0 \) \ -print0 | while IFS read -r -d f; do # 去掉最后一个后缀得到纯文件名 base$(basename ${f%.*}) # 解密器先输出无后缀中间文件再由下面的 case 决定补什么后缀 $DECODER -i $f -o $OUT_DIR/$base case ${f##*.} in qmcflac|mflac|mflac0) mv $OUT_DIR/$base $OUT_DIR/$base.flac ;; qmc0|qmc3) mv $OUT_DIR/$base $OUT_DIR/$base.mp3 ;; esac done echo done几个容易忽略的参数说明set -euo pipefail里-e表示任何命令失败立即退出-u拦截未定义变量pipefail让管道中任一步失败都能被捕获。批量场景下这三个开关能避免“跑一半还以为成功了”的假象。find的-print0必须搭配while IFS read -r -d 使用这样文件名里的空格、中文、emoji 都不会拆断循环。先输出无后缀中间文件、再由case决定补什么后缀是为了防一手“工具对容器判断错误”。如果解出来的实际是 OGG 但补了.flac后面 ffprobe 验证时会现出原形到时再做二次转码即可。如果你的解密工具本身就支持直接输出带后缀的文件那就把case分支简化成纯文件重命名逻辑脚本骨架不用动。3.3 用 ffprobe 与 metaflac 验证输出没翻车批量跑完后最怕的是输出目录里一堆“看似正常但打不开”的文件。验证这一步不能省# 安装 ffmpegffprobe 随附 brew install ffmpeg # 验证单个 FLAC 是否可解析并读取基础信息 ffprobe -v error -show_entries formatformat_name,duration,bit_rate \ -of defaultnoprint_wrappers1 输出/林俊杰 - 修炼爱情.flac正常输出会看到format_nameflac、duration和bit_rate。如果format_name显示ogg而你补了.flac后缀说明这个源文件其实是mgg那一族需要二次转码。FLAC 特有的标签和封面可以用metaflac查先装依赖brew install flac metaflac --list 输出/测试.flac这条命令会列出所有 VORBIS_COMMENT 标签和图片块。如果标签是空的说明解密工具没有保留源文件的元数据后面第 5 章会讲怎么补。macOS 没有装 FFmpeg 之前也可以用系统自带的afinfo做轻量验证afinfo 输出/测试.flac | head -20afinfo能读出采样率、位深、时长但不会告诉你容器格式是否匹配后缀所以最可靠的还是ffprobe。提示验证时不要只看文件大小。解密失败的文件有时大小看起来正常但 ffprobe 会直接报Invalid data found。以 ffprobe 的输出为准不要以“能播放”为准。3.4 碰到 96kHz/24bit 的 qmcflac要不要二次转码成 ALACQQ 音乐的高解析度无损下载下来是 96kHz/24bit 的qmcflac解密后就是标准 96/24 FLAC这时很多 mac 用户会想转到 ALAC 放进 Apple 生态。但“flac 96khz 24bit 转换alac失败”是搜索热词不是没原因的FFmpeg 在某些版本下对 96kHz ALAC 编码会报参数错误。最稳的方案是直接用 macOS 自带的afconvert不走 FFmpeg# 把 96kHz/24bit FLAC 转成 ALACm4a 容器 afconvert 输入/测试.flac 输出/测试.m4a -f m4af -d alac-f m4af指定 M4A 容器-d alac指定编码器。如果转换时提示采样率不支持可以先显式指定afconvert 输入/测试.flac 输出/测试.m4a -f m4af -d alac96000这里有一个容易被带偏的参数认知解密本身不涉及重采样但转 ALAC 时要明确保持原采样率。除非你的播放器硬件不支持 96kHz否则不要降采样到 44.1kHz——那不是“兼容优化”是音质损失。参数对比看这张表目标场景命令参数要点解密 qmcflac解密器 改名无重编码不要设码率验证解密结果ffprobe -v error ...看 format_name 是否匹配后缀FLAC 转 ALACafconvert -f m4af -d alac显式96000保持采样率mgg 内 OGG 转 FLACffmpeg -i in.ogg -c:a flac out.flac真正有损/无损转换FLAC 无损4. 避坑与排查解密失败、假转码、标签丢失的五个现场这一章全是从实际批量转换里踩出来的问题。每条按“现象 → 原因 → 解决”的顺序写可以直接当排查手册用。4.1 ffprobe 报 Invalid data老工具解新文件的翻车现场现象解密工具跑完文件后缀也对了但ffprobe一查就报Invalid data found while processing input文件打不开。原因新版mflac/mflac0用了动态密钥旧版工具只实现了静态密钥表逻辑或者密钥区解析的偏移算法与当前客户端版本不匹配。解密输出是一堆错位字节FLAC 的fLaC魔数在文件头就校验失败。解决先按 2.3 的方法head -c 4看输出文件头确认开头是不是66 4C 61 43。不是的话换支持新版动态密钥的 macOS 解密工具。如果工具本身有两个模式比如--old和--v2强制指定新版模式重新解一遍。这个场景里最容易犯的错是“换了个文件重新试”结果工具版本没换白跑一趟。4.2 改后缀能放但不等于解密假转码的危害现象把.qmcflac直接改成.flac用某些播放器能放出来但进度条拖动卡顿时长显示不对或者放到一半跳帧。原因播放器把加密数据当作 FLAC 解析时靠“碰运气”读到了部分可解码的帧片段但这不代表整个文件是合法 FLAC。QMC 旧版的加密只处理了部分字节音频帧偶尔能凑巧解出声音于是给人“成功了”的错觉。这种假转码在论坛里坑过不少人。解决判断标准只有一个——ffprobe -v error不报错并且format_nameflac。别用什么“能放就行”当标准。同理qmc0直接改.mp3如果播放器能放八成也是假象用ffprobe查一眼就现原形。4.3 macOS 首次运行被拦Gatekeeper 与可执行权限现象双击工具没反应终端里运行报Permission denied或者系统弹窗提示“无法打开因为无法验证开发者”。原因macOS 的 Gatekeeper 会对从网络下载的可执行文件做隔离标记同时 zip 解压可能丢掉了 Unix 执行位。两个问题叠加在一起新手很容易误判成“工具坏了”。解决先看权限再清隔离标记chmod x ./bin/qmc_decode xattr -d com.apple.quarantine ./bin/qmc_decode 2/dev/null || truexattr用于移除下载隔离属性2/dev/null || true是因为有些文件本来就没有这条属性报错也没关系直接跳过。做完这两步再运行。Apple Silicon 上如果还提示架构不符按 3.1 的arch -x86_64兜底。4.4 文件名带空格和 emoji批量脚本跑到一半停住现象批量脚本处理到某个文件时直接退出前面处理好的文件都在后面全部没跑。原因脚本里用了for f in $(find ...)文件名一遇到空格就被拆成多个词qmc_decode收到错误参数直接报错退出如果还开着set -e整个循环立即中断。解决用find -print0配合while IFS read -r -d 这是 3.2 脚本里已经写进去的写法。自己手写批量命令时只要看到for f in后面跟的是命令替换就要警惕空格问题。中文和 emoji 文件名在 macOS 上用的是 UTF-8只要脚本文件本身保存为 UTF-8一般不会出问题但保险起见脚本里可以加一句export LC_ALLen_US.UTF-8这行对环境变量要求不高的工具没影响但能避免某些 C 标准库函数在非 ASCII 路径上解出乱码。4.5 拿 QMC 工具解 mgg/kgg/ncm加密方案不是一家现象把.mgg、.kgg、.ncm文件拖进 QMC 专用工具工具报“未知格式”或直接无输出。原因.mgg虽然和mflac同属新版体系但容器是 OGG 而非 FLAC.kgg是酷狗的加密格式.ncm是网易云音乐的加密格式。三家公司的加密方案各自独立QMC 解密器只认 QMC 家族跨平台解密是另一套工具链。解决先分清楚你手里的文件属于哪家再用对应的解密流程。mgg解密后通常得到 OGG 容器需要ffprobe确认实际编码可能是 Opus之后按需转 FLAC 或 MP3。.ncm解密后常见输出是 MP3 或 FLAC取决于原始音质。.kgg解密后同样先用 ffprobe 判定。这类跨格式转换的场景里FFmpeg 几乎是绕不开的我在 3.3 装的ffmpeg在这里就能派上用场。5. 进阶用法批量并行、文件名安全与封面/歌词补全前面几章能把文件解出来但离“可以直接归档进播放器”还差两步批量速度以及标签与封面的完整性。5.1 用 find -print0 兜底特殊文件名4.4 已经解释了为什么空格会拆断循环。这里给一个可以直接替换 3.2 脚本的进阶版本把多段 find 合并成一次扫描顺便用-print0保证文件名绝对安全#!/usr/bin/env bash # qmc_batch_v2.sh 文件名安全版 set -euo pipefail DECODER./bin/qmc_decode SRC_DIR$1 OUT_DIR$2 mkdir -p $OUT_DIR # 一次性匹配 QMC 家族所有后缀-print0 保证特殊字符不拆词 find $SRC_DIR -type f \ \( -iname *.qmcflac -o -iname *.qmc0 -o -iname *.qmc3 \ -o -iname *.mflac -o -iname *.mflac0 \) \ -print0 | while IFS read -r -d f; do rel${f#$SRC_DIR/} # 去掉源目录前缀保留子目录结构 out_base${rel%.*} # 去掉加密后缀 mkdir -p $OUT_DIR/$(dirname $out_base) # 按子目录归档 case ${f##*.} in qmcflac|mflac|mflac0) $DECODER -i $f -o $OUT_DIR/$out_base.flac ;; qmc0|qmc3) $DECODER -i $f -o $OUT_DIR/$out_base.mp3 ;; esac done关键改动在第 13 行和第 16 行用rel保留源目录里的相对路径输出时同步重建子目录结构避免几百个文件全堆在一个目录里后续归档找不到专辑对应关系。这个版本是我现在批量转换的默认脚本-print0和相对路径两个点一并解决了。5.2 多核并行提升全量转换速度xargs -PQMC 解密本身很快但文件数量上千时单线程循环仍然可能跑上几分钟。解密是纯 CPU 密集操作适合并行。用xargs -P是最省事的做法# 列出所有 qmcflac/mflac/mflac0并行 4 核解密 find $SRC_DIR -type f \( -iname *.qmcflac -o -iname *.mflac \ -o -iname *.mflac0 \) -print0 | \ xargs -0 -P 4 -I {} ./bin/qmc_decode -i {} -o $OUT_DIR/{}.out参数说明-P 4表示同时跑 4 个进程-I {}把文件名占位符传进命令。并行数不建议直接拉满到 CPU 核心数QMC 解密时的新版解析有一定内存开销4 到 6 个进程是速度和稳定性的折中。跑完后别忘了把所有.out结尾的文件统一改后缀或者直接在并行命令里按源后缀分支处理。5.3 最后一步补标签用 mutagen 恢复标题、封面与内嵌歌词解密工具输出的文件经常是“裸奔”的没有标题、没有封面、没有专辑信息。如果你是按“歌手 - 歌名”命名的文件可以用 Python 的 mutagen 库直接从文件名重建标签# 先安装 mutagen python3 -m pip install mutagen写一个标签恢复脚本#!/usr/bin/env python3 # restore_tags.py 按文件名“歌手 - 歌名”补全 FLAC/MP3 基础标签 import sys from pathlib import Path from mutagen.flac import FLAC from mutagen.id3 import ID3 def split_name(stem: str): # 兼容“歌手 - 歌名”和“歌手 - 歌名 - 专辑”两种写法 parts [p.strip() for p in stem.split(-)] if len(parts) 3: return parts[0], parts[1], parts[2] # artist, title, album if len(parts) 2: return parts[0], parts[1], None return 未知歌手, stem, None for arg in sys.argv[1:]: path Path(arg) artist, title, album split_name(path.stem) if path.suffix.lower() .flac: audio FLAC(path) audio[artist] artist audio[title] title if album: audio[album] album audio.save() elif path.suffix.lower() .mp3: tags ID3(path) tags.add(mutagen.id3.TPE1(encoding3, text[artist])) tags.add(mutagen.id3.TIT2(encoding3, text[title])) if album: tags.add(mutagen.id3.TALB(encoding3, text[album])) tags.save()注意脚本里省掉了import mutagen.id3的显式引用实际使用时补上即可。mutagen.flac的audio[key]value是写 VORBIS_COMMENT 的标准方式mutagen.id3则是向 MP3 写 ID3 帧。封面图如果原始加密文件里有残留可以用FLAC.add_picture()或ID3的APIC帧写入这里不再展开。提示标签恢复永远在解密验证通过之后做。先 4.1 的 ffprobe 确认文件结构正常再补标签否则写进去的标签也随损坏文件一起浪费。6. 一个救回整张专辑的操作习惯转换后先抽样验证再归档我的习惯是任何批量转换之后不直接往播放器里拖先跑一个一次性的验证脚本把“坏文件”全部挑出来#!/usr/bin/env bash # verify_dir.sh 递归验证目录下所有 flac/mp3输出 OK 与 BAD 清单 find $1 -type f \( -iname *.flac -o -iname *.mp3 \) -print0 | \ while IFS read -r -d f; do if ffprobe -v error $f /dev/null 21; then echo OK $f else echo BAD $f fi done跑出来的BAD列表才是真正需要重新解密或转码的文件。这个小脚本看起来不起眼但能省下大量手动试听的时间。我最早转换一批两千多首的 qmcflac 时图快直接忽略验证结果归档后才发现有一百多首 mflac 被旧版工具解坏了之后再补跑一次全量前后折腾两遍。那之后我给自己定的规矩是单文件跑通 → 抽样 5 首验证 → 全量执行 → 全量验证四步缺一不可。抽样那一步尤其值得坚持因为解密工具的版本兼容问题只会在特定客户端文件上暴露抽 5 首能暴露大多数问题而全量验证只是最后的兜底。保留原始加密文件也是同一个道理解坏了随时能重来。希望这篇笔记能让你第一次批量转换 QMC 文件就顺利走完少踩我当年那些坑。本文还有配套的精品资源点击获取
返回列表