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

ReactJS项目中如何仅通过音频授权录制系统输出音频?

解决方案

利用浏览器系统音频设备枚举方案

现代浏览器(如Chrome、Edge)会将系统音频输出(对应Windows的「立体声混音」、Mac需手动启用的「内部音频」等)作为可选音频输入设备暴露。你可以通过设备枚举让用户选择对应系统音频设备,再仅请求音频授权获取流,完全不需要屏幕录制权限。

React 实现示例代码

import { useEffect, useState } from 'react';

const SystemAudioRecorder = () => {
  const [systemAudioDevices, setSystemAudioDevices] = useState([]);
  const [selectedDeviceId, setSelectedDeviceId] = useState('');
  const [recorder, setRecorder] = useState(null);

  // 枚举并筛选系统音频设备
  useEffect(() => {
    const fetchAudioDevices = async () => {
      try {
        // 先请求基础音频授权,才能获取带标签的设备列表
        await navigator.mediaDevices.getUserMedia({ audio: true });
        const allDevices = await navigator.mediaDevices.enumerateDevices();
        // 筛选系统音频相关设备,标签关键词需适配不同系统
        const targetDevices = allDevices.filter(device => 
          device.kind === 'audioinput' && 
          (device.label.includes('立体声混音') || device.label.includes('系统音频') || device.label.includes('Internal Audio'))
        );
        setSystemAudioDevices(targetDevices);
      } catch (err) {
        console.error('设备枚举失败:', err);
      }
    };
    fetchAudioDevices();
  }, []);

  // 启动录制
  const startRecording = async () => {
    if (!selectedDeviceId) return;
    try {
      const audioStream = await navigator.mediaDevices.getUserMedia({
        audio: { deviceId: { exact: selectedDeviceId } }
      });
      const mediaRecorder = new MediaRecorder(audioStream);
      const recordedChunks = [];

      mediaRecorder.ondataavailable = (e) => recordedChunks.push(e.data);
      mediaRecorder.onstop = () => {
        const audioBlob = new Blob(recordedChunks, { type: 'audio/webm' });
        // 处理录制完成的音频Blob,比如下载或上传
        const downloadLink = document.createElement('a');
        downloadLink.href = URL.createObjectURL(audioBlob);
        downloadLink.download = 'system-audio-recording.webm';
        downloadLink.click();
      };

      mediaRecorder.start();
      setRecorder(mediaRecorder);
    } catch (err) {
      console.error('获取系统音频流失败:', err);
    }
  };

  // 停止录制
  const stopRecording = () => {
    recorder?.stop();
    recorder?.stream.getTracks().forEach(track => track.stop());
    setRecorder(null);
  };

  return (
    <div>
      <select 
        value={selectedDeviceId}
        onChange={(e) => setSelectedDeviceId(e.target.value)}
        disabled={systemAudioDevices.length === 0}
      >
        <option value="">选择系统音频设备</option>
        {systemAudioDevices.map(device => (
          <option key={device.deviceId} value={device.deviceId}>
            {device.label}
          </option>
        ))}
      </select>
      <button onClick={startRecording} disabled={!selectedDeviceId || recorder}>
        开始录制
      </button>
      <button onClick={stopRecording} disabled={!recorder}>
        停止录制
      </button>
    </div>
  );
};

export default SystemAudioRecorder;

关键注意事项

  • 系统设备启用要求:MacOS需先通过「音频MIDI设置」启用「内部音频」输入设备;Windows需确保「立体声混音」设备已启用(在声音设置的录制选项卡中右键显示禁用设备)。
  • 设备标签可见条件:首次调用enumerateDevices()时设备标签会隐藏,必须先请求一次基础音频授权(getUserMedia({audio: true})),才能获取带明确名称的设备列表。
  • 兼容性:该方案目前支持Chrome、Edge、Opera等Chromium内核浏览器,Firefox对系统音频设备的支持需视版本和系统配置而定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 04:32:14