You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Electron应用录制设备输入输出音频的可行方案咨询

实现Electron应用录制系统输出音频的方案

老兄,你说的完全没错——navigator.mediaDevices.getUserMedia确实只能搞定麦克风这类输入设备的音频捕获,没法直接抓取系统输出的声音。不过在Electron生态里,我们有专门的工具能解决这个问题,下面给你两种实用的实现方案,都是Electron开发里常用的思路:

方法一:用Electron的desktopCapturer直接捕获系统音频

这是最贴合Electron原生能力的方案,desktopCapturer是Electron官方提供的API,专门用于捕获桌面内容(包括系统音频流)。

实现步骤&代码示例

首先要确保你的Electron应用配置了必要的权限:在主进程的BrowserWindow配置里,webPreferences需要开启nodeIntegration(或者用预加载脚本暴露API,这里先给基础写法)。

然后在渲染进程里写捕获逻辑:

async function startSystemAudioRecording() {
  try {
    // 请求获取桌面音频源
    const sources = await electron.desktopCapturer.getSources({
      types: ['audio'],
      audio: true
    });

    // 匹配系统音频源(不同系统的名称不一样,需要兼容)
    const systemAudioSource = sources.find(source => 
      source.name.includes('系统音频') || 
      source.name.includes('System Audio') ||
      source.name.includes('BlackHole') // Mac上的虚拟音频设备名称
    );

    if (!systemAudioSource) {
      alert('没找到系统音频源!Windows请检查系统权限,Mac需要先安装BlackHole这类虚拟音频设备');
      return;
    }

    // 创建包含系统音频的媒体流
    const streamConstraints = {
      audio: {
        mandatory: {
          chromeMediaSource: 'desktop',
          chromeMediaSourceId: systemAudioSource.id
        }
      }
    };
    const audioStream = await navigator.mediaDevices.getUserMedia(streamConstraints);

    // 用MediaRecorder录制流(和你之前录麦克风的逻辑一致)
    const recorder = new MediaRecorder(audioStream);
    const audioChunks = [];

    recorder.ondataavailable = (event) => audioChunks.push(event.data);
    recorder.onstop = () => {
      const audioBlob = new Blob(audioChunks, { type: 'audio/webm' });
      // 这里可以把录制好的音频保存到本地或者做其他处理
      const downloadLink = document.createElement('a');
      downloadLink.href = URL.createObjectURL(audioBlob);
      downloadLink.download = 'system-audio-recording.webm';
      downloadLink.click();
    };

    recorder.start();
    console.log('系统音频录制开始啦!');
    // 示例:5秒后自动停止录制
    setTimeout(() => recorder.stop(), 5000);
  } catch (error) {
    console.error('捕获系统音频失败:', error);
  }
}

系统兼容注意事项

  • Windows:原生支持系统音频捕获,不需要额外安装工具,直接用就行
  • macOS:苹果默认不允许直接捕获系统音频,必须先安装虚拟音频设备(比如BlackHole),然后在系统音频设置里把输出设备切换到这个虚拟设备,才能被desktopCapturer识别
  • Linux:大部分发行版需要依赖PulseAudio组件,配置好音频路由后就能正常捕获

方法二:用虚拟音频设备混合输入+输出音频

如果你需要同时录制麦克风输入和系统输出的声音,这种方案更合适——通过虚拟音频设备把两种音频流混合,再用getUserMedia捕获混合后的流。

实现步骤

  1. 安装虚拟音频设备:Windows用Voicemeeter,Mac用BlackHole,Linux用PulseAudio Loopback
  2. 系统音频设置配置:把系统输出和麦克风输入都路由到虚拟设备
  3. 在Electron里捕获这个虚拟设备的音频流

代码示例

async function startMixedAudioRecording() {
  try {
    // 获取所有音频输入设备
    const audioDevices = await navigator.mediaDevices.enumerateDevices();
    // 找到我们配置的虚拟音频设备
    const virtualDevice = audioDevices.find(device => 
      device.kind === 'audioinput' && 
      (device.label.includes('BlackHole') || device.label.includes('Voicemeeter'))
    );

    if (!virtualDevice) {
      alert('没找到虚拟音频设备,请先安装并完成系统配置');
      return;
    }

    // 捕获虚拟设备的音频流
    const streamConstraints = {
      audio: { deviceId: virtualDevice.deviceId }
    };
    const mixedStream = await navigator.mediaDevices.getUserMedia(streamConstraints);

    // 后续录制逻辑和之前完全一致
    const recorder = new MediaRecorder(mixedStream);
    const audioChunks = [];

    recorder.ondataavailable = (e) => audioChunks.push(e.data);
    recorder.onstop = () => {
      const mixedBlob = new Blob(audioChunks, { type: 'audio/webm' });
      // 处理录制好的混合音频
      const url = URL.createObjectURL(mixedBlob);
      const a = document.createElement('a');
      a.href = url;
      a.download = 'mixed-audio-recording.webm';
      a.click();
    };

    recorder.start();
    console.log('混合音频录制开始!');
  } catch (error) {
    console.error('捕获混合音频失败:', error);
  }
}

额外提示

  • 打包应用时,记得在package.json里声明desktopCapture权限,避免权限问题
  • 可以调整MediaRecorder的配置参数来提升音频质量,比如指定比特率:new MediaRecorder(stream, { audioBitsPerSecond: 192000 })
  • 不同系统的音频源名称差异较大,建议在代码里做更灵活的匹配逻辑,或者让用户手动选择设备

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

火山引擎 最新活动