一 个简单的基于DirectShow的打开本地视频文件的例子。ide
参考了各类资材,网上不少,也比较简单,但有个问题就是在调用" RenderFile "函数时只有在x86下都会返回S_OK,很费解。。。待继续深刻研究一下。函数
代码:ui
IGraphBuilder *gGraph = NULL; IMediaControl *gControl = NULL; IMediaEvent *gEvent = NULL;
bool CreateSimplerPlayer(PTSTR pstrFileName) { // init com HRESULT hr = CoInitialize(NULL); if (FAILED(hr)) return false; // init gragh builder hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&gGraph); if (FAILED(hr)) return false; // query controler interface in graphbuilder hr = gGraph->QueryInterface(IID_IMediaControl, (void**)&gControl); if (FAILED(hr)) return false; // query event interface in graphbuilder hr = gGraph->QueryInterface(IID_IMediaEvent, (void**)&gEvent); if (FAILED(hr)) return false; hr = gGraph->QueryInterface(IID_IBasicVo, (void**)&gVideo); if (FAILED(hr)) return false; // read a file hr = gGraph->RenderFile(pstrFileName, NULL); if (!FAILED(hr)) { hr = gControl->Run(); if (SUCCEEDED(hr)) { long evCode; gEvent->WaitForCompletion(INFINITE, &evCode); return true; } } return false; }
主要就是RenderFile,只要选择播放的文件,IGraphBuilder就智能地帮你构造出整个Filter Graph。spa
下面是在控制台程序中打开文件管理对话框的代码,选择好文件后将文件路径传给CreateSimplerPlayer。code
代码:视频
TCHAR szBuffer[MAX_PATH] = { 0 }; OPENFILENAME file = { 0 }; file.hwndOwner = NULL; file.lStructSize = sizeof(file); file.lpstrFilter = _T("全部文件(*.*)\0*.*\0Exe文件(*.exe)\0*.exe\0");//要选择的文件后缀 file.lpstrInitialDir = _T("E:\\");//默认的文件路径 file.lpstrFile = szBuffer;//存放文件的缓冲区 file.nMaxFile = sizeof(szBuffer) / sizeof(*szBuffer); file.nFilterIndex = 0; file.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER;//标志若是是多选要加上OFN_ALLOWMULTISELECT BOOL bSel = GetOpenFileName(&file); //cout << file.lpstrFile << endl; SimplePlayer::CreateSimplerPlayer(file.lpstrFile);