本主題是教學課程的步驟 6 如何使用 Media Foundation 播放媒體檔案。 在 媒體工作階段播放範例主題中顯示完整的程式代碼。
本主題包含下列各節:
開始播放
若要開始播放,請呼叫 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);
}
如果 CPlayer
物件具有有效的 IMFVideoDisplayControl 指標,則 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:關閉媒體會話
相關主題
-
如何使用 Media Foundation 播放媒體檔案