承接前作「即時語音通訊」,作者嘗試擴充至視訊功能:擷取攝影機畫面、即時預覽、選擇壓縮器編碼/解碼、單幀擷圖儲存。本文整理核心流程與關鍵 API,供有興趣開發視訊聊天/監控的開發者參考。
cap* 系列 API 及壓縮/解壓縮邏輯 (ICCompress/ICDecompress)。void CVideoPlayBackDlg::OnInitDialog()
{
// 1. 設定擷取格式 (BITMAPINFO)
InitCaptureFormat(); // 填寫 m_InInfo: 寬高、位深、壓縮格式等
// 2. 載入 VideoDll.dll 並初始化壓縮變數 COMPVARS
LoadLibrary(_T("VideoDll.dll"));
ICCompressGetFormat(...); // 取得壓縮後格式
ICCompressBegin(...); // 初始化壓縮器
// 3. 開啟視訊裝置並開始預覽
InitVideoCard();
}
void CVideoPlayBackDlg::InitVideoCard()
{
// 連接驅動程式 (裝置索引 0)
if (!capDriverConnect(m_hWndCapture, 0))
AfxMessageBox(_T("Driver Connect Failure"));
// 設定視訊格式
if (!capSetVideoFormat(m_hWndCapture, &m_InInfo, sizeof(BITMAPINFO)))
AfxMessageBox(_T("Fail to set video format"));
// 設定預覽幀率 (24 fps)
capPreviewRate(m_hWndCapture, 24);
// 啟用預覽 (畫面直接顯示在 m_hWndCapture 視窗)
capPreview(m_hWndCapture, TRUE);
// 設定單幀回呼函式
if (!capSetCallbackOnFrame(m_hWndCapture, FrameCallBack))
AfxMessageBox(_T("fail to setCallbackOnFrame function"));
}
每擷取一幀即觸發,執行壓縮、解壓縮、畫面刷新、網路發送:
LRESULT CALLBACK FrameCallBack(HWND hWnd, LPVIDEOHDR lpVHdr)
{
// 1. 壓縮原始幀資料
ICCompress(m_hIC, lpVHdr->lpData, lpVHdr->dwBytesUsed, ...);
// 2. 解壓縮供本地預覽
ICDecompress(m_hICDecomp, ...);
// 3. 觸發視窗重繪顯示最新幀
InvalidateRect(hWndPreview, NULL, FALSE);
// 4. 網路發送 (Socket) - 參考語音通訊傳送機制
// send(sock, compressedBuf, compressedLen, 0);
return TRUE; // 繼續回呼
}
void CVideoPlayBackDlg::OnDestroy()
{
capSetCallbackOnFrame(m_hWndCapture, NULL);
capPreview(m_hWndCapture, FALSE);
capDriverDisconnect(m_hWndCapture);
ICCompressEnd(m_hIC);
ICDecompressEnd(m_hICDecomp);
FreeLibrary(hVideoDll);
CDialog::OnDestroy();
}
| 功能 | VFW API | 壓縮 API |
|---|---|---|
| 開啟裝置 | capCreateCaptureWindow / capDriverConnect | - |
| 設定格式 | capSetVideoFormat | ICCompressGetFormat |
| 預覽 | capPreview / capPreviewRate | - |
| 單幀回呼 | capSetCallbackOnFrame | - |
| 壓縮 | - | ICSeqCompressFrame / ICCompress |
| 解壓縮 | - | ICDecompress |
| 儲存 AVI | capFileSaveAs / AVISaveV | - |
完整原始碼含 VideoDll.dll 專案與主程式,可向作者索取:terrist007@163.com