Jak ve vlastním programu zachytávat video?

Dnes se již stává skoro běžným vybavením počítače nějaké zařízení na zachytávání videa. Ukažme si proto, jak lze vytvořit vlastní program pro zachytávání videosekvencí.
Dnes se již stává skoro běžným vybavením počítače nějaké zařízení na zachytávání videa. Může to být běžná webová kamera (např. WebCam od firmy Creative), speciální karta (např. AV-Master) nebo jako doplněk některých běžných VGA karet, které mají vstup právě pro zachytávání videa. Ukažme si proto, jak lze vytvořit vlastní program pro zachytávání videosekvencí.

Pro zachytávání videa ve Windows se používají funkce (již v tomto seriálu zmíněné) knihovny „Video for Windows“.

Protože tato problematika, pokud budeme chtít zajít trochu více do podrobností, je obsáhlejší než rozsah tohoto článku, rozdělíme si ji na více (2-3) pokračování. V tomto prvním článku bude naším cílem vytvořit nejjednodušší funkční aplikaci, která bude umět zachytávat video nebo jednotlivé snímky, z nichž vytvoří video sekvenci (AVI soubor). Nebudeme se zatím zabývat speciálním nastavením driveru a použijeme výchozí nastavení, resp. to nastavení, které si uživatel nastaví v systému, třeba v jiné aplikaci, která obvykle bývá nainstalována s dodaným hardwarem. Nebudeme ani provádět kontrolu, zda zařízení opravdu je správně nainstalováno. To vše si necháme na příště.

Vytvoříme si tedy aplikaci (nejjednodušeji založenou na MFC dialogu), do níž si přidáme třídu (generic class), která nám bude zapouzdřovat funkce zachytávání videa.

Prvním krokem je vytvořit okno zachytávání videa. Pro tento účel nemusíme registrovat třídu a používat „klasickou“ funkci CreateWindowEx, neboť v knihovně „Video for Windows“ je pro tento účel již připravená funkce capCreateCaptureWindow:

HWND VFWAPI capCreateCaptureWindow(
  LPCSTR lpszWindowName, // “jméno” oknba
  DWORD dwStyle,         // styl okna
  int x,                 // pozice okna (x-ová souřadnice)
  int y,                 // pozice okna (y-ová souřadnice)
  int nWidth,            // šířka okna
  int nHeight,           // výška okna
  HWND hWnd,             // rodičovské okno
  int nID                // identifikátor okna
);

Tato funkce nám vrátí handle okna, na které se budeme dále odkazovat.

Pokud máme takto úspěšně vytvořené okno, můžeme se „připojit“ k ovladači zachytávání videa pomocí makra capDriverConnect:

BOOL capDriverConnect(
  hwnd,  // handle okna
  iIndex // index driveru (počítáno od 0)
);

Index driveru určuje (pokud je nainstalováno víc ovladačů zachytávání videa), který ovladač se má použít. Hodnota 0 je výchozí ovladač.

Nyní si tedy vytvoříme členskou funkci naší třídy, která vytvoří okno a připojí driver. Jejím parametrem je rodičovské okno, v našem případě handle okna dialogu naší aplikace.

BOOL CRPJVideoCapture::Create(HWND hwndParent)
{
  if ( IsWindow(m_hWnd) )
    return FALSE;
  m_hWnd = capCreateCaptureWindow(
    (LPSTR)"RPJ Video Capture",
    WS_CHILD | WS_VISIBLE,
    0, 0, 320, 240,
    (HWND)hwndParent,
    (int)0);
  if ( !IsWindow(m_hWnd) )
    return FALSE;
  if ( !capDriverConnect(m_hWnd, 0) ) // připojíme výchozí driver
    return FALSE;
  return TRUE;
}

Nyní bychom již mohli spustit zachytávání videa, ale bývá zvykem nejdříve spustit náhled (preview). K tomu slouží makro capPreview:

BOOL capPreview(
  HWND hwnd, 
  BOOL f        // TRUE spustí preview, FALSE jej zastaví
);

Ještě před tím však musíme (alespoň ve většině případů) nastavit frekvenci obrázků při náhledu. V opačném případě bychom viděli statický „snímek“ okamžiku připojení driveru. Tato frekvence se nastavuje v milisekundách, tj. jako doba trvání jednoho snímku. Standardní hodnota bývá 66 milisekund, odpovídající cca 15 snímkům za sekundu. K tomuto nastavení slouží makro capPreviewRate:

BOOL capPreviewRate(
  HWND hwnd,  // handle okna
  LONG wMS    // hodnota v milisekundách
);

Vytvořme si tedy členskou funkci, která spustí zobrazení náhledu:

BOOL CRPJVideoCapture::ShowPreview()
{
  if ( !IsWindow(m_hWnd) )
    return FALSE;
  ShowWindow(m_hWnd, SW_SHOW);
  capPreviewRate(m_hWnd, 66);
  return capPreview(m_hWnd, TRUE);
}

a podobně funkci na jeho zastavení a skrytí:

BOOL CRPJVideoCapture::HidePreview()
{
  if ( !IsWindow(m_hWnd) )
    return FALSE;
  if ( !capPreview(m_hWnd, FALSE) )
    return FALSE;
  ShowWindow(m_hWnd, SW_HIDE);
  return TRUE;
}

K tomu na vysvětlenou: pouhým zastavením náhledu funkcí capPreview s parametrem FALSE okno nezmizí, pouze zůstane zobrazen poslední snímek náhledu. Proto používáme funkci ShowWindow na skrytí a opětné zobrazení okna s náhledem. Můžeme si také vytvořit funkci, která pouze spustí nebo zastaví náhled, ale okno bude viditelné.

BOOL CRPJVideoCapture::Preview(BOOL Start)
{
  if ( !IsWindow(m_hWnd) )
    return FALSE;
  capPreviewRate(m_hWnd, 66);
  return capPreview(m_hWnd, Start);
}

Ještě se zmíním o funkci, která povolí overlay při zobrazování videa. Je však třeba, aby tuto vlastnost podporoval hardware a příslušný ovladač. Pomocí makra capDriverGetCaps:

BOOL capDriverGetCaps(
  hwnd,   
  psCaps, 
  wSize   
);

kterým se budeme podrobněji zabývat příště, zjistíme schopnosti ovladače. V případě, že to ovladač podporuje, povolíme overlay funkcí capOverlay:

BOOL capOverlay(
  HWND  hwnd,  // handle okna
  BOOL  f    // povolit overlay
);

Naše členská funkce bude tedy vypadat třeba takto:

BOOL CRPJVideoCapture::EnableOverlay(BOOL Overlay)
{
  if ( !IsWindow(m_hWnd) )
    return FALSE;
  if ( !Overlay )
  {
    return capOverlay(m_hWnd, FALSE);
  }
  else
  {
    CAPDRIVERCAPS CapDrvCaps;
    capDriverGetCaps(m_hWnd, &CapDrvCaps, sizeof (CAPDRIVERCAPS));
    if (!CapDrvCaps.fHasOverlay)
    {
      Error("Ovladač nepodporuje overlay!");
      return FALSE;
    }
    else
      return capOverlay(m_hWnd, TRUE);
  }
}

Nyní můžeme přistoupit k vlastnímu zachytávání videa do souboru. Jméno výsledného souboru je standardně nastaveno na „c:\capture.avi“. Zatím jej necháme beze změny, dalším nastavením se budeme zabývat v příštím článku. Ke spuštění zachytávání videa nám slouží makro capCaptureSequence:

BOOL capCaptureSequence(
  HWND  hwnd 
);

Tato funkce spustí zachytáváni videa do souboru „c:\capture.avi“ (pokud nenastavíme jiný soubor) a zachytávání pokračuje, dokud uživatel nestiskne klávesu <ESCAPE> nebo pokud zachytávání nezastavíme programově pomocí makra capCaptureStop:

BOOL capCaptureStop(
  HWND  hwnd  // handle okna
);

V naší třídě si tedy vytvoříme 2 členské funkce pro spuštění a zastavení zachytávání:

BOOL CRPJVideoCapture::StartCapture()
{
  if ( !IsWindow(m_hWnd) )
    return FALSE;
  return capCaptureSequence(m_hWnd);
}

BOOL CRPJVideoCapture::StopCapture()
{
  if ( !IsWindow(m_hWnd) )
    return FALSE;
  return capCaptureStop(m_hWnd);
}

Nakonec si ještě ukážeme, že je možné do výstupního videosouboru (.avi) ukládat jednotlivé samostatně zachycené snímky. Nejdříve musíme otevřít tento výstup pomocí makra capCaptureSingleFrameOpen:

BOOL capCaptureSingleFrameOpen(
  WND hwnd
);

Nyní můžeme do tohoto výstupního souboru přidávat jednotlivé zachycené snímky pomocí makra capCaptureSingleFrame:

BOOL capCaptureSingleFrame
(
  HWND  hwnd  // handle okna
);

Zavření výstupního souboru pak provedeme funkcí capCaptureSingleFrameClose:

BOOL capCaptureSingleFrameClose
(
  HWND  hwnd 
);

Výsledkem je videosoubor tvořený sekvencí zachycených snímků.

Na závěr ještě pár upřesňujících poznámek: Když se podíváte do dokumentace (nejlépe MSDN), zjistíte, že většina zde uvedených maker, jako třeba capCapturePreview, nemá u parametru(-ů) uveden typ. Ve skutečnosti tato makra realizují svoji funkci pomocí zaslání příslušné zprávy oknu. Například uvedené makro capCapturePreview posílá oknu zprávu WM_CAP_SET_PREVIEW

WM_CAP_SET_PREVIEW
wParam = (WPARAM) (BOOL) (f); // volba náhledu
lParam = 0L;

tudíž všechny parametry těchto maker jsou ve skutečnosti typu WPARAM nebo LPARAM (parametry zprávy Windows), což jsou ve Win32 API 32bitové hodnoty. A parametr hwnd u těchto maker je samozřejmě typu HWND, což je první parametr funkce SendMessage, jejíž syntaxe je tato:

LRESULT SendMessage(
  HWND hWnd,      // handle cílového okna
  UINT Msg,        // identifikátor zprávy
  WPARAM wParam,  // 1. parametr zprávy
  LPARAM lParam    // 2. parametr zprávy
);

Ukázku ke dnešnímu článku si můžete stáhnout zde: video_capture.zip (34 kB)

Diskuze (2) Další článek: Aktualizace virové databáze od Symantecu podražila

Témata článku: Video, Software, Windows, Programování, VLA, Běžná hodnota, Výstupní video, Code, Escape, Speciální karta, Statický snímek, Vid, Okno, Makro, Záchyt, Webcam


Určitě si přečtěte

Zahodil jsem Windows, přešel na Linux a nezbláznil se z toho

Zahodil jsem Windows, přešel na Linux a nezbláznil se z toho

** Měsíc jsem se nedotkl Windows a byl závislý jen na Linuxu ** Jaká byla pozitiva a negativa přechodu? ** Se kterými aplikacemi jsem (ne)zápasil a které bych doporučil?

Lukáš Václavík | 233

Nové názvy, upravený vývoj. Microsoft ukázal, jak teď bude vydávat Windows 10

Nové názvy, upravený vývoj. Microsoft ukázal, jak teď bude vydávat Windows 10

** Podzimní vydání Windows 10 přinese jen minimum novinek ** Aktualizace ponese formální označení 20H2 ** Microsoft mění názvy v programu Windows Insider

Lukáš Václavík | 17

Jak uložit dokument z Wordu, aby vydržel celé roky? Je to těžší než cesta na Mars

Jak uložit dokument z Wordu, aby vydržel celé roky? Je to těžší než cesta na Mars

** Jak uložit soubory, aby vydržely vnoučatům? ** A co kdyby měly přečkat celá staletí? ** Teď se o to pokouší GitHub a je to oříšek i pro lingvisty

Jakub Čížek | 118

Testy procesorů Intel Comet Lake pro desktopy jsou venku. Teď už je jasné, jakého dostaly Ryzeny soupeře

Testy procesorů Intel Comet Lake pro desktopy jsou venku. Teď už je jasné, jakého dostaly Ryzeny soupeře

** Embargo pro testy nových desktopových procesorů Comet Lake od Intelu skončilo ** Spousta recenzí a testů ukazuje výhody a nevýhody nových modelů ** Dokáží nové procesory konkurovat modelům od AMD?

Karel Javůrek | 47

Za hranicemi Chromu: 13 nejzajímavějších prohlížečů, které „nikdo“ nepoužívá

Za hranicemi Chromu: 13 nejzajímavějších prohlížečů, které „nikdo“ nepoužívá

** Šesti nejpoužívanějším prohlížečům patří 94 % trhu ** Různé „klony“ Chromu slibují lepší funkce nebo jiný design ** Také Firefox má řadu zajímavých odnoží

Lukáš Václavík | 38

Šmírování kamerami Googlu: Koukněte, co šíleného se objevilo na Street View

Šmírování kamerami Googlu: Koukněte, co šíleného se objevilo na Street View

Google stále fotí celý svět do své služby Street View. A novodobou zábavou je hledat v mapách Googlu vtipné záběry. Podívejte se na výběr nejlepších!

redakce | 3

Nejlepší programy z roku 2000: Podívejte se, bez čeho jste tehdy vůbec nemohli fungovat!

Nejlepší programy z roku 2000: Podívejte se, bez čeho jste tehdy vůbec nemohli fungovat!

** Dnes už skoro všechno uděláte ve webovém prohlížeči a na mobilu ** Před dvaceti lety to ale bylo jiné ** Zavzpomínejte na legendy, které jste pravděpodobně také používali

Jakub Čížek | 126


Aktuální číslo časopisu Computer

Megatest: nejlepší notebooky do 20 000 Kč

Test 8 levných IP kamer

Jak vybrat bezdrátová sluchátka

Testujeme Android 11