📄 mediacontrol.cpp
字号:
#include "StdAfx.h"
#include "MediaControl.h"
CMediaControl::CMediaControl(void)
{
//DSHOW init
m_pGB=NULL;
m_pMC=NULL;
m_pME=NULL;
m_pVW=NULL;
m_pBA=NULL;
m_pBV=NULL;
m_pMS=NULL;
//COM init
CoInitialize(NULL);
}
CMediaControl::~CMediaControl(void)
{
UnInitDShow();
CoUninitialize();
}
BOOL CMediaControl::InitDShow(LPCTSTR strFileName,//视频文件名
HWND hOwnerWnd,//显示视频的窗口句柄
HWND hNotifyWnd)//接收DSHOW事件的串口句柄
{
HRESULT hResult;
//第一步,创建IGraphBuilder接口
hResult = CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC,
IID_IGraphBuilder,(void **)&m_pGB);
if(hResult != S_OK)
{
return FALSE;
}
//第二步,利用IGraphBuilder渲染视频文件
hResult = m_pGB->RenderFile(strFileName,NULL);
if(hResult != S_OK)
{
if(hResult == VFW_S_PARTIAL_RENDER)
{
TRACE(L"Some of the streams in this movie are in an unsupported format.\n");
}
else if(hResult == VFW_S_AUDIO_NOT_RENDERED)
{
TRACE(L"Partial success;the audio was not rendered.\n");
}
else if(hResult == VFW_S_DUPLICATE_NAME)
{
TRACE(L"Success;the Filter Graph Manager modified the filter name to avoid duplication..\n");
}
else if(hResult == VFW_VIDEO_NOT_RENDERED)
{
TRACE(L"Partial success;Some of the streams in this movie are in an unsupported format.\n");
}
else
{
UnInitDShow();
return FALSE;
}
}
//第三步,得到媒体播放控制接口
hResult = m_pGB->QueryInterface(IID_IMediaControl,(void **)&m_pMC);
if(hResult != S_OK)
{
UnInitDShow();
return FALSE;
}
//第四步,得到媒体播放位置搜索接口
hResult = m_pGB->QueryInterface(IID_IMediaSeeking,(void **)&m_pMS);
if(hResult != S_OK)
{
UnInitDShow();
return FALSE;
}
//设置查找定位的时间单位,这里设置:100纳秒(十亿分之一)
GUID guid_timeFormat = TIME_FORMAT_MEDIA_TIME;
m_pMS->SetTimeFormat(&guid_timeFormat);
//第五步,得到媒体播放事件接口
hResult = m_pGB->QueryInterface(IID_IMediaEventEx,(void **)&m_pME);
if(hResult != S_OK)
{
UnInitDShow();
return FALSE;
}
//设置媒体事件通知消息窗口
m_pME->SetNotifyWindow((OAHWND)hNotifyWnd,WM_GRAPHNOTIFY,0);
//第六步,得到视频播放窗口接口
hResult = m_pGB->QueryInterface(IID_IVideoWindow,(void **)&m_pVW);
if(hResult != S_OK)
{
UnInitDShow();
return FALSE;
}
m_pVW->put_Owner((OAHWND)hOwnerWnd);//设置视频窗口句柄
m_pVW->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN);
//第七步,得到基础视频流接口
hResult = m_pGB->QueryInterface(IID_IBasicVideo,(void **)&m_pBV);
if(hResult != S_OK)
{
UnInitDShow();
return FALSE;
}
//第八步,得到基础音频流接口
hResult = m_pGB->QueryInterface(IID_IBasicAudio,(void **)&m_pBA);
if(hResult != S_OK)
{
UnInitDShow();
return FALSE;
}
return TRUE;
}
BOOL CMediaControl::UnInitDShow()
{//1
if(m_pMC != NULL)
{
m_pMC->Stop();
m_pMC->Release();
m_pMC = NULL;
}
//2
if(m_pME != NULL)
{
m_pME->SetNotifyWindow(NULL,0,0);
m_pME->Release();
m_pME = NULL;
}
//3
if(m_pVW != NULL)
{
m_pVW->put_Visible(OAFALSE);
m_pVW->put_Owner(NULL);
m_pVW->Release();
m_pVW = NULL;
}
//4
if(m_pBA != NULL)
{
m_pBA->Release();
m_pBA = NULL;
}
//5
if(m_pBV != NULL)
{
m_pBV->Release();
m_pBV = NULL;
}
//6
if(m_pMS != NULL)
{
m_pMS->Release();
m_pMS = NULL;
}
//7
if(m_pGB != NULL)
{
m_pGB->Release();
m_pGB = NULL;
}
return TRUE;
}
BOOL CMediaControl::OpenFile(LPCTSTR strFileName,HWND hOwnerWnd,HWND hNotifyWnd)
{
//存储显示视频窗口句柄
m_hOwnerWnd = hOwnerWnd;
//重置DShow接口
UnInitDShow();
//打开视频文件,并对DShow接口做初始化
return InitDShow(strFileName,hOwnerWnd,hNotifyWnd);
}
BOOL CMediaControl::VideoRun()
{
//检测IMediaControl接口有效性
if(m_pMC == NULL)
{
return FALSE;
}
//播放视频
HRESULT hResult = m_pMC->Run();
if(hResult != S_OK)
{
return FALSE;
}
return TRUE;
}
BOOL CMediaControl::VideoPause()
{
if(m_pMC == NULL)
{
return FALSE;
}
//播放视频
HRESULT hResult = m_pMC->Pause();
if(hResult != S_OK)
{
return FALSE;
}
return TRUE;
}
BOOL CMediaControl::VideoStop()
{
if(m_pMC == NULL)
{
return FALSE;
}
//播放视频
HRESULT hResult = m_pMC->Stop();
if(hResult != S_OK)
{
return FALSE;
}
//将当前播放位置置0
LONGLONG pos=0;
hResult = m_pMS->SetPositions(&pos,AM_SEEKING_AbsolutePositioning,
NULL,AM_SEEKING_NoPositioning);
return TRUE;
}
//设置视频显示比例
BOOL CMediaControl::FitVideoWindow(FLOAT fScale)
{
LONG lHeight,lWidth;
int iSeek = 0;
double dblScaleX,dblScaleY;
HRESULT hr = S_OK;
LONG lDeflateX = 0;
LONG lDeflateY = 0;
CRect clientRect;
CRect dstRect;
if(m_pBV == NULL)
{
return FALSE;
}
if(fScale>1.0)
{
return FALSE;
}
//得到原始视频尺寸
hr = m_pBV->GetVideoSize(&lHeight,&lWidth);
if(hr != S_OK)
{
return FALSE;
}
//设置拉伸后的尺寸
lHeight = lHeight*fScale;
lWidth = lWidth*fScale;
//得到视频播放窗口的尺寸
GetClientRect(m_hOwnerWnd,&clientRect);
lDeflateX = (clientRect.Width()-clientRect.Width()*fScale)/2;
lDeflateY = (clientRect.Height()-clientRect.Height()*fScale)/2;
//重新设置客户区域
clientRect.DeflateRect(lDeflateX,lDeflateY);
if((lWidth <= clientRect.Width())&&(lHeight<=clientRect.Height()))
{
dstRect.left=(clientRect.right-clientRect.left-lWidth)/2;
dstRect.right=dstRect.left+lWidth;
dstRect.top=(clientRect.bottom-clientRect.top-lHeight)/2;
dstRect.bottom=dstRect.top+lHeight;
}
else
{
dblScaleX = double(clientRect.Width())/double(lWidth);
dblScaleY = double(clientRect.Height())/double(lHeight);
if(dblScaleX<=dblScaleY)
{
dstRect.left=clientRect.left;
dstRect.right=clientRect.right;
iSeek =(clientRect.Height()-clientRect.Width()*(double(lHeight)/double(lWidth)))/2;
dstRect.top=clientRect.top+iSeek;
dstRect.bottom=dstRect.top+clientRect.Width()*(double(lHeight)/double(lWidth));
}
else
{
dstRect.top=clientRect.top;
dstRect.bottom=clientRect.bottom;
iSeek=(clientRect.Width()-clientRect.Height()*(double(lWidth)/double(lHeight)))/2;
dstRect.left=clientRect.left+iSeek;
dstRect.right=dstRect.left+clientRect.Height()*(double(lWidth)/double(lHeight));
}
}
//设置视频播放位置
m_pVW->SetWindowPosition(dstRect.left,dstRect.top,dstRect.Width(),dstRect.Height());
return true;
}
//全屏显示
BOOL CMediaControl::FullScreen()
{
LONG lMode=0;
static HWND hDrain=0;
if(m_pBV==NULL)
{
return FALSE;
}
//得到全屏状态
m_pVW->get_FullScreenMode(&lMode);
if(lMode == OAFALSE)
{
//save current message drain
m_pVW->get_MessageDrain((OAHWND *)&hDrain);
//set message drain to application main window
m_pVW->put_MessageDrain((OAHWND)m_hOwnerWnd);
//设置全屏
lMode = OATRUE;
m_pVW->put_FullScreenMode(lMode);
}
else
{
//切换到非全屏模式
lMode = OAFALSE;
m_pVW->put_FullScreenMode(lMode);
//undo change of message drain
m_pVW->put_MessageDrain((OAHWND )hDrain);
//reset video window
FitVideoWindow(1);
m_pVW->SetWindowForeground(-1);
}
return TRUE;
}
//得到是否全屏播放
BOOL CMediaControl::GetFullScreenStatus()
{
LONG lMode=0;
if(m_pBV==NULL)
{
return FALSE;
}
m_pVW->get_FullScreenMode(&lMode);
if(lMode == OAFALSE)
{
return FALSE;
}
else
{
return TRUE;
}
}
//得到媒体事件
BOOL CMediaControl::GetMediaEvent(long *lEventCode)
BOOL CMediaControl::SetPositions(DWORD dwPos)
BOOL CMediaControl::GetCurrentPos(DWORD &dwPos)
BOOL CMediaControl::GetDuration(DWORD &dwLength)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -