BlackHole macOS 音频循环驱动深度解析:5 个版本怎么选、怎么构建
【免费下载链接】BlackHoleBlackHole is a modern macOS audio loopback driver that allows applications to pass audio to other applications with zero additional latency.项目地址: https://gitcode.com/gh_mirrors/bl/BlackHole
BlackHole 是一个现代化的 macOS 音频循环驱动:它以虚拟设备形式,把某个应用的输出直接接到另一个应用的输入上,在不需要内核扩展、不改动系统安全设置的前提下完成零额外延迟的音频路由(把一个应用的输出重定向到另一个应用的输入)。本文面向会跑 brew、看得懂终端输出的读者,从 5 个通道版本的选型决策讲起,拆解它的构建流水线、进阶配置参数,以及社区已经踩过的坑。
版本选型对照:5 个音频循环驱动版本怎么选
五个版本共用同一份源码,只在构建时以不同的通道数区分,差异体现在获取方式和目标场景上:
| 版本 | 通道数 | 获取方式 | 典型用户画像 | 选择依据 |
|---|---|---|---|---|
| BlackHole 2ch | 2 | Homebrew / 官方安装包 | 办公、在线会议用户 | 立体声即可覆盖绝大多数路由与录音需求,系统开销最小 |
| BlackHole 16ch | 16 | Homebrew / 官方安装包 | 播客、音乐制作人 | 多轨录音需要通道隔离,避免应用之间互相串扰 |
| BlackHole 64ch | 64 | Homebrew / 官方安装包 | 音频工程师 | 复杂路由矩阵,单个驱动承载几十路并行音频流 |
| BlackHole 128ch | 128 | 仅源码构建 | 专业工作室 | 通道需求超过 64,且团队具备 macOS 构建环境 |
| BlackHole 256ch | 256 | 仅源码构建 | 研究、极端场景 | 极限通道数需求,须同时关注 CPU 负载与采样率选择 |
所有版本同时支持 Intel 与 Apple Silicon,最低系统要求 macOS 10.10;采样率覆盖 8kHz 到 768kHz,位深统一固定为 32-bit float(Core Audio 在系统层面原生使用 32-bit float,该格式对 24-bit 整数无损,动态余量最大)。
版本定了就可以安装。最短路径走 Homebrew;目标是 128 或 256 通道时,只能走源码构建。
最短安装路径与完整部署流程
最短路径:Homebrew 安装
brew install blackhole-2ch # 需要 16ch / 64ch 时,换成 brew install blackhole-16ch 或 blackhole-64ch- 关闭所有正在运行的音频应用
- 安装完成后打开 Audio MIDI Setup
- 确认左侧列表出现 BlackHole 设备,通道数与版本对应(例如 16ch 显示 16 in / 16 out)
完整路径:从源码构建到卸载
git clone https://gitcode.com/gh_mirrors/bl/BlackHole.git cd BlackHole ./Installer/create_installer.sh # 完成后 Installer/ 下生成 BlackHole2ch-0.6.1.pkg 等 5 个安装包- 在仓库根目录运行构建脚本;若脚本没有可执行权限,先执行
chmod +x Installer/create_installer.sh。脚本会对 5 个通道版本依次做环境校验、编译、签名与公证 - 双击 .pkg 走标准安装;或手动把 BlackHoleXch.driver 包拷入
/Library/Audio/Plug-Ins/HAL - 重启 Core Audio(macOS 的系统音频服务)使驱动生效:
sudo killall -9 coreaudiod - 卸载:删除
/Library/Audio/Plug-Ins/HAL/BlackHoleXch.driver(X 替换为 2、16、64 等)再重启 Core Audio,或使用对应的 Uninstaller 安装包
注意:要删除的是系统级的 /Library,而不是用户目录下的 ~/Library。这是手动卸载时最常见的错误。
brew 拉到的 .pkg 与脚本构建出来的 .pkg 来自同一条流水线,下面拆解这条流水线。
构建流水线拆解:一个脚本产出 5 份音频路由安装包
问题:官方分发需要 5 个通道版本,每个版本使用不同的 Bundle ID(audio.existential.BlackHoleXch 形式)与安装包名。手工用 Xcode 编译 5 次、签名、打包,极易出错。
方案:Installer/create_installer.sh 用一个 for 循环覆盖2 16 64 128 256,循环内每个环节全部参数化。
关键实现:
xcodebuild以 Release 配置构建,通过GCC_PREPROCESSOR_DEFINITIONS注入 kNumber_Of_Channels、kPlugIn_BundleID、kDriver_Name 三个编译时常量;驱动源码 BlackHole/BlackHole.c 用#ifndef提供默认值(默认 2 通道),构建期定义优先生效uuidgen生成新 UUID 并用 awk 替换 Info.plist 中的旧 UUID,避免 5 个版本同时安装时设备 UID 冲突codesign --force --deep --options runtime签名,runtime 开启加固运行时,是后续公证的前提pkgbuild打包,安装位置固定为/Library/Audio/Plug-Ins/HAL,附带 preinstall(创建目录并 chown root:wheel)与 postinstall(递归 chown 驱动目录)两个脚本productbuild依据运行时生成的 distribution.xml 产出 .pkg,再由notarytool提交 Apple 公证(Apple 对分发包的离线恶意代码扫描与出证)、stapler装订票据;版本号统一读自 VERSION 文件,当前为 0.6.1
卸载侧有对应的 Uninstaller/create_uninstaller.sh,生成带--nopayload(无载荷、仅脚本)的安装包,作用是删除驱动目录并重启 coreaudiod。
构建脚本面向分发,对进阶玩家更有价值的是驱动内部的配置模型。
进阶配置:镜像设备与自定义构建参数
所有定制都通过编译时常量完成,经xcodebuild的GCC_PREPROCESSOR_DEFINITIONS注入,无需改动源码。
场景一:希望输入与输出显示为两个可见设备。BlackHole 默认带一个隐藏的镜像设备(与主设备共享同一块环形缓冲区,环形缓冲区是固定容量、读写指针循环使用的缓冲)。把主设备与镜像设备的 IsHidden 都设为 false 后会显示两个 BlackHole;若只需要「一个纯输入 + 一个纯输出」:
| 常量 | 主设备 | 镜像设备(kDevice2_*) |
|---|---|---|
| kDevice_IsHidden | false | false |
| kDevice_HasInput | true | false |
| kDevice_HasOutput | false | true |
预期:出现两个可见设备,一个只有输入、一个只有输出,输出设备送入的音频会出现在输入设备上。隐藏设备也可通过kAudioHardwarePropertyTranslateUIDToDevice在程序里定位。
场景二:定制通道数、延迟、采样率。常见常量:
| 常量 | 作用 | 说明 |
|---|---|---|
| kNumber_Of_Channels | 通道数 | 2 / 16 / 64 / 128 / 256 |
| kLatency_Frame_Size | 驱动内部延迟帧数 | 默认 0;最多可延迟 65536 帧,高通道数下可缓解 CPU 压力 |
| kSampleRates | 采样率列表 | 默认覆盖 8kHz 至 768kHz,逗号分隔可裁剪 |
| kCanBeDefaultDevice / kCanBeDefaultSystemDevice | 是否允许成为默认设备 | 0.6.0 新增 |
| kDriver_Name / kPlugIn_BundleID / kPlugIn_Icon | 改名 | BundleID 需与 target 的 bundleID 一致 |
警告:高通道数不要叠加高采样率。环形缓冲区按 Float32 分配,通道数 × 采样率的乘积过大时,系统可能跟不上。
配置吃透之后,剩下的就是社区已经验证过的坑。
避坑手册:7 个高频问题
Q1:安装后应用程序文件夹里为什么找不到 BlackHole?结论:正常现象。它是 HAL(Hardware Abstraction Layer,macOS 的音频设备抽象层)虚拟驱动,不是应用。到 Audio MIDI Setup 或「系统偏好设置 → 声音」确认设备,应能看到与版本对应的输入/输出通道数。
Q2:要一边用扬声器听声音、一边把音频送入 BlackHole?结论:创建「多输出设备」。步骤:Audio MIDI Setup 点 + → 创建多输出设备,同时勾选 Built-in Output 与 BlackHole,再到系统偏好设置里选中该多输出设备。原因:单个输出只能指向一个设备,多输出设备会把同一路数据同时写入多个设备。另注意 macOS 不支持调整多输出设备的整体音量,只能在 Audio MIDI Setup 内逐个调整成员设备;Apple Podcasts、Apple Messages、HDHomeRun 与多输出设备不兼容。
Q3:把 BlackHole 放进多输出设备后没有声音?结论:Built-in Output 必须勾选,且排在设备列表第一位。步骤:打开多输出设备设置,勾选 Built-in Output 并把它拖到最上方。原因:多输出设备以列表中第一个设备为时钟源,Built-in Output 不在首位会导致整条链路无声。
Q4:多输出或聚合设备用了几分钟后音频开始卡断?结论:给除主设备外的所有设备开启 Drift Correction(时钟漂移校正)。步骤:在 Audio MIDI Setup 中,为时钟源(Primary Device)之外的每个设备勾选漂移校正。原因:各设备采样率存在微小偏差,随时间累积后表现为卡断。
Q5:聚合设备里把 AirPods 设为主时钟不工作?结论:AirPods 麦克风不能用作主时钟。步骤:改用内置扬声器(直接静音)或 BlackHole 2ch 作为 primary/clock 设备。原因:AirPods 麦克风的采样率较低,不适合做时钟源;BlackHole 16ch 同样不能当主设备,因为主设备必须是 2 通道。
Q6:.pkg 安装包突然装不上?结论:移动文件位置后重试。步骤:若 .pkg 在「下载」文件夹,移到「桌面」(或反之)再双击安装。原因:某些 macOS 版本存在已知问题,安装包文件所在位置会影响安装成败。
Q7:BlackHole 的位深能设成 24-bit 或 16-bit 吗?结论:不能,固定 32-bit float。原因:Core Audio 系统层面原生就是 32-bit float,该格式对 24-bit 整数无损,兼容性与动态余量最大;24-bit、16-bit 支持目前还在项目的功能请求列表里。
社区协作:如何跟进版本演进与贡献
BlackHole 采用 GPL-3.0 许可,嵌入非 GPLv3 应用需要向 Existential Audio 购买商业授权。版本记录见 CHANGELOG.md,当前 0.6.1 的改动集中在安装器与设备时钟属性;路线图包括更多位深、与其他音频设备的时钟同步、安装器直接创建多输出设备。构建脚本本身就是 CI/CD 集成的官方样例,README 明确建议参考 create_installer.sh 把 BlackHole 接入自有流水线。
落地结论:装完 BlackHole 你得到什么
- ✅ 一个装完即现身的系统级环回设备,驱动本身零额外延迟
- ✅ 5 个通道版本走同一套签名与公证流程,任何一份安装包都不需要单独做信任验证
- ✅ 无内核扩展、无系统安全设置改动,卸载只需删除一个目录并重启 coreaudiod
- ✅ 镜像设备与编译时常量为二次开发预留了明确接口
先跑一条brew install blackhole-2ch验证工作流;立体声不够用时切换到 16ch 或 64ch 的 Homebrew 版本,或按文中的流水线自行构建 128/256ch。
【免费下载链接】BlackHoleBlackHole is a modern macOS audio loopback driver that allows applications to pass audio to other applications with zero additional latency.项目地址: https://gitcode.com/gh_mirrors/bl/BlackHole
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考