You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

macOS下Electron.js系统音频捕获方案求助:虚拟设备问题

macOS Electron 系统音频捕获方案及BlackHole排查

一、BlackHole安装后不显示的排查步骤

  • 检查内核扩展权限:macOS 10.15及以上版本需在「系统设置-隐私与安全性」中允许BlackHole的内核扩展,若安装时未弹出提示,重启系统后再次查看该面板。
  • 验证安装文件完整性:通过Homebrew安装的用户可执行brew list blackhole-2ch确认安装路径;手动安装的用户检查/Library/Audio/Plug-Ins/HAL/BlackHole.driver是否存在,且权限为root:wheel。
  • 重启Core Audio服务:终端执行sudo launchctl kickstart -k system/com.apple.audio.coreaudiod,重启音频服务后刷新设备列表。
  • 定制版签名检查:若为自行编译的BlackHole,需确保驱动已通过苹果公证或用开发者证书签名——未签名的驱动无法被macOS加载,测试阶段可临时关闭系统完整性保护(不推荐用于生产环境)。

二、Electron中系统音频捕获的实现方案

核心逻辑:借助虚拟音频设备中转系统音频,设为默认输出后捕获设备音频,使用完成恢复原设置。

1. 基于现成虚拟设备的快速实现(推荐)

确保BlackHole/Soundflower正常加载后,在Electron渲染进程中通过WebRTC API指定设备捕获:

// 获取所有音频输入设备
async function getAudioInputDevices() {
  const devices = await navigator.mediaDevices.enumerateDevices();
  return devices.filter(device => device.kind === 'audioinput');
}

// 捕获BlackHole设备的音频流
async function captureSystemAudioStream() {
  const devices = await getAudioInputDevices();
  const targetDevice = devices.find(d => d.label.includes('BlackHole'));
  if (!targetDevice) throw new Error('未检测到BlackHole设备');

  const audioStream = await navigator.mediaDevices.getUserMedia({
    audio: { deviceId: targetDevice.deviceId, echoCancellation: false }
  });
  // 可将audioStream用于录制、实时处理等场景
  return audioStream;
}

2. 动态创建虚拟聚合设备(进阶)

若需编程动态创建/销毁设备,可在Electron主进程中通过ffi-napi调用macOS CoreAudio原生API:

  • 封装AudioComponentFindNext、AudioComponentInstanceCreate等函数,创建聚合音频设备,将系统输出路由至该虚拟设备。
  • 捕获完成后销毁聚合设备,避免残留系统资源。
    注意:此方式需熟悉CoreAudio API细节,且需处理驱动签名与系统权限问题。

3. 系统默认设备的切换与恢复

在主进程中借助Electron的systemPreferences保存并恢复原默认输出设备:

const { systemPreferences } = require('electron');

// 保存原默认输出设备ID
const originalOutputDeviceId = systemPreferences.getUserDefault('com.apple.sound.default-output-device', 'string');

// 设置指定设备为默认输出
function setDefaultAudioOutput(deviceId) {
  systemPreferences.setUserDefault('com.apple.sound.default-output-device', 'string', deviceId);
}

// 恢复原默认输出设备
function restoreOriginalAudioOutput() {
  setDefaultAudioOutput(originalOutputDeviceId);
}

内容的提问来源于stack exchange,提问作者Muhammad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 00:27:23