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

WPF音频输入源与输出设备选择功能开发技术求助

WPF多音频源选择与输出路由实现方案

我帮你梳理下WPF里实现多音频源选择和输出路由的可行方案——你遇到的MediaElement局限性确实很常见,它本来就不是为设备级音频路由设计的,下面用NAudio和Unosquare.FFME的具体用法来解决你的问题:

一、用NAudio实现完整的音频设备控制(推荐)

NAudio是.NET生态里最成熟的音频处理库之一,完全支持音频输入设备枚举、实时捕获,以及输出设备的自由选择和播放,步骤非常清晰:

1. 枚举所有可用音频输入设备

不管是麦克风、线路输入还是其他外接音频源,都可以通过WaveIn类枚举出来:

// 遍历所有输入设备,获取设备ID和名称
for (int deviceId = 0; deviceId < WaveIn.DeviceCount; deviceId++)
{
    var deviceCapabilities = WaveIn.GetCapabilities(deviceId);
    // 可以把这些信息绑定到WPF的ComboBox供用户选择
    Console.WriteLine($"输入设备 {deviceId}: {deviceCapabilities.ProductName}");
}

2. 捕获选定输入设备的音频

选好设备后,初始化WaveIn实例并监听音频数据回调:

// 假设用户选中了deviceId为1的设备
var waveIn = new WaveIn { DeviceNumber = 1 };
waveIn.WaveFormat = new WaveFormat(44100, 16, 2); // 设置标准音频格式

// 当有音频数据到来时触发这个回调
waveIn.DataAvailable += (sender, args) =>
{
    // args.Buffer里就是实时音频数据,接下来可以直接路由到输出设备
};

waveIn.StartRecording();

3. 枚举并选择音频输出设备

用WasapiOut可以支持现代音频设备(比如USB耳机、外接音箱),枚举方式如下:

var deviceEnumerator = new MMDeviceEnumerator();
// 获取所有活跃的输出设备
var outputDevices = deviceEnumerator.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active);

foreach (var device in outputDevices)
{
    Console.WriteLine($"输出设备: {device.FriendlyName}");
}

4. 实时路由音频到选定输出设备

把捕获到的音频数据直接喂给输出设备,实现实时传输:

// 初始化输出设备(这里用用户选中的设备)
var selectedOutputDevice = outputDevices.First(d => d.FriendlyName.Contains("扬声器"));
var wasapiOut = new WasapiOut(selectedOutputDevice, AudioClientShareMode.Shared, false, 100);

// 用缓冲提供者来衔接输入和输出
var waveBuffer = new BufferedWaveProvider(waveIn.WaveFormat);
wasapiOut.Init(waveBuffer);
wasapiOut.Play();

// 在数据回调里把新数据加入缓冲
waveIn.DataAvailable += (sender, args) =>
{
    waveBuffer.AddSamples(args.Buffer, 0, args.BytesRecorded);
};

二、Unosquare.FFME的设备级媒体源处理

如果你想用FFmpeg的强大媒体能力,Unosquare.FFME也是可行的,关键是要利用FFmpeg的设备输入支持:

1. 枚举FFmpeg支持的音频输入设备

FFmpeg通过dshow(Windows)或alsa(Linux)等设备协议来访问硬件,枚举方式如下:

// 枚举Windows下的dshow音频输入设备
var dshowFormat = FFmpeg.AutoGen.ffmpeg.av_find_input_format("dshow");
var deviceList = FFmpeg.AutoGen.ffmpeg.avdevice_list_input_sources(dshowFormat, null, null);
// 遍历deviceList获取设备名称,比如"麦克风 (Realtek Audio)"

2. 设置MediaElement的音频源为硬件设备

直接用设备协议URL作为MediaElement的源,再指定输出设备:

// 把选中的设备名称拼接到dshow URL里
mediaElement.Source = new Uri(@"dshow://audio=""麦克风 (Realtek Audio)""");

// 枚举并选择输出设备
var availableOutputDevices = mediaElement.AudioDevices;
mediaElement.AudioDevice = availableOutputDevices.First(d => d.FriendlyName == "蓝牙音箱");

注意:要确保你的FFmpeg构建包含了dshow设备支持,否则会无法识别硬件设备。

三、WPF UI集成小技巧

可以用两个ComboBox分别绑定输入/输出设备列表,让用户直观选择:

<!-- 输入设备选择下拉框 -->
<ComboBox x:Name="InputDeviceCombo" SelectionChanged="InputDeviceCombo_SelectionChanged">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding ProductName}"/>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

<!-- 输出设备选择下拉框 -->
<ComboBox x:Name="OutputDeviceCombo" SelectionChanged="OutputDeviceCombo_SelectionChanged">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding FriendlyName}"/>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

然后在后台代码的SelectionChanged事件里,触发对应的音频捕获/输出初始化逻辑就可以了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:21:37