.NET 在工控中的隐藏技能,快速获取Audio和Video设备名称

108 阅读3分钟

前言

在多媒体开发中,获取设备(如音频和视频输入设备)的名称是一个常见的需求。无论是进行音视频采集、推流还是其他多媒体处理任务,准确识别设备名称都是至关重要的。

本文将介绍几种在C#中获取音频和视频设备名称的方法,并对比它们的优缺点。同时,我们将提供具体的测试代码及其运行结果,帮助读者更好地理解和应用这些方法。

一、测试代码

首先,我们来看一段用于获取音频和视频设备名称的测试代码:

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();
}

二、主要获取方式

1、使用DirectX获取麦克风名称

以下是使用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;
}

2、使用NAudio获取设备名称

以下是使用NAudio库获取音频输入设备名称的代码示例:

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();
}

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;
}

3、使用AForge获取设备名称

以下是使用AForge库获取音频和视频输入设备名称的代码示例:

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;
}

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;
}

4、使用EnumDevice.dll获取设备名称

EnumDevice.dll 是一个开源的VC++项目,编译后大小仅为8K,且其设备名称完全与FFmpeg设备名称匹配。

三、对比分析

1、DirectX:需要配置文件和调试异常设置,较为复杂。

2、NAudio:功能强大,但在处理FFmpeg设备名称时存在兼容性问题,无法获取摄像头设备。

3、AForge:主要用于图像处理,功能丰富但依赖多个DLL,对于仅需获取设备名称的任务显得过于庞大。

4、EnumDevice.dll:体积小,设备名称与FFmpeg完全匹配,非常适合用于推流项目。

总结

通过上述几种方法的对比,我们可以看出每种方法都有其适用场景和局限性。对于简单的设备名称获取任务,EnumDevice.dll 显然是最佳选择,它不仅体积小巧,而且设备名称与FFmpeg完全匹配,极大地简化了后续的推流操作。而NAudio和AForge则更适合那些对音频和视频处理有更高要求的应用场景。

关键词

C#、DirectX、NAudio、AForge、EnumDevice、设备名称、音频、视频、推流、FFmpeg

最后

如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。

也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!

优秀是一种习惯,欢迎大家留言学习!

作者:hueEnergy

出处:cnblogs.com/hubEnergy/p/12681096.html

声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!