Шаг 1. Объявление класса CPlayer
Этот раздел является шагом 1 руководства Воспроизведение файлов мультимедиа с помощью Media Foundation. Полный код показан в разделе Пример воспроизведения сеанса мультимедиа.
В этом руководстве функции воспроизведения инкапсулируются в CPlayer
классе . Класс CPlayer
объявляется следующим образом:
const UINT WM_APP_PLAYER_EVENT = WM_APP + 1;
// WPARAM = IMFMediaEvent*, WPARAM = MediaEventType
enum PlayerState
{
Closed = 0, // No session.
Ready, // Session was created, ready to open a file.
OpenPending, // Session is opening a file.
Started, // Session is playing a file.
Paused, // Session is paused.
Stopped, // Session is stopped (ready to play).
Closing // Application has closed the session, but is waiting for MESessionClosed.
};
class CPlayer : public IMFAsyncCallback
{
public:
static HRESULT CreateInstance(HWND hVideo, HWND hEvent, CPlayer **ppPlayer);
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID iid, void** ppv);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
// IMFAsyncCallback methods
STDMETHODIMP GetParameters(DWORD*, DWORD*)
{
// Implementation of this method is optional.
return E_NOTIMPL;
}
STDMETHODIMP Invoke(IMFAsyncResult* pAsyncResult);
// Playback
HRESULT OpenURL(const WCHAR *sURL);
HRESULT Play();
HRESULT Pause();
HRESULT Stop();
HRESULT Shutdown();
HRESULT HandleEvent(UINT_PTR pUnkPtr);
PlayerState GetState() const { return m_state; }
// Video functionality
HRESULT Repaint();
HRESULT ResizeVideo(WORD width, WORD height);
BOOL HasVideo() const { return (m_pVideoDisplay != NULL); }
protected:
// Constructor is private. Use static CreateInstance method to instantiate.
CPlayer(HWND hVideo, HWND hEvent);
// Destructor is private. Caller should call Release.
virtual ~CPlayer();
HRESULT Initialize();
HRESULT CreateSession();
HRESULT CloseSession();
HRESULT StartPlayback();
// Media event handlers
virtual HRESULT OnTopologyStatus(IMFMediaEvent *pEvent);
virtual HRESULT OnPresentationEnded(IMFMediaEvent *pEvent);
virtual HRESULT OnNewPresentation(IMFMediaEvent *pEvent);
// Override to handle additional session events.
virtual HRESULT OnSessionEvent(IMFMediaEvent*, MediaEventType)
{
return S_OK;
}
protected:
long m_nRefCount; // Reference count.
IMFMediaSession *m_pSession;
IMFMediaSource *m_pSource;
IMFVideoDisplayControl *m_pVideoDisplay;
HWND m_hwndVideo; // Video window.
HWND m_hwndEvent; // App window to receive events.
PlayerState m_state; // Current state of the media session.
HANDLE m_hCloseEvent; // Event to wait on while closing.
};
Ниже приведены некоторые моменты, которые следует отметить.CPlayer
- Константная WM_APP_PLAYER_EVENT определяет сообщение частного окна. Это сообщение используется для уведомления приложения о событиях сеанса мультимедиа. См . раздел Шаг 5. Обработка событий сеанса мультимедиа.
- Перечисление
PlayerState
определяет возможные состоянияCPlayer
объекта . - Класс
CPlayer
реализует интерфейс IMFAsyncCallback , который используется для получения уведомлений о событиях из сеанса мультимедиа. - Конструктор
CPlayer
является частным. Приложение вызывает статическийCreateInstance
метод для создания экземпляраCPlayer
класса . - Деструктор
CPlayer
также является частным. КлассCPlayer
реализует IUnknown, поэтому время существования объекта контролируется с помощью счетчика ссылок (m_nRefCount). Чтобы уничтожить объект, приложение вызывает IUnknown::Release, а не delete. - Объект
CPlayer
управляет сеансом мультимедиа и источником мультимедиа.
Реализация IUnknown
Класс CPlayer
реализует IMFAsyncCallback, который наследует IUnknown.
Приведенный здесь код представляет собой довольно стандартную реализацию IUnknown. При желании для реализации этих методов можно использовать библиотеку активных шаблонов (ATL).
CPlayer
Однако не поддерживает CoCreateInstance или какие-либо расширенные функции COM, поэтому здесь нет никаких причин для использования ATL.
HRESULT CPlayer::QueryInterface(REFIID riid, void** ppv)
{
static const QITAB qit[] =
{
QITABENT(CPlayer, IMFAsyncCallback),
{ 0 }
};
return QISearch(this, qit, riid, ppv);
}
ULONG CPlayer::AddRef()
{
return InterlockedIncrement(&m_nRefCount);
}
ULONG CPlayer::Release()
{
ULONG uCount = InterlockedDecrement(&m_nRefCount);
if (uCount == 0)
{
delete this;
}
return uCount;
}
Далее: Шаг 2. Создание объекта CPlayer
Связанные темы