#ifndef __PlayVedioH__
#define __PlayVedioH__
#include <new>
#include <windows.h>
#include <windowsx.h>
#include <mfplay.h>
#include <mferror.h>
#include <shobjidl.h>
#include <strsafe.h>
#include <Shlwapi.h>
#pragma comment(linker, \
"\"/manifestdependency:type='Win32' "\
"name='Microsoft.Windows.Common-Controls' "\
"version='6.0.0.0' "\
"processorArchitecture='*' "\
"publicKeyToken='6595b64144ccf1df' "\
"language='*'\"")
class MediaPlayerCallback : public IMFPMediaPlayerCallback
{
private:
long m_cRef;
IMFPMediaPlayer* m_pPlayer;
BOOL m_bHasVideo;
public:
MediaPlayerCallback() : m_cRef(1) {}
STDMETHODIMP QueryInterface(REFIID riid, void** ppv)
{
static const QITAB qit[] =
{
QITABENT(MediaPlayerCallback, IMFPMediaPlayerCallback),
{ 0 },
};
return QISearch(this, qit, riid, ppv);
}
STDMETHODIMP_(ULONG) AddRef()
{
return InterlockedIncrement(&m_cRef);
}
STDMETHODIMP_(ULONG) Release()
{
ULONG count = InterlockedDecrement(&m_cRef);
if (count == 0)
{
delete this;
return 0;
}
return count;
}
void STDMETHODCALLTYPE OnMediaPlayerEvent(MFP_EVENT_HEADER *pEventHeader)
{
switch (pEventHeader->eEventType)
{
case MFP_EVENT_TYPE_MEDIAITEM_CREATED:
OnMediaItemCreated(MFP_GET_MEDIAITEM_CREATED_EVENT(pEventHeader));
break;
case MFP_EVENT_TYPE_MEDIAITEM_SET:
OnMediaItemSet(MFP_GET_MEDIAITEM_SET_EVENT(pEventHeader));
break;
}
}
void OnMediaItemCreated(MFP_MEDIAITEM_CREATED_EVENT *pEvent);
void OnMediaItemSet(MFP_MEDIAITEM_SET_EVENT *pEvent);
void Set(IMFPMediaPlayer* pPlayer, BOOL bHasVideo)
{
m_pPlayer = pPlayer;
m_bHasVideo = bHasVideo;
}
BOOL IsHasVideo() { return m_bHasVideo; }
};
void MediaPlayerCallback::OnMediaItemCreated(MFP_MEDIAITEM_CREATED_EVENT *pEvent)
{
if(m_pPlayer)
{
BOOL bHasVideo = FALSE;
BOOL bIsSelected = FALSE;
if(SUCCEEDED(pEvent->pMediaItem->HasVideo(&bHasVideo, &bIsSelected)))
{
m_bHasVideo = bHasVideo && bIsSelected;
m_pPlayer->SetMediaItem(pEvent->pMediaItem);
}
}
}
void MediaPlayerCallback::OnMediaItemSet(MFP_MEDIAITEM_SET_EVENT * /*pEvent*/)
{
m_pPlayer->Play();
}
class CPlayVideo
{
private:
HWND m_hWnd;
IMFPMediaPlayer* m_pPlayer;
MediaPlayerCallback* m_pPlayerCB;
BOOL m_bHasVideo;
public:
CPlayVideo() { HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0); CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); }
~CPlayVideo() { if(m_pPlayer) m_pPlayer->Release(); if(m_pPlayerCB) m_pPlayerCB->Release(); CoUninitialize(); }
void Init(HWND hWnd);
void StartPlay(WCHAR* wsURL);
void Play();
void Render();
void Pause();
void Stop();
void ShutDown();
};
void CPlayVideo::Init(HWND hWnd)
{
m_hWnd = hWnd;
}
void CPlayVideo::StartPlay(WCHAR* wsURL)
{
if(m_pPlayer == NULL)
{
m_pPlayerCB = new (std::nothrow) MediaPlayerCallback();
MFPCreateMediaPlayer(NULL, FALSE, 0, m_pPlayerCB, m_hWnd, &m_pPlayer);
m_pPlayerCB->Set(m_pPlayer, m_bHasVideo);
}
m_pPlayer->CreateMediaItemFromURL(wsURL, FALSE, 0, NULL);
m_bHasVideo = m_pPlayerCB->IsHasVideo();
}
void CPlayVideo::Play()
{
if(m_pPlayer) m_pPlayer->Play();
}
void CPlayVideo::Render()
{
PAINTSTRUCT ps;
HDC hdc = 0;
hdc = BeginPaint(m_hWnd, &ps);
if(m_pPlayer && m_bHasVideo)
{
m_pPlayer->UpdateVideo();
}
else
{
FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));
}
EndPaint(m_hWnd, &ps);
}
void CPlayVideo::Pause()
{
if(m_pPlayer) m_pPlayer->Pause();
}
void CPlayVideo::Stop()
{
if(m_pPlayer) m_pPlayer->Stop();
}
void CPlayVideo::ShutDown()
{
m_pPlayer->Shutdown();
}
#endif
//以下为使用示意
//#include "PlayVideo.h"
//BOOL InitializeWindow(HWND *pHwnd);
//LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
//CPlayVideo PlayVideo;
//INT WINAPI wWinMain(HINSTANCE,HINSTANCE,LPWSTR,INT)
//{
// HWND hwnd = 0;
// MSG msg = {0};
// InitializeWindow(&hwnd);
// PlayVideo.Init(hwnd);
// while(msg.message != WM_QUIT)
// {
// if(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
// {
// TranslateMessage(&msg);
// DispatchMessageA(&msg);
// }
// else PlayVideo.Render();
// }
// PlayVideo.ShutDown();
// return 0;
//}
//LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
//{
// if(uMsg == WM_KEYDOWN && wParam == VK_SPACE)
// {
// static BOOL bPlayed = TRUE;
// if(bPlayed) bPlayed = FALSE;
// else bPlayed = TRUE;
// if(bPlayed) PlayVideo.Play();
// else PlayVideo.Pause();
// }
// if(uMsg == WM_KEYDOWN && wParam == VK_RETURN)
// {
// static WCHAR wsURL1[] = L"F:/TDDOWNLOAD/第14集.mp4";
// static WCHAR wsURL2[] = L"F:/TDDOWNLOAD/第11集.mp4";
// static int nIndex = 1;
// nIndex = 3 - nIndex;
// if(nIndex == 1) PlayVideo.StartPlay(wsURL1);
// else PlayVideo.StartPlay(wsURL2);
// }
// if(uMsg == WM_KEYDOWN && wParam == VK_ESCAPE)
// {
// PostQuitMessage(0);
// }
// return DefWindowProc(hwnd, uMsg, wParam, lParam);
//}
//BOOL InitializeWindow(HWND *pHwnd)
//{
// const WCHAR CLASS_NAME[] = L"MFPlay Window Class";
// const WCHAR WINDOW_NAME[] = L"MFPlay Sample Application";
// WNDCLASS wc = {0};
// wc.lpfnWndProc = WindowProc;
// wc.hInstance = GetModuleHandle(NULL);
// wc.hCursor = LoadCursor(NULL, IDC_ARROW);
// wc.lpszClassName = CLASS_NAME;
// wc.lpszMenuName = 0;
// RegisterClass(&wc);
// HWND hwnd = CreateWindow(CLASS_NAME, WINDOW_NAME, WS_OVERLAPPED, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, GetModuleHandle(NULL), NULL);
// ShowWindow(hwnd, SW_SHOWDEFAULT);
// UpdateWindow(hwnd);
// *pHwnd = hwnd;
// return TRUE;
//}