CapAvi V2 - Захват видео с Web-камеры.
Программа работает следующим образом:
- если запустить без аргументов, запись по-умолчанию (Семь секунд)
- если указать CapAvi 600 то запись продлится десять минут (естественно сколько вы укажите, десять - это в переводе 600)
- в момент захвата - запись можно отменить, нажав CTRL+F12
Развернуть: CapAvi.cpp - Код: Выделить всё
// CapAvi.cpp
#pragma comment(lib,"vfw32.lib")
#include <windows.h>
#include <vfw.h>
#define TIMER_LIMIT 7 /* Время захвата по-умолчанию. */
#define ID_HOTKEY 0x0CDC31337 /* Горячая клавиша. */
char* GWndname="wnd_capavi"; /* Имя оконного класса. */
char* GAppname="Capture Avi'"; /* Имя приложения. */
UINT wTimeLimit=TIMER_LIMIT; /* Время захвата. Если аргументы не указаны, захват по-умолчанию, в течении семи секунд. */
void mb(char*); /* Сообщение пользователю. */
char* appBaseDir(); /* Получает рабочий каталог. */
DWORD WINAPI ThreadWatcher(LPVOID); /* Информационная триада (поток) работающий независимо. */
char* TimeCalc(int nTotal); /* Вычисляет время из величины введеной пользователем. */
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
{
char svBuffer[1024];
char svName[256];
char svComment[512];
WORD wDriverIndex=0;
/* Запуск одной копии. */
CreateMutex(NULL,0,GAppname);
BOOL bRet=(GetLastError()==ERROR_ALREADY_EXISTS);
if(bRet) return 0;
/* Обнаружение видео-устройств. */
for(int i=0;i<5;++i) {
if(capGetDriverDescription(wDriverIndex,svName,255,svComment,512)) {
wsprintf(svBuffer,"%d: %s %s",wDriverIndex,svName,svComment);
++wDriverIndex;
}
}
if(!wDriverIndex)
mb("Failed - missing video device.");
--wDriverIndex;
/* Получение аргументов командной строки. */
char* svCmdLine=GetCommandLine();
while(svCmdLine[0]) {
++svCmdLine;
if(' '==(*(svCmdLine-1)))
break;
}
if(svCmdLine[0])
wTimeLimit=atoi(svCmdLine);
/* Регистрация комбинации клавиш "Ctrl+F12"
для отмены захвата. */
UINT fsModifiers=MOD_CONTROL;
//UINT fsModifiers=MOD_CONTROL | MOD_ALT;
UINT vkey=VK_F12;
if(!RegisterHotKey(NULL,ID_HOTKEY,fsModifiers,vkey))
mb("Failed RegisterHotKey");
WNDCLASSEX wcex={sizeof(WNDCLASSEX),0,DefWindowProc,
0,0,hInstance,NULL,NULL,NULL,NULL,GWndname,NULL,};
ATOM Atom=RegisterClassEx(&wcex);
if(!Atom) {
Atom=RegisterClass((LPWNDCLASS)&wcex.style);
if(!Atom)
mb("Failed register class");
}
HWND hWnd=CreateWindowEx(0,MAKEINTATOM(Atom),
GAppname,0,0,0,0,0,HWND_DESKTOP,NULL,hInstance,NULL);
if(!hWnd)
mb("Failed create window");
/* Создание имя файла захвата состоящего из даты
и времени включая секунды (в этом уникальность имени). */
char svDate[128];
char svTime[128];
GetDateFormat(LOCALE_SYSTEM_DEFAULT,0,NULL,"ddMMyy",svDate,128);
GetTimeFormat(LOCALE_SYSTEM_DEFAULT,TIME_FORCE24HOURFORMAT,NULL,"hhmmss",svTime,128);
char svFilename[MAX_PATH];
wsprintf(svFilename,"%s%s_%s.avi",appBaseDir(),svDate,svTime);
char svTimeLimit[128];
if(svCmdLine[0]) {
/* Вычислить время указанное пользователем. */
lstrcpy(svTimeLimit,TimeCalc((int)wTimeLimit));
}
else
wsprintf(svTimeLimit,"%d",TIMER_LIMIT);
/*-------------------------------------------------------
Create watcher thread.
-------------------------------------------------------*/
char svTimeStart[128];
GetTimeFormat(LOCALE_SYSTEM_DEFAULT,
TIME_FORCE24HOURFORMAT,NULL,
"hh':'mm",
//"hh'-'mm'-'ss",
svTimeStart,128);
wsprintf(svBuffer,
"Capture video...\n"
"to file %s\n\n"
"record start %s\n\n"
"record total %s\n\n"
"Press \"CTRL+F12\" <Canceled>",
svFilename,
svTimeStart,
svTimeLimit);
LPVOID lpParameter=reinterpret_cast<LPVOID>(svBuffer);
DWORD tid;
HANDLE hThread=CreateThread(NULL,0,ThreadWatcher,lpParameter,0,&tid);
if(!hThread) mb("Failed create thread");
CloseHandle(hThread);
HWND hwndCap=capCreateCaptureWindow("wnd_cap",WS_CHILD,0,0,160,120,hWnd,1);
if(!hwndCap)
mb("Failed capCreateCaptureWindow");
if(!capDriverConnect(hwndCap,wDriverIndex)) {
DestroyWindow(hwndCap);
wsprintf(svBuffer,"Failed - unable to connect to driver #%d",wDriverIndex);
mb(svBuffer);
}
CAPDRIVERCAPS pcdc;
capDriverGetCaps(hwndCap,&pcdc,sizeof(CAPDRIVERCAPS));
if(!pcdc.fCaptureInitialized) {
DestroyWindow(hwndCap);
wsprintf(svBuffer,"Failed - driver was not initialized for device #%d",wDriverIndex);
mb(svBuffer);
}
DWORD dwSize=capGetVideoFormatSize(hwndCap);
BITMAPINFO* pbiOrig=(BITMAPINFO*)malloc(dwSize);
if(!pbiOrig) {
DestroyWindow(hwndCap);
mb("Failed - memory allocation error.");
}
BITMAPINFO* pbiInfo=(BITMAPINFO*)malloc(dwSize);
if(!pbiInfo) {
DestroyWindow(hwndCap);
mb("Failed - memory allocation error (#2).");
}
capGetVideoFormat(hwndCap,pbiOrig,dwSize);
memcpy(pbiInfo,pbiOrig,dwSize);
DWORD dwBPP=16;
DWORD dwFPS=15;
DWORD dwWidth=160;
DWORD dwHeight=120;
pbiInfo->bmiHeader.biWidth=dwWidth;
pbiInfo->bmiHeader.biHeight=dwHeight;
pbiInfo->bmiHeader.biBitCount=(WORD)dwBPP;
pbiInfo->bmiHeader.biPlanes=1;
pbiInfo->bmiHeader.biClrUsed=0;
pbiInfo->bmiHeader.biSizeImage=0;
pbiInfo->bmiHeader.biClrImportant=0;
pbiInfo->bmiHeader.biCompression=BI_RGB;
pbiInfo->bmiColors->rgbRed=0;
pbiInfo->bmiColors->rgbBlue=0;
pbiInfo->bmiColors->rgbGreen=0;
pbiInfo->bmiColors->rgbReserved=0;
CAPTUREPARMS capparms;
capSetVideoFormat(hwndCap,pbiInfo,dwSize);
capCaptureGetSetup(hwndCap,&capparms,
sizeof(CAPTUREPARMS));
capparms.vKeyAbort=MOD_CONTROL | VK_F12;
capparms.wTimeLimit=wTimeLimit;
capparms.fLimitEnabled=TRUE;
capparms.fAbortLeftMouse=FALSE;
capparms.fAbortRightMouse=FALSE;
capparms.fMakeUserHitOKToCapture=FALSE;
capparms.dwRequestMicroSecPerFrame=(1000000/dwFPS);
capCaptureSetSetup(hwndCap,&capparms,sizeof(CAPTUREPARMS));
capFileSetCaptureFile(hwndCap,svFilename);
capCaptureSequence(hwndCap);
capSetVideoFormat(hwndCap,pbiOrig,dwSize);
capDriverDisconnect(hwndCap);
DestroyWindow(hwndCap);
/* Закрыть триаду (информационное сообщение).
Найти с помощью функции FindWindow и с помощью
PostMessage - при этом найдя единственную кнопку
с помощью GetTopWindow, отправить сообщение о
как-бы нажатии кнопки OK (BM_CLICK).
Стоит заметить - этот трюк проходит не всегда.
Например в Windows XP, Seven - работает, в следующих
мне неизвестно. */
HWND hwnd=FindWindow("#32770",GAppname);
if(hwnd) PostMessage(GetTopWindow(hwnd),BM_CLICK,0,0);
wsprintf(svBuffer,
"Video record successful.\n\n"
"Play videos?\n%s",
svFilename);
if(IDYES==MessageBox(hWnd,svBuffer,GAppname,
MB_YESNO | MB_ICONQUESTION |
MB_SETFOREGROUND | MB_SYSTEMMODAL))
ShellExecute(0,"open",svFilename,NULL,NULL,SW_SHOWNORMAL);
/* Снять регистрацию горячих клавиш. */
UnregisterHotKey(hWnd,ID_HOTKEY);
return 0;
}
void mb(char* Str)
{
UINT uType=MB_OK | MB_ICONINFORMATION |
MB_SETFOREGROUND | MB_SYSTEMMODAL;
int n=0;
if(strstr(Str,"Failed") || strstr(Str,"Error"))
++n;
if(n) {
uType &=~MB_ICONINFORMATION;
uType |=MB_ICONWARNING;
} MessageBox(GetActiveWindow(),Str,GAppname,uType);
if(n)
ExitProcess(n);
}
char* appBaseDir()
{
static char Result[MAX_PATH];
if(!Result[0]) {
GetModuleFileName(GetModuleHandle(NULL),Result,MAX_PATH);
int i;
for(i=lstrlen(Result)-1;i>0;--i) {
if('\\'==Result[i-1] || '/'==Result[i-1])
break;
}
Result[i]=0;
}
return Result;
}
DWORD WINAPI ThreadWatcher(LPVOID parm)
{
char* svMsg=reinterpret_cast<char*>(parm);
mb(svMsg);
return 0;
}
char* TimeCalc(int nTotal)
{
static char svBuff[64];
int minutes=nTotal / 60;
int seconds=nTotal % 60;
int hours=minutes / 60;
minutes=minutes % 60;
if(!hours) {
if(!minutes)
wsprintf(svBuff,"%d secs",seconds);
else
wsprintf(svBuff,"%02d:%02d",minutes,seconds);
}
else
wsprintf(svBuff,"%2d:%02d:%02d",hours,minutes,seconds);
return svBuff;
}
Последний раз редактировалось
rvg 27 сен 2023, 15:31, всего редактировалось 1 раз.