Etapa 6: Controlar a reprodução
Este tópico é a etapa 6 do tutorial Como reproduzir arquivos de mídia com o Media Foundation. O código completo é mostrado no tópico Exemplo de Reprodução de Sessão de Mídia.
Este tópico contém as seguintes seções:
- Iniciando a reprodução
- Pausando a reprodução
- Interrompendo a reprodução
- Repintamento da janela de vídeo
- Redimensionando a janela de vídeo
- Tópicos relacionados
Iniciando a reprodução
Para iniciar a reprodução, chame IMFMediaSession::Start. O código a seguir mostra como começar a partir da posição de reprodução atual.
// 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();
}
O método Start também pode especificar uma posição inicial em relação ao início do arquivo; consulte o tópico de referência da API para obter mais informações.
Pausando a reprodução
Para pausar a reprodução, chame 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;
}
Interrompendo a reprodução
Para interromper a reprodução, chame IMFMediaSession::Stop. Enquanto a reprodução é interrompida, a imagem de vídeo é desmarcada e a janela de vídeo é pintada com a cor da tela de fundo (preto por padrão).
// 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;
}
Repintamento da janela de vídeo
O EVR ( Renderizador de Vídeo Avançado ) desenha o vídeo na janela especificada pelo aplicativo. Isso ocorre em um thread separado e, na maioria das vezes, seu aplicativo não precisa gerenciar esse processo. No entanto, se a reprodução estiver pausada ou interrompida, o EVR deverá ser notificado sempre que a janela de vídeo receber uma mensagem WM_PAINT . Isso permite que o EVR repintar a janela. Para notificar o EVR, chame o método 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;
}
}
O código a seguir mostra o manipulador da mensagem WM_PAINT . Essa função deve ser chamada do loop de mensagem do aplicativo.
// 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);
}
O HasVideo
método retornará TRUE se o CPlayer
objeto tiver um ponteiro IMFVideoDisplayControl válido. (Consulte a Etapa 1: Declarar a classe CPlayer.)
BOOL HasVideo() const { return (m_pVideoDisplay != NULL); }
Redimensionando a janela de vídeo
Se você redimensionar a janela de vídeo, atualize o retângulo de destino no EVR chamando o método IMFVideoDisplayControl::SetVideoPosition :
// 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;
}
}
Próximo: Etapa 7: Desligar a sessão de mídia
Tópicos relacionados