DES对于视频的拼接和拼接后视频的预览书上都有讲到,但是对于拼接后视频保存到本地的代码却是哪也找不到(自己搜索过很久)
保存到本地的关键一段代码就是找到压缩器,这段代码书上只说了大概的思路,如果你不使用压缩器直接用书上的代码的话,截取下来的视频画面将严重失真。
void CXunLeiPlayDlg::WriteFile(IAMTimeline *pTL) { IRenderEngine *pRenderEngine=NULL; CoCreateInstance(CLSID_RenderEngine,NULL,CLSCTX_INPROC_SERVER,IID_IRenderEngine ,(void**)&pRenderEngine); IMediaControl *pMC=NULL; IMediaEvent *pEvent=NULL; IGraphBuilder *pGraph; ICaptureGraphBuilder2 *pBuilder=NULL; HRESULT hr=pRenderEngine->SetTimelineObject(pTL); hr=pRenderEngine->ConnectFrontEnd(); hr=pRenderEngine->GetFilterGraph(&pGraph); hr=CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (void **)&pBuilder); ASSERT(SUCCEEDED(hr)); hr=pBuilder->SetFiltergraph(pGraph); ASSERT(SUCCEEDED(hr)); IBaseFilter *pMux; hr=pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi,L"流年逝水.avi",&pMux,NULL); ASSERT(SUCCEEDED(hr)); long NumGroups; pTL->GetGroupCount(&NumGroups); for (int i=0;i<NumGroups;i++) { IPin *pPin=NULL; if (pRenderEngine->GetGroupOutputPin(i,&pPin)==S_OK) { IBaseFilter *pCompressor=NULL; pCompressor=GetCompressor(CLSID_VideoCompressorCategory,"Microsoft Video 1"); //获取压缩器 pGraph->AddFilter(pCompressor,L"com");//加入过滤器 hr=pBuilder->RenderStream(NULL,NULL,pPin,pCompressor,pMux); ASSERT(SUCCEEDED(hr)); pPin->Release(); } } pGraph->QueryInterface(IID_IMediaEvent,(void**)&pEvent); pGraph->QueryInterface(IID_IMediaControl,(void**)&pMC); pMC->Run(); long evCode; pEvent->WaitForCompletion(INFINITE,&evCode); pMC->Stop(); } IBaseFilter* CXunLeiPlayDlg::GetCompressor(GUID inCategory, const char *inFriendlyName) { ICreateDevEnum * enumHardware = NULL; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_ALL, IID_ICreateDevEnum, (void**)&enumHardware); if (FAILED(hr)) { return NULL; } IBaseFilter * hardwareFilter = NULL; IEnumMoniker * enumMoniker = NULL; hr = enumHardware->CreateClassEnumerator(inCategory,&enumMoniker,0); if (enumMoniker) { enumMoniker->Reset(); ULONG fetched = 0; IMoniker * moniker = NULL; char friendlyName[256]; while (!hardwareFilter &&SUCCEEDED(enumMoniker->Next(1,&moniker,&fetched))&&fetched) { if (moniker) { IPropertyBag * propertyBag = NULL; VARIANT name; friendlyName[0] = 0; hr = moniker->BindToStorage(0,0,IID_IPropertyBag,(void **)&propertyBag); if (SUCCEEDED(hr)) { name.vt=VT_BSTR; hr = propertyBag->Read(L"FriendlyName",&name,NULL); } if (SUCCEEDED(hr)) { WideCharToMultiByte(CP_ACP, 0, name.bstrVal, -1, friendlyName, 256, NULL, NULL); if (strcmp(friendlyName,inFriendlyName) == 0) { moniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&hardwareFilter); } } if (propertyBag) { propertyBag->Release(); propertyBag = NULL; } moniker->Release(); } } enumMoniker->Release(); } enumHardware->Release(); return hardwareFilter; }