directshow - 如何检测网络摄像头插入/拔出?

标签 directshow directshow.net

DirectShow 是否有一种简单的方法来检测网络摄像头是否已插入 (USB),或者是否有人拔掉了它(然后轮询或搜索它)?

我看过 Microsoft Media Foundation 的代码,但它很复杂,而且 Media Foundation 不能安装在 < Vista 上,afaik。

谢谢,WW

最佳答案

我使用 WMI 事件观察器在属性字符串中查找 PID(某些相机可能会触发事件两次,具体取决于驱动程序)。这是一个 VB.Net 示例:

 Dim CamEventWatcher As ManagementEventWatcher
 Public Delegate Sub SetMessageCallback(ByVal [_Msg] As Boolean)

Private Sub MessageCallback(ByVal _Msg As Boolean)
    If (_Msg) Then
        'cam connected
    Else
        'camera removed
    End If
End Sub

Private Sub RemoveCameraUSBHandler()
    Try
        If Not CamEventWatcher Is Nothing Then
            CamEventWatcher.Stop()
        End If
    Catch ex As Exception

    End Try
End Sub

Private Sub AddCameraUSBHandler()
    Dim q As WqlEventQuery

    Dim scope As ManagementScope = New ManagementScope("root\CIMV2")

    scope.Options.EnablePrivileges = True

    Try

        q = New WqlEventQuery()

        q.EventClassName = "__InstanceOperationEvent"

        q.WithinInterval = New TimeSpan(0, 0, 1)

        q.Condition = "TargetInstance ISA 'Win32_USBControllerdevice'"

        CamEventWatcher = New ManagementEventWatcher(scope, q)

        AddHandler CamEventWatcher.EventArrived, AddressOf CamUSBEvent

        CamEventWatcher.Start()
    Catch ex As Exception
    End Try
End Sub

Private iCreatedFired As Integer = 0
Private iRemovedFired As Integer = 0
Public Sub CamUSBEvent(ByVal sender As System.Object, ByVal e As EventArrivedEventArgs)
    If e.NewEvent.ClassPath.ClassName = "__InstanceCreationEvent" Then

        Dim sAntecedent As String
        Dim sDependent As String

        sAntecedent = e.NewEvent.Properties("TargetInstance").Value.Properties("Antecedent").Value.ToString() + ControlChars.CrLf

        sDependent = e.NewEvent.Properties("TargetInstance").Value.Properties("Dependent").Value.ToString() + ControlChars.CrLf

        If sDependent.Contains(CAM_DEV_ID) Then
            iCreatedFired += 1
            If (iCreatedFired = 1) Then
                e.NewEvent.Dispose()
                Return
            End If
            iCreatedFired = 0
            iRemovedFired = 0
            Dim _delegate As New SetMessageCallback(AddressOf MessageCallback)
            Me.Invoke(_delegate, New Object() {True})

        End If
    ElseIf e.NewEvent.ClassPath.ClassName = "__InstanceDeletionEvent" Then

        Dim sAntecedent As String
        Dim sDependent As String

        sAntecedent = e.NewEvent.Properties("TargetInstance").Value.Properties("Antecedent").Value.ToString() + ControlChars.CrLf

        sDependent = e.NewEvent.Properties("TargetInstance").Value.Properties("Dependent").Value.ToString() + ControlChars.CrLf

        If sDependent.Contains(CAM_DEV_ID) Then
            iRemovedFired += 1
            If (iRemovedFired = 1) Then
                e.NewEvent.Dispose()
                Return
            End If
            iCreatedFired = 0
            iRemovedFired = 0
            Dim _delegate As New SetMessageCallback(AddressOf MessageCallback)
            Me.Invoke(_delegate, New Object() {False})
        End If
    End If

    e.NewEvent.Dispose()
End Sub

关于directshow - 如何检测网络摄像头插入/拔出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12601779/

相关文章:

c++ - DirectShow 手动图形内存泄漏

c# - C# 中的 DirectShow 推送源过滤器?

c# - 将相机名称映射到 opencv 相机索引

c# - 在线程中创建 DirectShow 图形

c# - DirectShow:如何更改过滤器属性?

c# - 如何获取可用视频捕获设备的列表

c# - 将 WDM 流式交叉开关设备添加到 FilterGraph

jpeg - 困难的 gstreamer 管道 - 使用 DirectShow 在 Windows 上将 h264 文件解码/解复用为 jpeg

c++ - 直接显示捕获过滤器 "wrapper"

c# - 图表在监视器更改后重新启动