Re: 2 web cameras and .net
avicap32.dll is almost certainly (actually, scrap 'almost') NOT the method used by any of the applications that work with the tablet. It is, like, so last century. You'll need something considerably more sophisticated such as DirectShow
Re: 2 web cameras and .net
Thanx dunfiddlin
I have gone down the directshow road and have hit a wall, the only thing left is to be able to select which camera to use, the code I have below will always bring up the first video device. I have tried playing around with things in the findcapturedevice sub but to no avail. Any ideas how I could select which camera to use?
cheers for the help
Code:
Imports DirectShowLib
Imports System
Imports System.Diagnostics
Imports System.Drawing
Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Imports System.Runtime.InteropServices.ComTypes
Public Class Form1
Dim D As Integer = Convert.ToInt32("0X8000", 16)
Public WM_GRAPHNOTIFY As Integer = D + 1
Dim VideoWindow As IVideoWindow = Nothing
Dim MediaControl As IMediaControl = Nothing
Dim MediaEventEx As IMediaEventEx = Nothing
Dim GraphBuilder As IGraphBuilder = Nothing
Dim CaptureGraphBuilder As ICaptureGraphBuilder2 = Nothing
Enum PlayState
Stopped
Paused
Running
Init
End Enum
Dim CurrentState As PlayState = PlayState.Stopped
Dim rot As DsROTEntry = Nothing
Private Sub CaptureVideo()
Dim hr As Integer = 0
Dim sourceFilter As IBaseFilter = Nothing
Try
GetInterfaces()
hr = CaptureGraphBuilder.SetFiltergraph(GraphBuilder) 'Specifies filter graph "graphbuilder" for the capture graph builder "captureGraphBuilder" to use.
sourceFilter = FindCaptureDevice()
hr = GraphBuilder.AddFilter(sourceFilter, "Video Capture")
hr = CaptureGraphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, sourceFilter, Nothing, Nothing)
Marshal.ReleaseComObject(sourceFilter)
SetupVideoWindow()
rot = New DsROTEntry(GraphBuilder)
hr = MediaControl.Run()
CurrentState = PlayState.Running
Catch ex As Exception
MessageBox.Show("An unrecoverable error has occurred.With error : " & ex.ToString)
End Try
End Sub
Private Sub GetInterfaces()
Dim hr As Integer = 0
GraphBuilder = CType(New FilterGraph, IGraphBuilder)
CaptureGraphBuilder = CType(New CaptureGraphBuilder2, ICaptureGraphBuilder2)
MediaControl = CType(GraphBuilder, IMediaControl)
VideoWindow = CType(GraphBuilder, IVideoWindow)
MediaEventEx = CType(GraphBuilder, IMediaEventEx)
hr = MediaEventEx.SetNotifyWindow(Me.Handle, WM_GRAPHNOTIFY, IntPtr.Zero) 'This method designates a window as the recipient of messages generated by or sent to the current DirectShow object
End Sub
Public Function FindCaptureDevice() As IBaseFilter
Dim hr As Integer = 0
Dim classEnum As IEnumMoniker = Nothing
Dim moniker As IMoniker() = New IMoniker(0) {}
Dim source As Object = Nothing
Dim devEnum As ICreateDevEnum = CType(New CreateDevEnum, ICreateDevEnum)
hr = devEnum.CreateClassEnumerator(FilterCategory.VideoInputDevice, classEnum, 0)
Marshal.ReleaseComObject(devEnum)
If classEnum Is Nothing Then
Throw New ApplicationException("No video capture device was detected.\r\n\r\n" & _
"This sample requires a video capture device, such as a USB WebCam,\r\n" & _
"to be installed and working properly. The sample will now close.")
End If
If classEnum.Next(moniker.Length, moniker, IntPtr.Zero) = 0 Then
Dim iid As Guid = GetType(IBaseFilter).GUID
moniker(0).BindToObject(Nothing, Nothing, iid, source)
Else
Throw New ApplicationException("Unable to access video capture device!")
End If
Marshal.ReleaseComObject(moniker(0))
Marshal.ReleaseComObject(classEnum)
Return CType(source, IBaseFilter)
End Function
Public Sub SetupVideoWindow()
Dim hr As Integer = 0
'set the video window to be a child of the main window
'putowner : Sets the owning parent window for the video playback window.
hr = VideoWindow.put_Owner(PictureBox1.Handle)
hr = VideoWindow.put_WindowStyle(WindowStyle.Child Or WindowStyle.ClipChildren)
'Use helper function to position video window in client rect of main application window
ResizeVideoWindow()
'Make the video window visible, now that it is properly positioned
'put_visible : This method changes the visibility of the video window.
hr = VideoWindow.put_Visible(OABool.True)
End Sub
Public Sub ResizeVideoWindow()
'Resize the video preview window to match owner window size
'left , top , width , height
If Not (VideoWindow Is Nothing) Then 'if the videopreview is not nothing
VideoWindow.SetWindowPosition(0, 0, Me.Width, Me.ClientSize.Height)
End If
End Sub
Public Sub closeinterfaces()
'//stop previewing data
If Not (Me.MediaControl Is Nothing) Then
Me.MediaControl.StopWhenReady()
End If
Me.CurrentState = PlayState.Stopped
'//stop recieving events
If Not (Me.MediaEventEx Is Nothing) Then
Me.MediaEventEx.SetNotifyWindow(IntPtr.Zero, WM_GRAPHNOTIFY, IntPtr.Zero)
End If
'// Relinquish ownership (IMPORTANT!) of the video window.
'// Failing to call put_Owner can lead to assert failures within
'// the video renderer, as it still assumes that it has a valid
'// parent window.
If Not (Me.VideoWindow Is Nothing) Then
Me.VideoWindow.put_Visible(OABool.False)
Me.VideoWindow.put_Owner(IntPtr.Zero)
End If
' // Remove filter graph from the running object table
If Not (rot Is Nothing) Then
rot.Dispose()
rot = Nothing
End If
'// Release DirectShow interfaces
Marshal.ReleaseComObject(Me.MediaControl) : Me.MediaControl = Nothing
Marshal.ReleaseComObject(Me.MediaEventEx) : Me.MediaEventEx = Nothing
Marshal.ReleaseComObject(Me.VideoWindow) : Me.VideoWindow = Nothing
Marshal.ReleaseComObject(Me.GraphBuilder) : Me.GraphBuilder = Nothing
Marshal.ReleaseComObject(Me.CaptureGraphBuilder) : Me.CaptureGraphBuilder = Nothing
End Sub
Re: 2 web cameras and .net
Just in case you want to try a different approach, I can recommend the Aforge.Net library - http://www.aforgenet.com/aforge/framework/
I too gave up on avicap32.dll because I wanted better support for multiple webcams.
Re: 2 web cameras and .net
thanx paulg4ije, worked like a charm and effortlessly. THANKYOU EVERYONE :)
Re: 2 web cameras and .net
Hello,
Could one of you send me a sample VB.Net code showing how to use the AForge.Net lib to select an imaging device as a source for capture ?
Bensonsearch, how did you do exactly ?
Thanks.
Re: 2 web cameras and .net
This is some of my code:
Code:
Imports AForge.Video
Imports AForge.Video.DirectShow
Module modCameras
Public videoDevices As FilterInfoCollection
'Private cam As VideoCaptureDevice
Sub Get_Camera_List(cmb As ComboBox)
' Get list of available video capture devices (webcams) using AForge library
Try
videoDevices = New FilterInfoCollection(FilterCategory.VideoInputDevice)
Dim iCamCount As Integer = videoDevices.Count
If iCamCount > 0 Then
For i As Integer = 0 To iCamCount - 1
cmb.items.add(videoDevices(i).Name)
Next
End If
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Information)
End Try
End Sub
End Module
Code:
Private Sub cmbCams_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles cmbCams.SelectedIndexChanged
GsCamName = cmbCams.SelectedItem.ToString
GiCamID = cmbCams.SelectedIndex
End Sub
Private Sub Camera_On()
Try
Dim videoSource As VideoCaptureDevice = New VideoCaptureDevice(videoDevices(GiCamID).MonikerString)
vsp1.VideoSource = videoSource
videoSource.DesiredFrameRate = 10
videoSource.DesiredFrameSize = New Size(640, 480)
vsp1.Start()
cmdGrab.Enabled = True
vsp1.Visible = True
bCameraOn = True
Catch ex As Exception
MsgBox("Failed to connect to chosen webcam.", MsgBoxStyle.Information)
Call Camera_Off()
End Try
End Sub
Private Sub Camera_Off()
Try
chkPreview.Checked = False
cmdGrab.Enabled = False
vsp1.SignalToStop()
vsp1.WaitForStop()
vsp1.Visible = False
bCameraOn = False
Catch
End Try
End Sub
Private Sub cmdGrab_Click(sender As System.Object, e As System.EventArgs) Handles cmdGrab.Click
Call Grab_Image()
End Sub
Private Sub Grab_Image()
If fnGrab_Image() Then
vsp1.Visible = False
vsp1.SignalToStop()
chkPreview.Checked = False
End If
End Sub
You need an Aforge Video Source Player on your form (vsp1 in my code).
Hopefully you can adapt this code to suit your requirements.
Re: 2 web cameras and .net
Forgot this bit:
Code:
Private Function fnGrab_Image() As Boolean
' Grab an image from webcam - Aforge Video Source Player must be running
Try
Dim bm As Bitmap = New Bitmap(640, 480)
bm = vsp1.GetCurrentVideoFrame
If bm.Width <> 640 Or bm.Height <> 480 Then
bm = New Bitmap(bm, New Size(640, 480))
End If
Dim bm2 As Bitmap = New Bitmap(640, 512)
Dim g As Graphics = Graphics.FromImage(bm2)
g.DrawImage(bm, 0, 32)
g.Dispose()
pbTX.Image = fnAdd_Header(bm2, "Greyscale") ' Add 16 line greyscale header
Gbm = CType(bm2.Clone, Bitmap)
If chkStamp.Checked Then pbTX.Image = fnAdd_Date_Time_Stamp(CType(pbTX.Image, Bitmap))
If chkLive.Checked Then pbTX.Image = fnAdd_Live_Webcam_Stamp(CType(pbTX.Image, Bitmap))
If chkCallsign.Checked Then pbTX.Image = fnAdd_Callsign(CType(pbTX.Image, Bitmap))
Return True
Catch
MsgBox("Aforge Video Source Player (webcam) not ready.")
Return False
End Try
End Function
Ignore the "stamps" and "header" - you should be able to adapt this code to do what you want.
Paul.
Re: 2 web cameras and .net
Thank you, Paul.
It's so simple compared to what it could have been with avicap.
popeau