手順 6: 再生を制御する
このトピックは、 Media Foundation を使用してメディア ファイルを再生する方法に関するチュートリアルの手順 6 です。 完全なコードは、「 メディア セッション再生の例」のトピックに示されています。
このトピックは、次のセクションで構成されています。
再生の開始
再生を開始するには、 IMFMediaSession::Start を呼び出します。 次のコードは、現在の再生位置から開始する方法を示しています。
// Start playback from the current position.
HRESULT CPlayer::StartPlayback()
{
assert(m_pSession != NULL);
PROPVARIANT varStart;
PropVariantInit(&varStart);
HRESULT hr = m_pSession->Start(&GUID_NULL, &varStart);
if (SUCCEEDED(hr))
{
// Note: Start is an asynchronous operation. However, we
// can treat our state as being already started. If Start
// fails later, we'll get an MESessionStarted event with
// an error code, and we will update our state then.
m_state = Started;
}
PropVariantClear(&varStart);
return hr;
}
// Start playback from paused or stopped.
HRESULT CPlayer::Play()
{
if (m_state != Paused && m_state != Stopped)
{
return MF_E_INVALIDREQUEST;
}
if (m_pSession == NULL || m_pSource == NULL)
{
return E_UNEXPECTED;
}
return StartPlayback();
}
Start メソッドは、ファイルの先頭を基準とした開始位置を指定することもできます。詳細については、API リファレンス トピックを参照してください。
再生の一時停止
再生を一時停止するには、 IMFMediaSession::P ause を呼び出します。
// Pause playback.
HRESULT CPlayer::Pause()
{
if (m_state != Started)
{
return MF_E_INVALIDREQUEST;
}
if (m_pSession == NULL || m_pSource == NULL)
{
return E_UNEXPECTED;
}
HRESULT hr = m_pSession->Pause();
if (SUCCEEDED(hr))
{
m_state = Paused;
}
return hr;
}
再生の停止
再生を停止するには、 IMFMediaSession::Stop を呼び出します。 再生が停止すると、ビデオ イメージがクリアされ、ビデオ ウィンドウが背景色 (既定では黒) で塗りつぶされます。
// Stop playback.
HRESULT CPlayer::Stop()
{
if (m_state != Started && m_state != Paused)
{
return MF_E_INVALIDREQUEST;
}
if (m_pSession == NULL)
{
return E_UNEXPECTED;
}
HRESULT hr = m_pSession->Stop();
if (SUCCEEDED(hr))
{
m_state = Stopped;
}
return hr;
}
ビデオ ウィンドウの再描画
拡張ビデオ レンダラー (EVR) は、アプリケーションで指定されたウィンドウにビデオを描画します。 これは別のスレッドで発生します。ほとんどの場合、アプリケーションでこのプロセスを管理する必要はありません。 ただし、再生が一時停止または停止している場合は、ビデオ ウィンドウが WM_PAINT メッセージを受信するたびに、EVR に通知する必要があります。 これにより、EVR でウィンドウを再描画できます。 EVR に通知するには、 IMFVideoDisplayControl::RepaintVideo メソッドを呼び出します。
// Repaint the video window. Call this method on WM_PAINT.
HRESULT CPlayer::Repaint()
{
if (m_pVideoDisplay)
{
return m_pVideoDisplay->RepaintVideo();
}
else
{
return S_OK;
}
}
次のコードは、 WM_PAINT メッセージのハンドラーを示しています。 この関数は、アプリケーションのメッセージ ループから呼び出す必要があります。
// Handler for WM_PAINT messages.
void OnPaint(HWND hwnd)
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
if (g_pPlayer && g_pPlayer->HasVideo())
{
// Video is playing. Ask the player to repaint.
g_pPlayer->Repaint();
}
else
{
// The video is not playing, so we must paint the application window.
RECT rc;
GetClientRect(hwnd, &rc);
FillRect(hdc, &rc, (HBRUSH) COLOR_WINDOW);
}
EndPaint(hwnd, &ps);
}
オブジェクトに有効な IMFVideoDisplayControl ポインターがある場合CPlayer
、メソッドは HasVideo
TRUE を返します。 ( 「手順 1: CPlayer クラスを宣言する」を参照してください)。
BOOL HasVideo() const { return (m_pVideoDisplay != NULL); }
ビデオ ウィンドウのサイズ変更
ビデオ ウィンドウのサイズを変更する場合は、 IMFVideoDisplayControl::SetVideoPosition メソッドを呼び出して、EVR の変換先の四角形を更新します。
// Resize the video rectangle.
//
// Call this method if the size of the video window changes.
HRESULT CPlayer::ResizeVideo(WORD width, WORD height)
{
if (m_pVideoDisplay)
{
// Set the destination rectangle.
// Leave the default source rectangle (0,0,1,1).
RECT rcDest = { 0, 0, width, height };
return m_pVideoDisplay->SetVideoPosition(NULL, &rcDest);
}
else
{
return S_OK;
}
}
次へ: 手順 7: メディア セッションをシャットダウンする
関連トピック