直接上測試代碼和運行結果
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來獲取麥克風名稱
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來獲取
/// <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來獲取。
/// <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設備名稱完全對上。
這個使用的過程中遇到不少問題,准備完整記錄一下。
