欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#?使用com獲取Windows攝像頭列表

 更新時(shí)間:2022年08月04日 15:42:17   作者:CodeOfCC  
本文主要介紹了C#?使用com獲取Windows攝像頭列表,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

想使用ffmpeg打開攝像頭,需要輸入攝像頭的名稱,而ffmpeg本身的枚舉攝像頭列表功能不是接口
,所以需要用其他方式獲取到設(shè)備列表。C++獲取視頻設(shè)備列表的方法有不少,但C#獲取視頻設(shè)備列表的方法網(wǎng)上提供的解決方案基本都是依賴第三方庫的,為了獲取視頻設(shè)備列表而引入一整個(gè)視頻庫實(shí)在是不太必要。經(jīng)過思考,Windows的directshow和mediafudation都是基于com的,而且C#對(duì)com的支持是很好的,基于上述兩點(diǎn)我們完全可以在C#中直接調(diào)用com。

一、定義com接口

我們使用directshow獲取視頻設(shè)備列表,由于com的跨語言特性,完全可以直接在C#中調(diào)用,而不用通過C++封裝一層dll給C#使用。我們首先定義需要的com對(duì)象接口。

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

二、枚舉設(shè)備

與directshow流程一樣,調(diào)用com枚舉設(shè)備即可,本文只展示獲取設(shè)備名稱(FriendlyName),獲取其他屬性可以參照c++調(diào)用directshow的實(shí)現(xiàn)。

        /// <summary>
        /// 枚舉視頻設(shè)備
        /// </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 r = moniker.Next(1, monikers, IntPtr.Zero);
                        if (r != 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>
        /// 獲取設(shè)備名稱
        /// </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);
                }
            }
        }

三、完整代碼

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>
        /// 枚舉視頻設(shè)備
        /// </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>
        /// 獲取設(shè)備名稱
        /// </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);
        }      
    }
}

四、使用示例

.net 6.0代碼示例如下

// See https://aka.ms/new-console-template for more information
using AC;
//枚舉設(shè)備
foreach (var i in EnumDevices.Devices)
{
    //打印設(shè)備名稱
    Console.WriteLine(i);
}

效果:

在這里插入圖片描述

總結(jié)

以上就是今天要講的內(nèi)容,本文介紹了C#直接調(diào)用com獲取視頻設(shè)備列表的方法,只要知道了com的一些基本原理以及c#和com的關(guān)系,很容易就能實(shí)現(xiàn)c#直接使用directshow的功能,第三方的庫也是做了類似的工作,定義了完整的directshow的接口,只是筆者使用的環(huán)境中只需要枚舉視頻設(shè)備列表,不需要其他功能,引入完整的directshow接口有點(diǎn)大材小用,所以還不如自己定義幾個(gè)必要的接口來的實(shí)在。

到此這篇關(guān)于C# 使用com獲取Windows攝像頭列表的文章就介紹到這了,更多相關(guān)C# 獲取Windows攝像頭列表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關(guān)文章

  • C#不登錄電腦啟動(dòng)程序

    C#不登錄電腦啟動(dòng)程序

    本文主要介紹了創(chuàng)建系統(tǒng)服務(wù);開啟服務(wù),啟動(dòng)程序。具有一定的參考價(jià)值,下面跟著小編一起來看下吧
    2017-01-01
  • asp.net之生成驗(yàn)證碼的方法集錦(一)

    asp.net之生成驗(yàn)證碼的方法集錦(一)

    現(xiàn)在很多網(wǎng)站都有注冊(cè)登錄的頁面,為了更好的滿足用戶體驗(yàn)和網(wǎng)站的安全性,很多網(wǎng)站都采用動(dòng)態(tài)生成的圖形碼或者是附加碼進(jìn)行驗(yàn)證,這篇文章主要就是介紹生成驗(yàn)證碼的方法,需要的朋友可以參考下
    2015-08-08
  • C#中Hashtable和Dictionary的區(qū)別與用法示例

    C#中Hashtable和Dictionary的區(qū)別與用法示例

    由于 Hashtable 和 Dictionary 同時(shí)存在, 在使用場景上必然存在選擇性, 并不任何時(shí)刻都能相互替代。所以這篇文章主要給大家介紹了關(guān)于C#中Hashtable和Dictionary區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2021-05-05
  • C#語法相比其它語言比較獨(dú)特的地方(一)

    C#語法相比其它語言比較獨(dú)特的地方(一)

    這篇文章主要介紹了C#語法相比其它語言比較獨(dú)特的地方(一),本文講解了switch語句可以用來測試string型的對(duì)象、多維數(shù)組、foreach語句、索引器和Property等內(nèi)容,需要的朋友可以參考下
    2015-04-04
  • C#?Random類隨機(jī)函數(shù)實(shí)例詳解

    C#?Random類隨機(jī)函數(shù)實(shí)例詳解

    這篇文章主要為大家介紹了C#?Random類隨機(jī)函數(shù)實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • C#實(shí)現(xiàn)在兩個(gè)數(shù)字之間生成隨機(jī)數(shù)的方法

    C#實(shí)現(xiàn)在兩個(gè)數(shù)字之間生成隨機(jī)數(shù)的方法

    這篇文章主要介紹了C#實(shí)現(xiàn)在兩個(gè)數(shù)字之間生成隨機(jī)數(shù)的方法,在一些特殊場景會(huì)用到哦,需要的朋友可以參考下
    2014-08-08
  • Unity使用LineRender實(shí)現(xiàn)簽名效果

    Unity使用LineRender實(shí)現(xiàn)簽名效果

    這篇文章主要為大家詳細(xì)介紹了Unity使用LineRender實(shí)現(xiàn)簽名效果,制作簽名功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • C#實(shí)現(xiàn)提高xml讀寫速度的方法

    C#實(shí)現(xiàn)提高xml讀寫速度的方法

    這篇文章主要介紹了C#實(shí)現(xiàn)提高xml讀寫速度的方法,并且針對(duì)各類文件的讀寫做了較為細(xì)致的分析,非常實(shí)用,需要的朋友可以參考下
    2014-11-11
  • C#之Windows自帶打印功能的實(shí)現(xiàn)

    C#之Windows自帶打印功能的實(shí)現(xiàn)

    這篇文章主要介紹了C#之Windows自帶打印功能的實(shí)現(xiàn)方式,具有很好的價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • WinForm防止程序重復(fù)運(yùn)行的方法分析

    WinForm防止程序重復(fù)運(yùn)行的方法分析

    這篇文章主要介紹了WinForm防止程序重復(fù)運(yùn)行的方法,通過記錄窗口句柄實(shí)現(xiàn)防止WinForm程序重復(fù)運(yùn)行的功能,需要的朋友可以參考下
    2017-05-05

最新評(píng)論