3

Is there a simple way with DirectShow to detect if the webcam is plugged in (USB), or if someone has unplugged it (and then poll or search for it)?

I have seen code for Microsoft Media Foundation, but it is complex and Media Foundation isn't installable on < Vista, afaik.

Thx, WW

Delimitry
  • 2,987
  • 4
  • 30
  • 39

1 Answers1

1

i use a WMI event watcher looking for the PID in the property string (some cameras may fire the events twice depending on drivers). here is a VB.Net example:

 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
devHead
  • 794
  • 1
  • 15
  • 38
  • take note it may be a little sloppy, i had to remove some code i didn't want visible, this routine will do the trick though, I've never seen this capability available or implemented in DS.... – devHead Oct 01 '12 at 14:20