自己写接口获取到电脑上安装的摄像头

C# 使用com获取Windows摄像头列表前言
想使用ffmpeg打开摄像头,需要输入摄像头的名称,而ffmpeg本身的枚举摄像头列表功能不是接口
,所以需要用其他方式获取到设备列表。C++获取视频设备列表的方法有不少,但C#获取视频设备列表的方法网上提供的解决方案基本都是依赖第三方库的,为了获取视频设备列表而引入一整个视频库实在是不太必要。经过思考,Windows的directshow和mediafudation都是基于com的,而且C#对com的支持是很好的,基于上述两点我们完全可以在C#中直接调用com。我们使用directshow获取视频设备列表,由于com的跨语言特性,完全可以直接在C#中调用,而不用通过C++封装一层dll给C#使用。我们首先定义需要的com对象接口。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Security;
namespace AC
{
    public class EnumDevices
    {
        /// <summary>
        /// 枚举视频设备
        /// </summary>
        public static IEnumerable<string> Devices
        {
            get
            {
                IMoniker[] monikers = new IMoniker[5];
                var devEnum = Activator.CreateInstance(Type.GetTypeFromCLSID(SystemDeviceEnum)) as ICreateDevEnum;
                IEnumMoniker moniker;
                if (devEnum.CreateClassEnumerator(VideoInputDevice, out moniker, 0) == 0)
                {
                    while (true)
                    {
                        int hr = moniker.Next(1, monikers, IntPtr.Zero);
                        if (hr != 0 || monikers[0] == null)
                            break;
                        yield return GetName(monikers[0]);
                        foreach (var i in monikers)
                        {
                            if(i!=null)
                            Marshal.ReleaseComObject(i);
                        }                      
                    }
                    Marshal.ReleaseComObject(moniker);
                }
                Marshal.ReleaseComObject(devEnum);
            }
        }
        /// <summary>
        /// 获取设备名称
        /// </summary>
        /// <param name="moniker"></param>
        /// <returns></returns>
        static string GetName(IMoniker moniker)
        {
            IPropertyBag property;
            object value;
            object temp = null;
            try
            {
                Guid guid = typeof(IPropertyBag).GUID;
                moniker.BindToStorage(null, null, ref guid, out temp);
                property = temp as IPropertyBag;
                int hr = property.Read("FriendlyName", out value, null);
                Marshal.ThrowExceptionForHR(hr);
                return value as string;
            }
            catch (Exception)
            {
                return null;
            }
            finally
            {
                if (temp != null)
                {
                    Marshal.ReleaseComObject(temp);
                }
            }
        }
        static readonly Guid SystemDeviceEnum = new Guid(0x62BE5D10, 0x60EB, 0x11D0, 0xBD, 0x3B, 0x00, 0xA0, 0xC9, 0x11, 0xCE, 0x86);
        static readonly Guid VideoInputDevice = new Guid(0x860BB310, 0x5D01, 0x11D0, 0xBD, 0x3B, 0x00, 0xA0, 0xC9, 0x11, 0xCE, 0x86);
        [Flags]
        enum CDef
        {
            None = 0x0,
            ClassDefault = 0x1,
            BypassClassManager = 0x2,
            ClassLegacy = 0x4,
            MeritAboveDoNotUse = 0x8,
            DevmonCMGRDevice = 0x10,
            DevmonDMO = 0x20,
            DevmonPNPDevice = 0x40,
            DevmonFilter = 0x80,
            DevmonSelectiveMask = 0xF0
        }
        [ComImport]
        [SuppressUnmanagedCodeSecurity]
        [Guid("3127CA40-446E-11CE-8135-00AA004BB851")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        interface IErrorLog
        {
            [PreserveSig]
            int AddError([In][MarshalAs(UnmanagedType.LPWStr)] string pszPropName, [In] System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo);
        }
        [ComImport]
        [Localizable(false)]
        [SuppressUnmanagedCodeSecurity]
        [Guid("55272A00-42CB-11CE-8135-00AA004BB851")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        interface IPropertyBag
        {
            [PreserveSig]
            int Read([In][MarshalAs(UnmanagedType.LPWStr)] string pszPropName, [MarshalAs(UnmanagedType.Struct)] out object pVar, [In] IErrorLog pErrorLog);
 
            [PreserveSig]
            int Write([In][MarshalAs(UnmanagedType.LPWStr)] string pszPropName, [In][MarshalAs(UnmanagedType.Struct)] ref object pVar);
        }
 
        [ComImport]
        [SuppressUnmanagedCodeSecurity]
        [Guid("29840822-5B84-11D0-BD3B-00A0C911CE86")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        interface ICreateDevEnum
        {
            [PreserveSig]
            int CreateClassEnumerator([In][MarshalAs(UnmanagedType.LPStruct)] Guid pType, out IEnumMoniker ppEnumMoniker, [In] CDef dwFlags);
        }      
    }
}

获取方法:

string[] CamSNames = EnumCamDevices.Devices.ToArray();

参考网站 : http://www.icodebang.com/article/341130

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值