c# 获取本地摄像头列表 录制视频 拍照

视频录制

安装nuget 【System.Runtime.InteropServices】


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

相关nuget

安装操作视频、图片的nuget ,注意版本号
OpenCvSharp4 4.7.0.20230115
OpenCvSharp4.Extensions 4.7.0.20230115
OpenCvSharp4.runtime.win 4.7.0.20230115

操作

临时变量

        private VideoCapture Capture;
        VideoWriter videoWriter;

打开摄像头

   //0为第一个摄像头设备
   Capture = new VideoCapture(0, VideoCaptureAPIs.DSHOW);
   Capture.FrameWidth = Convert.ToInt32(1024);
   Capture.FrameHeight = Convert.ToInt32(768);
   Capture.FourCC = @"MJPG";

捕获图片 - 转换为BitmapSource可以直接显示在界面上

   Mat frameTemp = new Mat();

   Capture.Read(frameTemp);
   //if (frameTemp.Empty())
   //    continue;
   var bitmapInfo = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(frameTemp);

   //录制视频保存到输出
   videoWriter?.Write(frameTemp);

   var hBitmap = bitmapInfo.GetHbitmap();
   var imgData = Imaging.CreateBitmapSourceFromHBitmap(
       hBitmap,
       IntPtr.Zero,
       Int32Rect.Empty,
       BitmapSizeOptions.FromEmptyOptions());

保存视频

 videoWriter = new VideoWriter(
    "D:\\test.mp4",
    VideoWriter.FourCC(@"X264"),
    30, new OpenCvSharp.Size(Capture.FrameWidth, Capture.FrameHeight));

停止录制

videoWriter.Dispose();

关闭摄像头

Capture.Dispose();

音频录制

安装nuget
NAudio 2.2.1


            WaveIn cap = new WaveIn();   // cap, capture
            WaveFileWriter writer = new WaveFileWriter("filename", new WaveFormat(16000, 16, 1));
            cap.DataAvailable += (s, args) => writer.Write(args.Buffer, 0, args.BytesRecorded);    // 订阅事件
            cap.StartRecording();   // 开始录制

            // 结束录制时:
            cap.StopRecording();    // 停止录制
            writer.Close();         // 关闭 FileWriter, 保存数据

[参考]
C#环境下通过OpenCvSharp实现USB摄像头视频显示及存储
C#环境下通过VLC实现USB摄像头视频显示及存储

posted @ 2024-11-26 13:27  Hey,Coder!  阅读(19)  评论(0编辑  收藏  举报