我正在尝试使用avicap32.dll创建一个记录视频的应用程序,但不使用用户界面。我找到的示例代码(显示如何录制视频而不仅仅是捕获图像的唯一代码)使用需要图片框的句柄ID的hWnd。有什么方法可以绕过这个,只需连接到驱动程序,记录并保存视频?
我的代码如下:
Imports System
Imports System.Runtime.InteropServices
Public Class Recorder
Const WM_CAP_START = &H400S
Const WS_CHILD = &H40000000
Const WS_VISIBLE = &H10000000
Const WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10
Const WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11
Const WM_CAP_EDIT_COPY = WM_CAP_START + 30
Const WM_CAP_SEQUENCE = WM_CAP_START + 62
Const WM_CAP_FILE_SAVEAS = WM_CAP_START + 23
Const WM_CAP_SET_SCALE = WM_CAP_START + 53
Const WM_CAP_SET_PREVIEWRATE = WM_CAP_START + 52
Const WM_CAP_SET_PREVIEW = WM_CAP_START + 50
Const SWP_NOMOVE = &H2S
Const SWP_NOSIZE = 1
Const SWP_NOZORDER = &H4S
Const HWND_BOTTOM = 1
Declare Function capGetDriverDescriptionA Lib "avicap32.dll" (ByVal wDriverIndex As Short, ByVal lpszName As String, ByVal cbName As Integer, ByVal lpszVer As String, ByVal cbVer As Integer) As Boolean
Declare Function capCreateCaptureWindowA Lib "avicap32.dll" (ByVal lpszWindowName As String, ByVal dwStyle As Integer, ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, ByVal nHeight As Short, ByVal hWnd As Integer, ByVal nID As Integer) As Integer
Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Integer, ByVal Msg As Integer, ByVal wParam As Integer, <MarshalAs(UnmanagedType.AsAny)> ByVal lParam As Object) As Integer
Private Shared Function ReturnDriver() As Integer 'As String
Dim DriverName As String = Space(100)
Dim DriverVersion As String = Space(100)
'Dim ReturnDriverName As String = ""
Dim DriverIndex As Integer = Nothing
For i As Integer = 0 To 9
If capGetDriverDescriptionA(i, DriverName, 80, DriverVersion, 80) Then
'lstVideoSources.Items.Add(DriverName.Trim)
'ReturnDriverName = DriverName.Trim
DriverIndex = i
Exit For
End If
Next
Return DriverIndex
End Function
Public Shared Sub StartRecording()
Dim DriverVersion As Integer = ReturnDriver()
If SendMessage(0, WM_CAP_DRIVER_CONNECT, DriverVersion, 0) Then
SendMessage(0, WM_CAP_SEQUENCE, 0, 0)
End If
End Sub
Public Shared Sub StopRecording()
SendMessage(0, WM_CAP_FILE_SAVEAS, 0, "C:\records\" & Now().ToString() & ".avi")
End Sub
End Class
答案 0 :(得分:2)
你想要的东西很可能无法完成。 VFW甚至一些DS滤镜/播放器都需要hWnd来绘制视频输出。没有它,就没有视频输出,因此无需捕捉。您可以尝试通过绘制到隐藏或屏幕外控制来欺骗它,但是Windows只是跳过绘画,因为它在屏幕外。 VFW不是很灵活。
答案 1 :(得分:1)
我找到了答案。我一般习惯于web开发,而不是那么多Windows窗体开发,我意识到我可以创建一个类型图片框的变量,瞧,我有一个引用的句柄。
有关信息,在我重新考虑之后,我的代码如下。
Const WM_CAP_START = &H400S
Const WS_CHILD = &H40000000
Const WS_VISIBLE = &H10000000
Const WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10
Const WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11
Const WM_CAP_EDIT_COPY = WM_CAP_START + 30
Const WM_CAP_SEQUENCE = WM_CAP_START + 62
Const WM_CAP_FILE_SAVEAS = WM_CAP_START + 23
Const WM_CAP_SET_SCALE = WM_CAP_START + 53
Const WM_CAP_SET_PREVIEWRATE = WM_CAP_START + 52
Const WM_CAP_SET_PREVIEW = WM_CAP_START + 50
Const SWP_NOMOVE = &H2S
Const SWP_NOSIZE = 1
Const SWP_NOZORDER = &H4S
Const HWND_BOTTOM = 1
Declare Function capGetDriverDescriptionA Lib "avicap32.dll" (ByVal wDriverIndex As Short, ByVal lpszName As String, ByVal cbName As Integer, ByVal lpszVer As String, ByVal cbVer As Integer) As Boolean
Declare Function capCreateCaptureWindowA Lib "avicap32.dll" (ByVal lpszWindowName As String, ByVal dwStyle As Integer, ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, ByVal nHeight As Short, ByVal hWnd As Integer, ByVal nID As Integer) As Integer
Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Integer, ByVal Msg As Integer, ByVal wParam As Integer, <MarshalAs(UnmanagedType.AsAny)> ByVal lParam As Object) As Integer
Declare Function SetWindowPos Lib "user32" Alias "SetWindowPos" (ByVal hwnd As Integer, ByVal hWndInsertAfter As Integer, ByVal x As Integer, ByVal y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal wFlags As Integer) As Integer
Declare Function DestroyWindow Lib "user32" (ByVal hndw As Integer) As Boolean
Private hWnd As Integer
Private DriverVersion As Integer
Private mypicture As PictureBox = New PictureBox()
Public Sub New()
DriverVersion = ReturnDriver()
hWnd = capCreateCaptureWindowA(DriverVersion, WS_VISIBLE Or WS_CHILD, 0, 0, 0, 0, mypicture.Handle.ToInt32, 0)
End Sub
Private Function ReturnDriver() As Integer
Dim DriverName As String = Space(100)
Dim DriverVersion As String = Space(100)
Dim DriverIndex As Integer = Nothing
For i As Integer = 0 To 9
If capGetDriverDescriptionA(i, DriverName, 80, DriverVersion, 80) Then
DriverIndex = i
Exit For
End If
Next
Return DriverIndex
End Function
Public Sub StartRecording()
If SendMessage(hWnd, WM_CAP_DRIVER_CONNECT, DriverVersion, 0) Then
SendMessage(hWnd, WM_CAP_SEQUENCE, 0, 0)
End If
End Sub
Public Sub StopRecording(byval FileName As String)
Try
FileName = "C:/records/_" & FileName & ".avi"
SendMessage(hWnd, WM_CAP_FILE_SAVEAS, 0, FileName)
SendMessage(hWnd, WM_CAP_DRIVER_DISCONNECT, DriverVersion, 0)
System.IO.File.Delete("C:/CAPTURE.avi")
Catch ex As Exception
End Try
End Sub
不,我有代码在运行,我看到无法使用avicap32.dll压缩视频,并且它可以保存200 MB视频10秒钟。好像我必须理解DirectShow.net。