⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 videoplay.cpp

📁 VC++视频开发实例集锦(包括“远程视频监控”"语音识别系统"等13个经典例子)
💻 CPP
字号:
// VideoPlay.cpp: implementation of the CVideoPlay class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "VideoPlay.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CVideoPlay::CVideoPlay(HWND hwnd)
{
   
   pigb  = NULL;
   pimc  = NULL;
   pimex = NULL;
   pivw  = NULL;
   pmp   = NULL;
   pVCap = NULL;
   CappFg = NULL;
   CapPigb = NULL;
   m_hwnd=hwnd;


}

CVideoPlay::~CVideoPlay()
{
  HELPER_RELEASE(pivw);
  HELPER_RELEASE(pigb);
  HELPER_RELEASE(pimc);
  HELPER_RELEASE(pimex);
  HELPER_RELEASE(pmp);
  HELPER_RELEASE(CapPigb);
  HELPER_RELEASE(CappFg);
  HELPER_RELEASE(pVCap);

}

//实时捕捉图像的播放
void CVideoPlay::RealPlay()
{
	HRESULT hr;
 
	//创建捕捉过滤器图表
	CHECK_ERROR(CoCreateInstance((REFCLSID)CLSID_CaptureGraphBuilder,NULL,
				CLSCTX_INPROC, (REFIID)IID_ICaptureGraphBuilder,(void **)&CapPigb),
				"CoCreateInstance Error");
  
	//创建过滤器图表
	CHECK_ERROR(hr=CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,
		        IID_IGraphBuilder, (LPVOID *)&CappFg),"Cannot instantiate filtergraph");

	//将捕捉过滤器图表和过滤器图表进行关联
	hr = CapPigb->SetFiltergraph(CappFg);
	if (hr != NOERROR)
	{
    	MessageBox(m_hwnd,"Cannot give graph to builder","Error",MB_OK);
        return;
	}
	int uIndex=0;
	//创建视频设备枚举器
	ICreateDevEnum *pCreateDevEnum;
	hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
			  IID_ICreateDevEnum, (void**)&pCreateDevEnum);
	//创建一个类型枚举器,指向系统的视频设备列表
	IEnumMoniker *pEm;
	hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
								&pEm, 0);
	HELPER_RELEASE(pCreateDevEnum);
	pEm->Reset();
	ULONG cFetched;
	IMoniker *pM;
	//枚举每个视频设备
	while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
    {
		//生成并初始化管理该设备的过滤器
		hr = pM->BindToObject(0, 0, IID_IBaseFilter, (void**)&pVCap);
		if(pVCap== NULL) 
		{
		    MessageBox(m_hwnd,"Cannot get the capture filterr","Error",MB_OK);
			return;
		}
		HELPER_RELEASE(pM);
		uIndex++;
    }
	HELPER_RELEASE(pEm);
	
	if(pVCap)
		hr = CappFg->AddFilter(pVCap, NULL); //添加过滤器到Filter Graph中
	if (hr != NOERROR) 
	{
    	MessageBox(m_hwnd,"Cannot add vidcap to filtergraph","Error",MB_OK);
		return;
	}
	//连接源过滤器和提交过滤器
	hr = CapPigb->RenderStream(&PIN_CATEGORY_PREVIEW,pVCap,NULL, NULL);
	if (hr != S_OK)
	{
	    MessageBox(m_hwnd,"This graph cannot preview properly","Error",MB_OK);
		return;
	}
	//在过滤器图表中查找一个与捕捉有关的接口
    hr = CapPigb->FindInterface(&PIN_CATEGORY_PREVIEW,pVCap,IID_IVideoWindow,(void **)&pivw);
    if (hr != NOERROR) 
	{
      	MessageBox(m_hwnd,"cannot find Video Window properly","Error",MB_OK);
		return;
    
	} 
	else 
	{
		DisplayVideoWin(); //显示视频播放窗口
  	}
	//查询数据流控制接口
    hr =CappFg->QueryInterface(IID_IMediaControl, (void **)&pimc);
    if (SUCCEEDED(hr)) 
	{
	   hr = pimc->Run(); //播放视频
	 	 
	}
	else
	{
        MessageBox(m_hwnd,"Cannot run preview graph","Error",MB_OK);
	    return;
	} 
 
}

//显示视频播放窗口
void CVideoPlay::DisplayVideoWin()
{
	RECT grc;
    if(pivw)
	{
		//设置窗口所有者
		pivw->put_Owner((OAHWND)m_hwnd);
		//设置窗口尺寸
	    pivw->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN);
		//设置窗口位置
        ::GetClientRect(m_hwnd, &grc);; 
	    pivw->SetWindowPosition(grc.left, grc.top, grc.right, grc.bottom);
		//显示窗口
        pivw->put_Visible(OATRUE);
	}     
}

//停止播放视频
void CVideoPlay::StopPlay()
{
 
    if(pimc)
	{
		//停止播放视频
		pimc->Stop();  
		HELPER_RELEASE(pimc);
	}
	if (pivw)
    {   
		//关闭视频播放窗口
        pivw->put_Visible(OAFALSE);
        pivw->put_Owner(NULL);
        HELPER_RELEASE(pivw);
	}
	HELPER_RELEASE(CapPigb);
    HELPER_RELEASE(CappFg);
    HELPER_RELEASE(pVCap);	

}

//播放视频文件
void CVideoPlay::PlayFromFile(CString szFile)
{
      WCHAR wFile[MAX_PATH];
	  HRESULT   hr;
	  MultiByteToWideChar( CP_ACP, 0, szFile.GetBuffer(_MAX_PATH), -1, wFile, MAX_PATH );
      szFile.ReleaseBuffer();
	  //创建过滤器图表生成器接口
      CHECK_ERROR(::CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
		           IID_IGraphBuilder, (void **)&pigb),"CoCreateInstance Error") ;
	  //查询数据流控制接口
      pigb->QueryInterface(IID_IMediaControl, (void **)&pimc);  
	  //查询过滤器图表事件接口
      hr=pigb->QueryInterface(IID_IMediaEventEx, (void **)&pimex);
	  //查询视频播放窗口接口	
      pigb->QueryInterface(IID_IVideoWindow, (void **)&pivw);
	  //查询数据流位置接口
      hr=pigb->QueryInterface(IID_IMediaPosition, (void**) &pmp);

      //为指定的多媒体文件创建一个过滤器图表进行处理
      hr = pigb->RenderFile(wFile, NULL);
	  //得到视频文件的播放时间
	  if (SUCCEEDED(hr)) 	           
         hr=pmp->get_Duration(&tLength);  

	  //显示视频播放窗口
	  DisplayVideoWin();    
	  if (SUCCEEDED(hr))
         pimc->Run();       //播放视频

	  pimex->SetNotifyWindow((OAHWND)m_hwnd, WM_PLAYOVER, 0);

}

int CVideoPlay::PlayOver()
{
  long evCode,evParam1,evParam2;
  HRESULT   hr;
  if(pimex)
  {
  while (SUCCEEDED(pimex->GetEvent(&evCode, &evParam1, &evParam2, 0)))
      { // Spin through the events
               hr = pimex->FreeEventParams(evCode, evParam1, evParam2);

                if (EC_COMPLETE == evCode)

                  { // Finished

                    if (pivw)

                      { // Relinquish ownership (IMPORTANT!) after hiding

                        pivw->put_Visible(OAFALSE);
                        pivw->put_Owner(NULL);
                        HELPER_RELEASE(pivw);

                      } // Relinquish ownership (IMPORTANT!) after hiding

                 //   HELPER_RELEASE(pif);
                    HELPER_RELEASE(pigb);
                    HELPER_RELEASE(pimc);
                 	HELPER_RELEASE(pmp);
				    HELPER_RELEASE(pimex);
					return 0;
				  break;
				}
   }
  }
  return -1;
}

//继续播放
void CVideoPlay::ResumePlay()
{
 	HRESULT hr; 
	//得到当前播放位置
	hr = pmp->get_CurrentPosition(&tCurrent);
    if (SUCCEEDED(hr)) 
	{
       // 如果已在播放文件的最后(播放时间剩下不到1分钟),当前位置回到文件头
       if ((tRemain=tLength - tCurrent) < 1) 
         pmp->put_CurrentPosition(0);
	   //不在文件尾,当前位置不变
       else
	     pmp->put_CurrentPosition(tCurrent);
    }
    if(pimc)
	  	pimc->Run(); //继续播放文件
}


//暂停播放
void CVideoPlay::PausePlay()
{
	if(pimc)
		pimc->Pause();
}

//搜索视频设备,并返回视频设备名列表
void CVideoPlay::FindDevice(CStringList &DevName)
{
    HRESULT hr;
	int uIndex=0;

	//创建一个系统设备枚举器接口
	ICreateDevEnum *pCreateDevEnum;  
	hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
			  IID_ICreateDevEnum, (void**)&pCreateDevEnum);  

	//创建一个类型枚举器,指向系统的视频设备列表
    IEnumMoniker *pEm;  
    hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
						&pEm, 0);
    HELPER_RELEASE(pCreateDevEnum);
	if(pEm)
	{
		pEm->Reset();
		ULONG cFetched;
		IMoniker *pM;
		//枚举每个视频设备
		while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
		{
			IPropertyBag *pBag;
			hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
			if(SUCCEEDED(hr)) 
			{
				VARIANT var;
				var.vt = VT_BSTR;
				//得到视频设备的友好名称
				hr = pBag->Read(L"FriendlyName", &var, NULL);
				if (hr == NOERROR)
				{
					CString achName;
					WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, achName.GetBuffer(50),80,NULL, NULL);
					achName.ReleaseBuffer();
					//将设备名添加到设备名列表末尾
					DevName.AddTail(achName);		
					SysFreeString(var.bstrVal);
				}
	  			HELPER_RELEASE(pBag);
	  
			}	
			HELPER_RELEASE(pM);
			uIndex++;
		}
   		HELPER_RELEASE(pEm);
	}
}

CVideoPlay::CVideoPlay()
{
   pigb  = NULL;
   pimc  = NULL;
   pimex = NULL;
   pivw  = NULL;
   pmp   = NULL;
   pVCap = NULL;
   CappFg = NULL;
   CapPigb = NULL;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -