HGE中的视频播放
HGE的确是2D游戏开发的利器,不过并不是所有东西它都给你提供好了,比如中文输入显示,视频播放等。中文输入显示已经在之前谈过,视频播放则可通过微软的DirectShow库进行开发。网上讲游戏中视频播放大多是用DirectShow建ddraw表面,但HGE底层使用的是D3D,所以我们需要一种更简便的方法。<br/> 其实MSDN中有个在win32应用程序中播放视频的例子已展示了如何使用dshow播放视频,只需要取得窗口句柄,初始化各种com接口,很简单的。HGE里取得窗口句柄可以用HWND hwnd = hge->System_GetState(HGE_HWND)。这样我封装了一个VideoManager类进行视频播放管理。<br/>//VideoManager.h<br/><br/>#include <hge.h><br/>#include <dshow.h><br/><br/>//视频管理类<br/>class VideoManager<br/>{<br/>public:<br/> VideoManager();<br/> ~VideoManager();<br/><br/> void Init(); //初始化<br/> void Release(); //释放资源<br/> <br/> void PlayFile(const WCHAR* filename); //加载视频<br/> void Play(); //播放<br/> void Pause(); //暂停<br/> void Stop(); //停止 <br/><br/> bool IsPlaying()const { return m_bIsPlaying;} //释放正在播放<br/> void SetContinuePlay(bool value) { m_bIsContinuePlay=value; }<br/> bool HandleEvent(); //消息处理<br/>private:<br/> HGE* m_phge;<br/> IGraphBuilder* m_pGraph;<br/> IMediaControl* m_pMediaControl;<br/> IMediaEventEx* m_pEvent;<br/> HWND m_hwnd;<br/> IVideoWindow* m_pVidWin;<br/><br/> bool m_bIsPlaying; //是否在播放<br/> bool m_bIsContinuePlay; //是否持续播放(不间断)<br/>};<br/> <br/><br/>#include "stdafx.h"<br/>#include "VideoManager.h"<br/><br/>#define WM_GRAPHNOTIFY WM_APP + 1<br/><br/><br/>VideoManager::VideoManager()<br/>{ <br/> m_bIsPlaying = false;<br/> m_phge = 0;<br/> m_pGraph = 0;<br/> m_pMediaControl = 0;<br/> m_pEvent = 0; <br/> m_pVidWin = 0;<br/> m_bIsContinuePlay = false;<br/>}<br/><br/>VideoManager::~VideoManager()<br/>{ <br/>}<br/><br/>//初始化<br/>void VideoManager::Init()<br/>{<br/> m_phge = hgeCreate(HGE_VERSION);<br/> m_hwnd = m_phge->System_GetState(HGE_HWND); <br/>}<br/><br/>//释放资源<br/>void VideoManager::Release()<br/>{<br/> m_pGraph->QueryInterface(IID_IVideoWindow, (void **)&m_pVidWin);<br/> m_pVidWin->put_Visible(OAFALSE);<br/> m_pVidWin->put_Owner(NULL);<br/><br/> // Stop the graph.<br/> m_pMediaControl->Stop(); <br/><br/> long evCode;<br/> m_pEvent->WaitForCompletion(INFINITE, &evCode);<br/><br/> if(m_pMediaControl) m_pMediaControl->Release();<br/> if(m_pEvent) m_pEvent->Release();<br/> if(m_pGraph) m_pGraph->Release();<br/><br/> m_pGraph = NULL;<br/> m_pVidWin = NULL;<br/> m_pMediaControl = NULL;<br/> m_pEvent = NULL;<br/>}<br/><br/>//加载视频<br/>void VideoManager::PlayFile(const WCHAR* filename)<br/>{ <br/> Stop();<br/><br/> m_pGraph->RenderFile(filename,NULL);<br/><br/> RECT rc;<br/> GetClientRect(m_hwnd, &rc);<br/> m_pVidWin->SetWindowPosition(0, 0, rc.right, rc.bottom);<br/> m_pVidWin->put_Owner((OAHWND)m_hwnd); <br/> m_pVidWin->put_WindowStyle( WS_CHILD | WS_CLIPSIBLINGS);<br/> <br/> Play();<br/>}<br/><br/>//播放视频<br/>void VideoManager::Play()<br/>{<br/> if(m_pMediaControl)<br/> {<br/> m_pMediaControl->Run();<br/> m_bIsPlaying = true; <br/><br/> if(m_bIsContinuePlay)<br/> {<br/> long evCode;<br/> m_pEvent->WaitForCompletion(INFINITE, &evCode); //强制持续播放(不接受其他消息)<br/> m_bIsPlaying = false;<br/> }<br/> }<br/>}<br/><br/>//暂停<br/>void VideoManager::Pause()<br/>{<br/> if(m_pMediaControl) m_pMediaControl->Pause();<br/>}<br/><br/>//停止<br/>void VideoManager::Stop()<br/>{<br/> if(m_pMediaControl)<br/> {<br/> m_pMediaControl->Stop();<br/> m_pMediaControl->Release();<br/> m_bIsPlaying = false;<br/> }<br/> if(m_pEvent) m_pEvent->Release();<br/> if(m_pGraph) m_pGraph->Release();<br/> if(m_pVidWin) m_pVidWin->Release();<br/><br/> CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&m_pGraph);<br/><br/> m_pGraph->QueryInterface(IID_IVideoWindow, (void **)&m_pVidWin); <br/> m_pGraph->QueryInterface(IID_IMediaEventEx, (void **)&m_pEvent);<br/> m_pEvent->SetNotifyWindow((OAHWND)m_hwnd, WM_GRAPHNOTIFY, 0);<br/> <br/> m_pGraph->QueryInterface(IID_IMediaControl, (void **)&m_pMediaControl); <br/>}<br/><br/>//消息处理<br/>bool VideoManager::HandleEvent()<br/>{<br/> long evCode, param1, param2;<br/> HRESULT hr;<br/> while (hr = m_pEvent->GetEvent(&evCode, &param1, &param2, 0), SUCCEEDED(hr))<br/> {<br/> hr = m_pEvent->FreeEventParams(evCode, param1, param2);<br/> if ((EC_COMPLETE == evCode) || (EC_USERABORT == evCode))<br/> { <br/> Stop(); <br/> break;<br/> }<br/> }<br/> return false;<br/>}<br/> <br/><br/>使用时就先初始化,然后播放,最后释放。可以使用IsPlaying()判断视频是否正在播放,若是则不绘制其他东西;但是有个问题就是若正在播放视频时还每次进行逻辑检测,则会使视频画面不连贯较卡;一般来说游戏播放视频时是不能打断的,所以可以在m_pMediaControl->Run()后加上m_pEvent->WaitForCompletion来强制连续播放,直到视频结束。<br/> 请问那个播放视频函数要怎么用啊,关键那个实参不会填啊,你的形参是16位的unicode字符....为什么不用普遍一点的ASCii编码呢
页:
[1]