direct show 和windows media player 播放音视频的一个实际使用实例,使用wmp时候一定要注意需要把要播放或者getinfo的媒体文件放入到播放列表或者媒体库具体参见wmp sdk sample ,而不仅仅是open才可以取到媒体信息,方式如下:CComBSTR openBSTR(inputPath);hr = m_spMC->add(openBSTR.m_str, &spMedia); hr = spPlayer->put_currentMedia(spMedia);if(hr ==S_OK)hr =spMedia->get_duration(&time);
int getDurationByWmp(const wchar_t* inputPath){CoInitialize(NULL);CComPtr pPlayer;HRESULT hr = S_OK;CComBSTR bstrVersionInfo; // Contains the version string.CComPtr spPlayer; // Smart pointer to IWMPPlayer interface.hr = spPlayer.CoCreateInstance( __uuidof( WindowsMediaPlayer), 0, CLSCTX_INPROC_SERVER |CLSCTX_INPROC_HANDLER |CLSCTX_LOCAL_SERVER);if(SUCCEEDED(hr)){hr = spPlayer->get_versionInfo(&bstrVersionInfo);}///////////////////////// CComBSTR bstrURL, bstrMediaType;CComPtr spMedia; hr = E_POINTER; // Add the URL using mediaCollection.add() CComPtr m_spMC; CComPtr m_spPC; if( spPlayer->get_mediaCollection(&m_spMC) ==S_OK){CComBSTR openBSTR(inputPath);hr = m_spMC->add(openBSTR.m_str, &spMedia);} double time =0.0f;if(SUCCEEDED(hr) && (spMedia.p != NULL)){hr = spMedia->getItemInfo(CComBSTR(_T("MediaType")), &bstrMediaType); hr = spPlayer->put_currentMedia(spMedia); if(hr ==S_OK) hr =spMedia->get_duration(&time);}/////////////////////////// Clean up.spPlayer.Release();CoUninitialize();return (int)time;}int getMediaDuration(const wchar_t* inputPath){CoInitialize( NULL );IGraphBuilder *pGraph;HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);////////////////////////////////////////////////////////////////IMediaDet *pMedia = NULL;//hr = CoCreateInstance( CLSID_MediaDet, NULL, CLSCTX_INPROC_SERVER, IID_IMediaDet, (void **)&pMedia);//if(!pMedia)// return 0;//CComBSTR openBSTR(inputPath);//hr =pMedia->put_Filename(openBSTR.m_str);//double val =0.0;//pMedia->get_StreamLength(&val);//////////////////////////////////////////////////////////////if(!pGraph)return 0;hr = pGraph->RenderFile(inputPath,0);if(hr != S_OK){pGraph->Release();CoUninitialize();std::wstring strInput =getAbsoluteFromRelativePath(inputPath);return getDurationByWmp(strInput.c_str());//return 0;}long long duration = 0;IMediaSeeking *g_pSeek = 0;hr = pGraph->QueryInterface(IID_IMediaSeeking, (void**)&g_pSeek);if(!g_pSeek)return duration;g_pSeek->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME);hr = g_pSeek->GetDuration(&duration);duration /= VLE_FILE_SEC;g_pSeek->Release();pGraph->Release();CoUninitialize();return duration;}
DIRECT PLAYER:CVideoManager CVideoManager::vManager;CVideoManager::CVideoManager(){}CVideoManager::~CVideoManager(){for(VideoListItem begin = videos.begin(); begin != videos.end(); ++begin){IGraphBuilder* builder = (*begin)->getGraphBuilder();(*begin)->release();builder->Release();}}IGraphBuilder* CVideoManager::createGraphBuilder(){IGraphBuilder* builder = 0;HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&builder);if(hr != S_OK)printf("Failed to create graph builder\n.");return builder;}CVideoManager& CVideoManager::getInstance(){return vManager;}CVideoDS* CVideoManager::addVideo(int id){HRESULT hr = E_FAIL;CVideoDS* video = new CVideoDS(id,createGraphBuilder(),0,&hr);if(hr != S_OK)return 0;videos.push_back(video);return video;}CVideoDS* CVideoManager::getVideo(int id){for(VideoListItem begin = videos.begin(); begin != videos.end(); ++begin){if((*begin)->getID() == id)return (*begin);}return 0;}void CVideoManager::releaseVideo(CVideoDS* video){if(video){videos.remove(video);IGraphBuilder* builder = video->getGraphBuilder();video->release();ULONG ref = builder->Release();for(;ref>0;)ref = builder->Release();//ULONG ref2 = video->Release();// printf("reference count:-%d.", ref2 );//delete video;}}void CVideoManager::releaseVideo(int id){CVideoDS* video = getVideo(id);if(video){videos.remove(video);IGraphBuilder* builder = video->getGraphBuilder();video->release();builder->Release();}}void CVideoDS::release(){#ifdef __REGISTER_FOR_DEBUG__RemoveFromROT();#endifstop();// if(source)// {// builder->RemoveFilter(source);// //source->Release();// //source = 0;// }if(mediaEvent){mediaEvent->Release();mediaEvent = 0;}if(position){position->Release();position = 0;}if(control){control->Release();control = 0;}if(buffer){delete[] buffer;buffer = 0;}builder->RemoveFilter(this);}bool CVideoDS::loadFile(const wchar_t* filename){IBaseFilter* source = 0;HRESULT hr = builder->AddSourceFilter(filename,L"Source",&source);if(hr != S_OK){printf("Failed to add source filter.\n");return false;}// IBaseFilter* bFilter = NULL;// AddFilter(builder,L"Overlay Mixer",&bFilter,CLSID_LegacyAmFilterCategory,L"Overlay Mixer");IPin* pin = 0;IEnumPins* pins = 0;source->EnumPins(&pins);while(hr == S_OK){hr = pins->Next(1,&pin,0);if(hr == S_OK){wchar_t* pinName = 0;pin->QueryId(&pinName);wprintf(L"pin's name: \"%s\"\n",pinName);HRESULT hr2 = builder->Render(pin);if(hr2 == S_OK)wprintf(L"Rendered \"%s\" pin successfully.\n",pinName);elsewprintf(L"Failed to render \"%s\" pin.\n",pinName);ensureDisplayPin();pin->Release(); }}pins->Release();hr = builder->QueryInterface(IID_IMediaControl,(void**)&control);if(hr != S_OK)printf("Failed to get controller, you won't be able to play, stop and pause the file as you like.\n");hr = builder->QueryInterface(IID_IMediaPosition,(void**)&position);if(hr != S_OK)printf("Failed to get controller, you won't be able to seek the file as you like.\n");hr = builder->QueryInterface(IID_IMediaEvent,(void**)&mediaEvent);if(hr != S_OK)printf("Failed to get controller, you won't be able to loop the file as you like.\n");ULONG l =source->Release();return (hr == S_OK);}void CVideoDS::ensureDisplayPin(){if(isOK)return;IEnumFilters* pEnum = NULL;IBaseFilter* pFilter = NULL;ULONG cFetched = 0;builder->EnumFilters(&pEnum);IPin* thisFilterPin = GetPin(0);while(pEnum->Next(1, &pFilter, &cFetched) == S_OK){bool breaked = false;FILTER_INFO FilterInfo;pFilter->QueryFilterInfo(&FilterInfo);wprintf(L"Filter's name: %s\n",FilterInfo.achName);IPin* ipin = NULL;if(GetFilterPin(pFilter,PINDIR_OUTPUT,&ipin) == S_OK && ipin != thisFilterPin){AM_MEDIA_TYPE* mType;wchar_t* pinName = 0;ipin->QueryId(&pinName);wprintf(L"output pin's name: %s\n",pinName);//if input pin is our desire inputif(GetPinMediaType(ipin,MEDIATYPE_Video,GUID_NULL,GUID_NULL,&mType) == S_OK){wprintf(L"found the culprit pin!!!\n");//reconnectwprintf(L"disconnect from old pin.\n");builder->Disconnect(ipin);//remove activeMovie windowIBaseFilter* vRenderer = NULL;builder->FindFilterByName(L"Video Renderer",&vRenderer);builder->RemoveFilter(vRenderer);vRenderer->Release();printf("Reconnecting to new pin\n");builder->Connect(ipin,thisFilterPin);breaked = true;}DeleteMediaType(mType);//reconnect// wprintf(L"disconnect from old pin.\n");// builder->Disconnect(ipin);ipin->Release();ipin = NULL;}pFilter->Release();if(breaked)break;}pEnum->Release();}bool CVideoDS::play() const{if(!control)return false;HRESULT hr = control->Run();return (hr == S_OK);}bool CVideoDS::stop() const{if(!control)return false;return (control->Stop() == S_OK);}bool CVideoDS::isPlaying() const{if(!control)return false;OAFilterState state;control->GetState(0,&state);return (state == State_Running);}bool CVideoDS::pause() const{if(!control)return false;return (control->Pause() == S_OK);}double CVideoDS::getLength() const{if(!position)return 0;double duration = 0;position->get_Duration(&duration);return duration;}bool CVideoDS::setPosition(double pos){if(!position)return false;return (position->put_CurrentPosition(pos) == S_OK);}double CVideoDS::getPosition() const{double timePos = 0;if(!position)return timePos;position->get_CurrentPosition(&timePos);return timePos;}HRESULT CVideoDS::CheckMediaType(const CMediaType *pmt ) // Format acceptable?{if (pmt->majortype == MEDIATYPE_Video){isOK = false;if(pmt->subtype == MEDIASUBTYPE_RGB24 && pmt->formattype == FORMAT_VideoInfo){isOK = true;return S_OK;}return E_FAIL;}else {isOK = true;return E_FAIL;}}HRESULT CVideoDS::SetMediaType(const CMediaType *pmt ) // Video format notification{VIDEOINFO *pviBmp; // Bitmap info headerpviBmp = (VIDEOINFO *)pmt->Format();if(buffer){delete[] buffer;buffer = NULL;}bWidth = pviBmp->bmiHeader.biWidth;bHeight = pviBmp->bmiHeader.biHeight;bPitch = (bWidth * 3 + 3) & ~(3); // We are forcing RGB24int size = bHeight*bPitch;buffer = new unsigned char[size];memset(buffer,0,sizeof(unsigned char)*size);return S_OK;}void CVideoDS::readBuffer(unsigned char* b, int p){if(!buffer)return;read = false;unsigned char *pBmpBuffer, *pTxtBuffer; // Bitmap buffer, texture bufferlong lTxtPitch; // Pitch of bitmap, textureunsigned char* pbS = NULL;unsigned long * pdwS = NULL;unsigned long * pdwD = NULL;pBmpBuffer = buffer;pTxtBuffer = b+p*(bHeight-1);lTxtPitch = p;int dwordWidth = bWidth / 4; // aligned width of the row, in DWORDS// (pixel by 3 bytes over sizeof(DWORD))for(int row = 0; row< bHeight; ++row){pdwS = (unsigned long*)pBmpBuffer;pdwD = (unsigned long*)pTxtBuffer;for(int col = 0; col < dwordWidth; ++col){pdwD[0] = pdwS[0] | 0xFF000000;pdwD[1] = ((pdwS[1]<<8 0xff000000="" pdws="" 0="">>24);pdwD[2] = ((pdwS[2]<<16 0xff000000="" pdws="" 1="">>16);pdwD[3] = 0xFF000000 | (pdwS[2]>>8);pdwD +=4;pdwS +=3;}// we might have remaining (misaligned) bytes herepbS = (BYTE*) pdwS;for(int col2 = 0; col2 < bWidth % 4; ++col2){*pdwD = 0xFF000000 |(pbS[2] << 16) |(pbS[1] << 8) |(pbS[0]);pdwD--;pbS += 3;} pBmpBuffer += bPitch;pTxtBuffer -= lTxtPitch;}// for rows}void CVideoDS::update(){if(mediaEvent)loopCheck();}HRESULT CVideoDS::DoRenderSample(IMediaSample *pMediaSample) // New video sample{if(read)return S_OK;unsigned char *pBmpBuffer;pMediaSample->GetPointer( &pBmpBuffer );int size = pMediaSample->GetSize();memcpy(buffer,pBmpBuffer,bHeight*bPitch);read = true;return S_OK;}void CVideoDS::loopCheck(){long lEVentCode = 0;long lParam1 = 0, lParam2 = 0;mediaEvent->GetEvent(&lEVentCode,&lParam1,&lParam2,0);if(lEVentCode == EC_COMPLETE){if(!sendEventToListeners(END_OF_MEDIA_FILE_REACHED) && looped)setPosition(0);}mediaEvent->FreeEventParams(lEVentCode,lParam1,lParam2);}
medie player 播放://mfc way to create windowmmediaplayer:http://msdn.microsoft.com/en-us/library/dd564579 m_spPlayer->put_URL(dlg.m_bstrURL); CComPtr spControls; m_spPlayer->get_controls(&spControls); if(spControls.p) {///////////////////////// CComBSTR bstrURL, bstrMediaType;CComPtr spMedia;HRESULT hr = E_POINTER;LRESULT iRetCode; // Add the URL using mediaCollection.add() CComPtr m_spMC; CComPtr m_spPC; m_spPlayer->get_mediaCollection(&m_spMC);//m_spPlayer->get_playlistCollection(&m_spPC);{hr = m_spMC->add(dlg.m_bstrURL, &spMedia);}if(SUCCEEDED(hr) && (spMedia.p != NULL)){hr = spMedia->getItemInfo(CComBSTR(_T("MediaType")), &bstrMediaType); hr = m_spPlayer->put_currentMedia(spMedia); double time =0.0f; if(hr ==S_OK) hr =spMedia->get_duration(&time); // Based on the media type, return different media type as return code// So the main dialog can update different node in the tree viewUSES_CONVERSION;/*if(SUCCEEDED(hr) && (bstrMediaType.m_str != NULL)){iRetCode = TellMediaType(OLE2T(bstrMediaType));}else{iRetCode = INVALID;}*/}//////////////////////////double time=0.0;CComPtr sMedia; spControls->play();WMPOpenState pwmpos;if(m_spPlayer->get_openState(&pwmpos)==S_OK)hrs =sMediaCur->get_duration(&time); int i=0; } }