2011-02-10 21 views
14

Potrzebuję przechwycić wideo z kamery internetowej. Czy są jakieś klasy w C#/.NET, które mogą mi w tym pomóc. Interesują mnie tylko dane w czasie rzeczywistym.Jak przechwycić wideo z kamery internetowej?

Czy są jakieś dobre książki C#/.NET, które mogę studiować, aby zdobyć głęboką wiedzę na temat języka i platformy?

+0

Witamy w StackOverflow. Zalecam, abyś zarejestrował się na konto, aby móc stale monitorować swoje pytania. To jest doskonałe pytanie, ale zadajesz tutaj dwa pytania. Czy możesz zadać drugiemu pytanie nowe pytanie? Myślę, że możesz znaleźć odpowiedź, której szukasz: [The Definitive C++ Book Guide and List] (http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list), ale Nie wahałbym się zapytać, czy to nie pomoże. Powinien być w stanie. – jcolebrand

+1

Polecam podzielenie pytań na dwie części: część z kamerą i część z książkami. –

+1

@drachenstern: Wątpię, że znajdzie odpowiedź na swoje pytanie C# w książce o C++. Przypuszczam, że to możliwe. –

Odpowiedz

12

To jest to, czego używam. Potrzebny jest pierwsza klasa iteracyjne urządzeń:

public class DeviceManager 
{ 
    [DllImport("avicap32.dll")] 
    protected static extern bool capGetDriverDescriptionA(short wDriverIndex, 
     [MarshalAs(UnmanagedType.VBByRefStr)]ref String lpszName, 
     int cbName, [MarshalAs(UnmanagedType.VBByRefStr)] ref String lpszVer, int cbVer); 

    static ArrayList devices = new ArrayList(); 

    public static TCamDevice[] GetAllDevices() 
    { 
     String dName = "".PadRight(100); 
     String dVersion = "".PadRight(100); 

     for (short i = 0; i < 10; i++) 
     { 
      if (capGetDriverDescriptionA(i, ref dName, 100, ref dVersion, 100)) 
      { 
       TCamDevice d = new TCamDevice(i); 
       d.Name = dName.Trim(); 
       d.Version = dVersion.Trim(); 

       devices.Add(d); 
      } 
     } 

     return (TCamDevice[])devices.ToArray(typeof(TCamDevice)); 
    } 

    public static TCamDevice GetDevice(int deviceIndex) 
    { 
     return (TCamDevice)devices[deviceIndex]; 
    } 
} 

a ten do sterowania kamerą.

public class TCamDevice 
{ 
    private const short WM_CAP = 0x400; 
    private const int WM_CAP_DRIVER_CONNECT = 0x40a; 
    private const int WM_CAP_DRIVER_DISCONNECT = 0x40b; 
    private const int WM_CAP_EDIT_COPY = 0x41e; 
    private const int WM_CAP_SET_PREVIEW = 0x432; 
    private const int WM_CAP_SET_OVERLAY = 0x433; 
    private const int WM_CAP_SET_PREVIEWRATE = 0x434; 
    private const int WM_CAP_SET_SCALE = 0x435; 
    private const int WS_CHILD = 0x40000000; 
    private const int WS_VISIBLE = 0x10000000; 

    [DllImport("avicap32.dll")] 
    protected static extern int capCreateCaptureWindowA([MarshalAs(UnmanagedType.VBByRefStr)] ref string lpszWindowName, 
     int dwStyle, int x, int y, int nWidth, int nHeight, int hWndParent, int nID); 

    [DllImport("user32", EntryPoint = "SendMessageA")] 
    protected static extern int SendMessage(int hwnd, int wMsg, int wParam, [MarshalAs(UnmanagedType.AsAny)] object lParam); 

    [DllImport("user32")] 
    protected static extern int SetWindowPos(int hwnd, int hWndInsertAfter, int x, int y, int cx, int cy, int wFlags); 

    [DllImport("user32")] 
    protected static extern bool DestroyWindow(int hwnd); 

    int index; 
    int deviceHandle; 

    public TCamDevice(int index) 
    { 
     this.index = index; 
    } 

    private string _name; 

    public string Name 
    { 
     get { return _name; } 
     set { _name = value; } 
    } 

    private string _version; 

    public string Version 
    { 
     get { return _version; } 
     set { _version = value; } 
    } 

    public override string ToString() 
    { 
     return this.Name; 
    } 
    /// <summary> 
    /// To Initialize the device 
    /// </summary> 
    /// <param name="windowHeight">Height of the Window</param> 
    /// <param name="windowWidth">Width of the Window</param> 
    /// <param name="handle">The Control Handle to attach the device</param> 
    public void Init(int windowHeight, int windowWidth, int handle) 
    { 
     string deviceIndex = Convert.ToString(this.index); 
     deviceHandle = capCreateCaptureWindowA(ref deviceIndex, WS_VISIBLE | WS_CHILD, 0, 0, windowWidth, windowHeight, handle, 0); 

     if (SendMessage(deviceHandle, WM_CAP_DRIVER_CONNECT, this.index, 0) > 0) 
     { 
      SendMessage(deviceHandle, WM_CAP_SET_SCALE, -1, 0); 
      SendMessage(deviceHandle, WM_CAP_SET_PREVIEWRATE, 0x42, 0); 
      SendMessage(deviceHandle, WM_CAP_SET_PREVIEW, -1, 0); 

      SetWindowPos(deviceHandle, 1, 0, 0, windowWidth, windowHeight, 6); 
     } 
    } 

    /// <summary> 
    /// Shows the webcam preview in the control 
    /// </summary> 
    /// <param name="windowsControl">Control to attach the webcam preview</param> 
    public void ShowWindow(global::System.Windows.Forms.Control windowsControl) 
    { 
     Init(windowsControl.Height, windowsControl.Width, windowsControl.Handle.ToInt32());       
    } 

    /// <summary> 
    /// Stop the webcam and destroy the handle 
    /// </summary> 
    public void Stop() 
    { 
     SendMessage(deviceHandle, WM_CAP_DRIVER_DISCONNECT, this.index, 0); 

     DestroyWindow(deviceHandle); 
    } 
} 

Program ShowWindow przyjmuje parametr PictureBox jako parametr.

+0

Używam tego samego sposobu co rob, ale odkryłem, że kamera internetowa nie jest wywoływana zawsze. jeśli zrestartuję mój system, kamera internetowa uruchomi się po naciśnięciu przycisku start, ale jeśli się zatrzymam i ponownie naciśnie klawisz Start, wideo nie zostanie wyświetlone. wartości SendMessage (deviceHandle, WM_CAP_DRIVER_CONNECT, this.index, 0 dochodzi do zera i nie wyświetla się żaden film, ktoś zasugerował, żebym zmieniał wartość handle/this.index za każdym razem, ale to też nie wyszło na jaw – Swati

+0

ja też nie mogłem znajdź, jak zapisać ten film wideo otrzymany w formacie MP4. Pomóżcie – Swati

+0

Potem próbuję wywołać DeviceManager.GetAllDevices(), że rzuci "System.EntryPointNotFoundException:" Nie można pobrać w systemie "CapGetDriverDescriptionA" w DLL "avicap32.dll". "" Co robię nieprawidłowo? – EgoPingvina

4

Zalecam korzystanie z biblioteki innej firmy. Byłoby to najlepsze rozwiązanie, zamiast wymyślać własny rower. Tutaj użyłem AForge.Net. Choć ma pewne problemy z wydajnością, ale sam podkręciłem bibliotekę, gdy wydajność stała się dla mnie kluczowym problemem. Kod AForge.Net jest open source i możesz go dostosować do swoich potrzeb.

Co do książek, zdecydowanie powinieneś spojrzeć na Jeffrey Richter's "CLR via C#" i John Skeet's "C# in Depth".

-1

Do przechwytywania zdjęć i filmów służy . Oto Link tutaj jest kod źródłowy do tego LINK

Powiązane problemy