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
相关产品推荐
相关产品推荐

