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

如何用C#版Selenium设置输出音频设备并捕获多浏览器实时音频流

捕获多浏览器实时音频流的两种可行方案

方案一:为每个浏览器指定专属虚拟音频设备

核心思路是让每个浏览器实例输出到独立的虚拟音频设备,再用NAudio捕获对应设备的音频流,实现隔离式实时处理。

1. 准备多虚拟音频设备

使用支持多实例的虚拟音频工具(如VB-Cable、Voicemeeter Banana)创建30对输入/输出虚拟设备(每个输出设备对应一个输入设备,用于转捕输出音频)。

2. 获取虚拟设备ID

用NAudio枚举系统音频设备,获取每个虚拟输出设备的GUID(Chrome/Edge需要此参数)或设备编号:

// 获取设备GUID(适配Chrome/Edge)
using NAudio.CoreAudioApi;
var enumerator = new MMDeviceEnumerator();
var devices = enumerator.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active);
foreach (var device in devices)
{
    Console.WriteLine($"设备名称: {device.FriendlyName}, GUID: {device.ID}");
}

// 获取设备编号(适配NAudio捕获)
using NAudio.Wave;
for (int i = 0; i < WaveIn.DeviceCount; i++)
{
    var capabilities = WaveIn.GetCapabilities(i);
    Console.WriteLine($"设备编号: {i}, 名称: {capabilities.ProductName}");
}

3. Selenium启动浏览器时指定音频设备

  • Chrome/Edge:添加--audio-output-device启动参数,传入目标设备的GUID:
var options = new ChromeOptions();
// 替换为对应虚拟设备的GUID字符串
options.AddArgument(@"--audio-output-device=""{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}""");
var driver = new ChromeDriver(options);

每个浏览器实例使用不同的设备GUID,确保输出完全隔离。

  • Firefox:通过设置浏览器偏好指定输出设备:
var options = new FirefoxOptions();
// 替换为目标设备的ID(可通过about:config查看可选值)
options.SetPreference("media.audio.output_device", "设备ID");
var driver = new FirefoxDriver(options);

4. NAudio捕获虚拟设备的音频流

针对每个虚拟输出设备对应的输入设备,启动捕获并处理实时数据:

var captureDevice = new WaveInEvent();
captureDevice.DeviceNumber = 虚拟输入设备编号;
captureDevice.WaveFormat = new WaveFormat(44100, 16, 2);
captureDevice.DataAvailable += (sender, e) =>
{
    // 在此处处理e.Buffer中的实时音频数据
};
captureDevice.StartRecording();

方案二:直接捕获指定浏览器进程的音频流

无需额外虚拟设备,通过Windows Core Audio API直接捕获目标浏览器进程的音频会话流,NAudio对此提供了封装支持。

1. 获取浏览器进程ID

Selenium可直接获取浏览器主进程ID,若需捕获Chrome标签页的独立音频进程,可进一步遍历主进程的子进程:

var driver = new ChromeDriver();
// 获取主进程ID
int mainProcessId = driver.Service.ProcessId;
// 遍历主进程的子进程(可选,针对Chrome标签页音频)
var childProcesses = Process.GetProcessById(mainProcessId).GetProcesses();

2. 用NAudio捕获进程音频会话

枚举系统音频会话,匹配目标进程ID并启动捕获:

using NAudio.CoreAudioApi;
using System.Threading;

var enumerator = new MMDeviceEnumerator();
var outputDevice = enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
var sessionManager = outputDevice.AudioSessionManager2;

// 遍历所有活动音频会话
foreach (var session in sessionManager.Sessions)
{
    var sessionControl = session as AudioSessionControl2;
    if (sessionControl != null && sessionControl.ProcessID == targetProcessId)
    {
        var captureClient = sessionControl.QueryInterface<AudioCaptureClient>();
        // 启动异步捕获线程
        Task.Run(() =>
        {
            while (true)
            {
                AudioCaptureClientFlags flags;
                int packetLength = captureClient.GetNextPacketSize();
                if (packetLength == 0)
                {
                    Thread.Sleep(10);
                    continue;
                }
                IntPtr dataPointer;
                int numFramesAvailable;
                captureClient.GetBuffer(out dataPointer, out numFramesAvailable, out flags, out _, out _);
                // 复制dataPointer中的音频数据到本地缓冲区进行实时处理
                captureClient.ReleaseBuffer(numFramesAvailable);
            }
        });
        break;
    }
}

注意:需处理音频会话的动态创建(如浏览器加载新页面时可能生成新会话),且程序需以管理员身份运行以获取进程权限。


注意事项

  • 30个并发浏览器实例会占用较多系统资源,建议添加浏览器启动参数(如--headless、--disable-extensions)降低负载。
  • 虚拟设备方案稳定性更高,适合大规模实例管理;进程捕获方案无需额外硬件,但需处理会话动态变化的情况。
  • 实时处理音频时,建议使用异步线程单独处理数据,避免阻塞Selenium的浏览器控制逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 11:40:23