# pragma once # include # include # include "utility/com_ptr.h" # include "utility/optional.h" class MediaPlayer; typedef void (*MediaPlayerEventCallback)(MediaPlayer* player, com_ptr, MediaEventType); class MediaPlayer: private IMFAsyncCallback { public: enum State { Closed = 0, // no session Ready, // session was created, ready to open file OpenPending, // session is opening a file Started, // session is playing a file Paused, // session is paused Stopped, // session is stopped (but ready to play) Closing // session was closed, waiting for async callback }; static HRESULT Create(MediaPlayerEventCallback eventCallback, MediaPlayer** outMediaPlayer); // IUnknown virtual ULONG STDMETHODCALLTYPE AddRef() override; virtual ULONG STDMETHODCALLTYPE Release() override; virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** object) override; HRESULT OpenURL(const wchar_t* url); HRESULT Play(); HRESULT Pause(); HRESULT Stop(); HRESULT Shutdown(); State GetState() const; void SetMasterVolume(float volume); float GetMasterVolume() const; void SetReplayGain(float replayGain); float GetReplayGain() const; optional GetPresentationTime() const; optional GetDuration() const; void SetUserData(void* userData); void* GetUserData() const; HRESULT HandleEvent(IMFMediaEvent* mediaEvent); protected: MediaPlayer(MediaPlayerEventCallback eventCallback); virtual ~MediaPlayer(); HRESULT Initialize(); HRESULT CreateSession(); HRESULT CloseSession(); HRESULT StartPlayback(); HRESULT ApplyTopology(); HRESULT ApplyMasterVolume(float volume); HRESULT ApplyReplayGain(float replayGain); const com_ptr& GetMediaSession() const { return m_MediaSession; } const com_ptr& GetMediaSource() const { return m_MediaSource; } virtual HRESULT OnTopologyStatus(IMFMediaEvent* mediaEvent); virtual HRESULT OnPresentationEnded(IMFMediaEvent* mediaEvent); virtual HRESULT OnNewPresentation(IMFMediaEvent* mediaEvent); // Override to handle additional session events. virtual HRESULT OnSessionEvent(IMFMediaEvent* mediaEvent, MediaEventType mediaEventType); virtual HRESULT OnStateChange(State state, State previousState); private: // IMFAsyncCallback virtual HRESULT STDMETHODCALLTYPE GetParameters(DWORD* flags, DWORD* queue); virtual HRESULT STDMETHODCALLTYPE Invoke(IMFAsyncResult* asyncResult); HRESULT SetState(State state); ULONG m_RefCount; com_ptr m_SourceResolver; com_ptr m_CancelCookie; com_ptr m_MediaSession; com_ptr m_MediaSource; com_ptr m_SimpleAudioVolume; com_ptr m_PresentationClock; com_ptr m_StreamAudioVolume; optional m_SetMasterVolume; mutable float m_MasterVolume; mutable float m_ReplayGain; MediaPlayerEventCallback m_EventCallback; void* m_UserData; State m_State; HANDLE m_CloseEvent; };