MFPlayは非推奨であり、Media Sessionを使用することとされています。
IMFPMediaPlayer* gPlayer = NULL; // MFPlay playerオブジェクト void OnFileOpen(HWND hWnd) { WCHAR pwszURL[] = L"C:\\sample.wmv"; BOOL fStartPlayback = TRUE; MFP_CREATION_OPTIONS creationOptions = 0; HRESULT hr = MFPCreateMediaPlayer(pwszURL, fStartPlayback, creationOptions, NULL, hWnd, &gPlayer); } void OnClose(HWND /*hWnd*/) { if (gPlayer) { gPlayer->Shutdown(); gPlayer->Release(); gPlayer = NULL; } }Windows-classic-samples/winmain.cpp at master · Microsoft/Windows-classic-samples · GitHub
MFPlayプレーヤーオブジェクトを表します。
MFPlayプレーヤーを作成できます。
HRESULT MFPCreateMediaPlayer( LPCWSTR pwszURL, // Media FileのURLを含む文字列。後で指定するならばNULLでも良い BOOL fStartPlayback, // 自動再生させるならばTRUE MFP_CREATION_OPTIONS creationOptions, // オプション IMFPMediaPlayerCallback *pCallback, // MFPlayのイベント通知を受け取るためのコールバック。イベントを受け取らないならばNULLでも良い HWND hWnd, // 映像を描画するためのウィンドウ。音声だけならばNULLでも良い IMFPMediaPlayer **ppMediaPlayer // 作成されたMFPlayを受け取るためのポインタ );MFPCreateMediaPlayer function | Microsoft Learn
pwszURLをNULLとしたときは、fStartPlaybackをFALSEとしなければなりません。
LPCWSTR pwszURL = L"C:\\sample.wmv";
IMFPMediaPlayer* ppMediaPlayer = NULL;
// 指定ファイルを読み込み再生する
HRESULT hr = MFPCreateMediaPlayer(pwszURL, TRUE, 0, NULL, hWnd, &ppMediaPlayer);
Playing a Media File - Getting Started with MFPlay - Win32 apps | Microsoft Learn
URLからMedia Itemを作成できます。
HRESULT CreateMediaItemFromURL( LPCWSTR pwszURL, // Media FileのURLを含む文字列 BOOL fSync, // 完了までブロックさせ同期して実行させるならばTRUE DWORD_PTR dwUserData, // Media Itemに保管する任意のデータ IMFPMediaItem **ppMediaItem // fSyncがTRUEのときに、Media Itemを受け取るポインタ );IMFPMediaPlayer::CreateMediaItemFromURL | Microsoft Learn
MFPCreateMediaPlayer()の引数のpCallbackをNULLとしてコールバックを受け取らないときは、fSyncをTRUEとしてppMediaItemに有効なポインタを与えます。
この関数はその結果に応じて、下表のような値を返します。
Return code | Description | |
---|---|---|
0x0 | S_OK | The method succeeded. |
0x80004003 | E_POINTER | Invalid pointer.
fSyncをTRUEとしているのに、ppMediaItemに有効なポインタを指定していない |
0x80070057 | E_INVALIDARG | Invalid argument. |
0xC00D36B2 | MF_E_INVALIDREQUEST | Invalid request.
このエラーはfSyncをFALSEとしているのに、MFPCreateMediaPlayer()でコールバックを提供しないときに発生する。 |
0xC00D3E85 | MF_E_SHUTDOWN | The object's Shutdown method was called.
このエラーは、MFStartup()を呼び出していないときにも発生する。 |
0xC00D36C3 | MF_E_UNSUPPORTED_SCHEME | Unsupported protocol. |
再生位置を指定できます。
HRESULT SetPosition(
REFGUID guidPositionType, // 時間の単位。有効な値はMFP_POSITIONTYPE_100NS
const PROPVARIANT *pvPositionValue
);
IMFPMediaPlayer::SetPosition | Microsoft Learn
PROPVARIANT vPositionValue;
PropVariantInit(&vPositionValue);
vPositionValue.vt = VT_I8;
vPositionValue.hVal.QuadPart = 10000000; // 1秒 (10000000[100nsec]) の位置から再生する;
HRESULT hr = gPlayer->SetPosition(
MFP_POSITIONTYPE_100NS,
&vPositionValue
);
PropVariantClear(&vPositionValue);
Media Itemを表します。
Metadataを含むProperty storeを取得できます。
HRESULT GetMetadata( IPropertyStore **ppMetadataStore );IMFPMediaItem::GetMetadata (mfplay.h) | Microsoft Learn
IMFPMediaPlayerCallbackインターフェイスは、IMFPMediaPlayerで発生するイベントを受け取るためのコールバックの定義に用います。
IMFPMediaPlayer* gPlayer = NULL; // MFPlay playerオブジェクト BOOL gHasVideo = FALSE; // 映像を含むならばTRUE class MediaPlayerCallback; MediaPlayerCallback* gPlayerCB = NULL; // コールバック オブジェクト class MediaPlayerCallback : public IMFPMediaPlayerCallback { long mRef; // 参照カウント public: MediaPlayerCallback() : mRef(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(&mRef); } STDMETHODIMP_(ULONG) Release() { ULONG count = InterlockedDecrement(&mRef); if (count == 0) { delete this; return 0; } return count; } void STDMETHODCALLTYPE OnMediaPlayerEvent(MFP_EVENT_HEADER* pEventHeader); }; HRESULT OnMediaItemCreated(MFP_MEDIAITEM_CREATED_EVENT* pEvent) { HRESULT hr = S_OK; if (gPlayer) { BOOL bHasVideo = FALSE; BOOL bIsSelected = FALSE; // Media Itemが映像を含むか確認する hr = pEvent->pMediaItem->HasVideo(&bHasVideo, &bIsSelected); if (SUCCEEDED(hr)) { gHasVideo = bHasVideo && bIsSelected; // プレイヤーにMedia Itemを設定する hr = gPlayer->SetMediaItem(pEvent->pMediaItem); } } return hr; } HRESULT OnMediaItemSet(MFP_MEDIAITEM_SET_EVENT* /*pEvent*/) { return gPlayer->Play(); } void MediaPlayerCallback::OnMediaPlayerEvent(MFP_EVENT_HEADER* pEventHeader) { if (FAILED(pEventHeader->hrEvent)) { // Playback error } else { HRESULT hr = S_OK; switch (pEventHeader->eEventType) // MFP_EVENT_TYPE { case MFP_EVENT_TYPE_MEDIAITEM_CREATED: // 新しいMedia Itemが作成された hr = OnMediaItemCreated(MFP_GET_MEDIAITEM_CREATED_EVENT(pEventHeader)); if (FAILED(hr)) // Error playing this file break; case MFP_EVENT_TYPE_MEDIAITEM_SET: // Media Itemの再生の用意ができた hr = OnMediaItemSet(MFP_GET_MEDIAITEM_SET_EVENT(pEventHeader)); if (FAILED(hr)) // Play failed break; } } }
これを利用するには、次のようにMFPCreateMediaPlayer()の引数で渡します。
void OnFileOpen(HWND hWnd) { WCHAR pwszURL[] = L"C:\\sample.wmv"; BOOL fStartPlayback = FALSE; MFP_CREATION_OPTIONS creationOptions = 0; gPlayerCB = new (std::nothrow) MediaPlayerCallback(); // MFP_EVENT_TYPE_MEDIAITEM_CREATED イベントを受け取るため、MFPlayオブジェクト作成時にファイルを指定しない HRESULT hr = MFPCreateMediaPlayer(NULL, fStartPlayback, creationOptions, gPlayerCB, hWnd, &gPlayer); hr = gPlayer->CreateMediaItemFromURL(pwszURL, FALSE, 0, NULL); } void OnPaint(HWND hWnd) { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); if (gPlayer && gHasVideo) { // 映像を含むため、背景を描画しない gPlayer->UpdateVideo(); } else { // 映像を含まないため、クライアント領域を塗りつぶす FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1)); } EndPaint(hWnd, &ps); }Windows-classic-samples/winmain.cpp at master · Microsoft/Windows-classic-samples · GitHub