2013-10-10 24 views
1

我想創建一個應用程序,使用avicap32.dll記錄視頻,但不使用用戶界面。我找到的示例代碼(唯一顯示如何記錄視頻而不僅僅是捕獲圖像的代碼)使用需要圖片框的句柄ID的hWnd。有什麼方法可以規避這種情況,只需連接到驅動程序,錄製和保存視頻?VB.Net捕獲視頻使用avicap32.dll沒有UI

我下面的代碼:你想要什麼很可能

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 

回答

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被壓縮,它是節省10秒捕獲200級MB的視頻。看來我必須理解DirectShow.net。

2

無法做到的。 VFW甚至一些DS濾波器/播放器都需要一個hWnd來繪製視頻輸出。沒有它,沒有視頻輸出,因此沒有什麼可以捕捉。您可以嘗試通過繪製到隱藏或屏幕外控制來欺騙它,但是隨後Windows會跳過繪畫,因爲它不在屏幕上。 VFW不是非常靈活。