直接上测试代码和运行结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
static void Main( string [] args)
{
#region 测试代码
List< string > dataList;
dataList = DirectXHelper.GetAudioDevicesList();
OutPutInfo( "DirectX获取麦克风:" , dataList);
dataList = NAudioHelper.GetInDeviceList();
OutPutInfo( "NAudio获取麦克风" , dataList);
dataList = NAudioHelper.GetInDeviceListFull();
OutPutInfo( "NAudio获取麦克风完整名称" , dataList);
dataList = NAudioHelper.GetOutDeviceList();
OutPutInfo( "NAudio获取扬声器" , dataList);
dataList = NAudioHelper.GetOutDeviceListFull();
OutPutInfo( "NAudio获取扬声器完整名称" , dataList);
dataList = AForgeHelper.GetAudioInDevicesList();
OutPutInfo( "AForge获取麦克风" , dataList);
dataList = AForgeHelper.GetVideoInDevicesList();
OutPutInfo( "AForge获取摄像头" , dataList);
//dataList = DeviceHelper.GetAudioInList();
//OutPutInfo("VC++获取麦克风(中文会乱码):", dataList);
dataList = DeviceHelper.GetAudioInDeviceList();
OutPutInfo( "VC++获取麦克风:" , dataList);
dataList = DeviceHelper.GetVideoInDeviceList();
OutPutInfo( "VC++获取摄像头:" , dataList);
#endregion
Console.Read();
}
private static void OutPutInfo( string defaultMessage, IEnumerable< string > data)
{
Console.WriteLine(defaultMessage);
if (data == null )
{
return ;
}
foreach ( var item in data)
{
Console.WriteLine(item);
}
Console.WriteLine();
}
|
运行结果:
主要使用了四种方式来获取:
一、C#直接调用DirectX来获取麦克风名称
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public static List< string > GetAudioDevicesList()
{
var audioDevices = new CaptureDevicesCollection();
var deviceNames = new List< string >();
for ( int i = 0; i < audioDevices.Count; i++)
{
var guid = (audioDevices[i]).DriverGuid;
if (guid == Guid.Empty)
{
continue ;
}
deviceNames.Add(audioDevices[i].Description);
}
return deviceNames;
}
|
二、使用NAudio来获取
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
/// <summary>
/// 获取声音输入设备
/// </summary>
/// <returns></returns>
public static List< string > GetInDeviceList()
{
var devices = new List<WaveInCapabilities>();
int waveInDevices = WaveIn.DeviceCount;
for ( int i = 0; i < waveInDevices; i++)
{
devices.Add(WaveIn.GetCapabilities(i));
}
return devices.Select(item => item.ProductName).ToList();
}
/// <summary>
/// 获取声音输入设备完整名称
/// </summary>
/// <returns></returns>
public static List< string > GetInDeviceListFull()
{
List< string > devices = new List< string >();
var enumberator = new MMDeviceEnumerator();
var deviceCollection = enumberator.EnumerateAudioEndPoints(DataFlow.Capture, DeviceState.All);
for ( int waveInDevice = 0; waveInDevice < WaveIn.DeviceCount; waveInDevice++)
{
WaveInCapabilities deviceInfo = WaveIn.GetCapabilities(waveInDevice);
foreach (MMDevice device in deviceCollection)
{
try
{
if (device.FriendlyName.StartsWith(deviceInfo.ProductName))
{
devices.Add(device.FriendlyName);
break ;
}
}
catch (Exception ex)
{
continue ;
}
}
}
return devices;
}
|
三、使用AForge的API来获取。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
/// <summary>
/// 获取麦克风列表
/// </summary>
/// <returns></returns>
public static List< string > GetAudioInDevicesList()
{
List< string > devicesList = new List< string >();
try
{
var videoDevices = new FilterInfoCollection(FilterCategory.AudioInputDevice);
foreach (FilterInfo device in videoDevices)
{
devicesList.Add(device.Name);
}
}
catch (ApplicationException)
{
Console.WriteLine( "No local capture devices" );
}
return devicesList;
}
/// <summary>
/// 获取摄像头列表
/// </summary>
/// <returns></returns>
public static List< string > GetVideoInDevicesList()
{
List< string > devicesList = new List< string >();
try
{
var videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
foreach (FilterInfo device in videoDevices)
{
devicesList.Add(device.Name);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return devicesList;
}
|
四、用VC++一个开源项目EnumDevice
本文获取获取设备信息,主要是为了使用FFMpeg的API来进行推流.
先简单对比一下各个方式的差异 .
第一种方式 并不是拿来就能使用的, 要改配置文件,还要设置调试异常,
具体解决方法可以参考:https://www.cnblogs.com/wzwyc/articles/7262666.html
我编译的时候遇到前面2个问题,改后能正常获取。
第二种方式 NAudio (C#开源项目)在处理声音方便很出名。
结合推流项目它不怎么合适,原因有两,
1、只能获取音频输入设备即(麦克风)。获取不到摄像头
2、NAudio获取麦克风的名称 无法和FFMpeg获取名称完成对上,有些电脑FFmpeg要全名,而有些不是.
第三种方式 AForge
AForge在处理图像方面更出名了,现在变为Accord.Net,这里只测试AForge为例。
因为功能强大需要使用 AForge.Video.DirectShow.dll,AForge.Video.dll,AForge.dll,
不过 我仅仅是为了获取一个麦克风和摄像头名称,就要引用3个dll,100K左右,杀鸡焉用牛刀,因此不符合我的要求。
第四种方式: EnumDevice.dll
网上VC++的一个开源想项目,编译后8k,更重要的是和FFMpeg设备名称完全对上。
这个使用的过程中遇到不少问题,准备完整记录一下。