使用directshow播放檔案並監聽事件的簡單例子
編者:李國帥
qq:9611153 微信lgs9611153
時間:2010/8/24
背景原因:
使用directShow進行檔案播放,並監聽事件。入門例子
播放
Some events are handled silently by the Filter Graph Manager, without the application being notified. Other events are placed on a queue for the application.
#include "stdafx.h" #include <DShow.h>
#pragma comment(lib,"Strmiids.lib") #pragma comment(lib,"Quartz.lib") //Strmiids.lib Exports class identifiers (CLSIDs) and interface identifiers (IIDs). All DirectShow applications require this library. //Quartz.lib Exports the AMGetErrorText function. If you do not call this function, this library is not required.
int _tmain(int argc, _TCHAR* argv[]) { // Initialize the COM library. HRESULT hr =CoInitialize(NULL); if (FAILED(hr)) { printf("ERROR - Could not initialize COM library" perror("CoInitialize failed!"); exit(-1); } // Create the filter graph manager and query for interfaces. IGraphBuilder *pGraph =NULL; hr = CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,IID_IGraphBuilder,(void **)&pGraph); if (FAILED(hr)) { printf("ERROR - Could not create the Filter Graph Manager."); perror("IGraphBuilder get failed!"); CoUninitialize(); exit(-1); } IMediaControl *pControl =NULL; IMediaEvent *pEvent =NULL; hr = pGraph->QueryInterface(IID_IMediaControl,(void**)&pControl); hr = pGraph->QueryInterface(IID_IMediaEvent,(void**)&pEvent);
// Build the graph. IMPORTANT: Change this string to a file on your system. hr = pGraph->RenderFile(L"F:\\Samples\\Media\\chicken_divx.avi",NULL); if (SUCCEEDED(hr)) { // Run the graph. hr = pControl->Run(); if (SUCCEEDED(hr)) { // Wait for completion. long evCode; pEvent->WaitForCompletion(INFINITE, &evCode);
// Note: Do not use INFINITE in a real application, because it can block indefinitely. } } if (FAILED(hr)) { perror("RenderFile failed!"); pGraph->Release(); CoUninitialize(); exit(-1); }
pControl->Release(); pEvent->Release(); pGraph->Release(); CoUninitialize();
return 0; }
|
使用視窗控制代碼接收事件
#define WM_GRAPHNOTIFY WM_APP + 1 IMediaEventEx *g_pEvent = NULL;
pGraph->QueryInterface(IID_IMediaEventEx, (void **)&g_pEvent); g_pEvent->SetNotifyWindow((OAHWND)g_hwnd, WM_GRAPHNOTIFY, 0);
//In your application's WindowProc function, add a case statement for the WM_GRAPHNOTIFY message: case WM_GRAPHNOTIFY: HandleGraphEvent(); break; void HandleGraphEvent() { // Disregard if we don't have an IMediaEventEx pointer. if (g_pEvent == NULL) return;
// Get all the events long evCode, param1, param2; HRESULT hr; while (SUCCEEDED(g_pEvent->GetEvent(&evCode, ¶m1, ¶m2, 0))) { g_pEvent->FreeEventParams(evCode, param1, param2); switch (evCode) { case EC_COMPLETE: // Fall through. case EC_USERABORT: // Fall through. case EC_ERRORABORT: CleanUp(); PostQuitMessage(0); return; } } }
// Disable event notification before releasing the graph. g_pEvent->SetNotifyWindow(NULL, 0, 0); g_pEvent->Release(); g_pEvent = NULL;
|