Compartir a través de


Paso 6: Controlar la reproducción

Este tema es el paso 6 del tutorial Cómo reproducir archivos multimedia con Media Foundation. El código completo se muestra en el tema Ejemplo de reproducción de sesión multimedia.

Este tema contiene las siguientes secciones:

Iniciar reproducción

Para iniciar la reproducción, llame a IMFMediaSession::Start. En el código siguiente se muestra cómo empezar desde la posición de reproducción actual.

//  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();
}

El método Start también puede especificar una posición inicial relativa al inicio del archivo; consulte el tema de referencia de API para obtener más información.

Pausar reproducción

Para pausar la reproducción, llame a 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;
}

Detener la reproducción

Para detener la reproducción, llame a IMFMediaSession::Stop. Mientras se detiene la reproducción, la imagen de vídeo se borra y la ventana de vídeo se pinta con el color de fondo (negro de forma predeterminada).

// 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;
}

Volver a dibujar la ventana de vídeo

El representador de vídeo mejorado (EVR) dibuja el vídeo en la ventana especificada por la aplicación. Esto ocurre en un subproceso independiente y, en su mayor parte, la aplicación no necesita administrar este proceso. Sin embargo, si la reproducción está en pausa o detenida, el EVR debe recibir una notificación cada vez que la ventana de vídeo recibe un mensaje de WM_PAINT . Esto permite que el EVR vuelva a pintar la ventana. Para notificar al EVR, llame al 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;
    }
}

En el código siguiente se muestra el controlador del mensaje de WM_PAINT . Se debe llamar a esta función desde el bucle de mensajes de la aplicación.

//  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);
}

El HasVideo método devuelve TRUE si el CPlayer objeto tiene un puntero IMFVideoDisplayControl válido. (Consulta paso 1: Declarar la clase CPlayer).

    BOOL          HasVideo() const { return (m_pVideoDisplay != NULL);  }

Cambio del tamaño de la ventana de vídeo

Si cambia el tamaño de la ventana de vídeo, actualice el rectángulo de destino en el EVR llamando al 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;
    }
}

Siguiente: Paso 7: Apagar la sesión multimedia

Reproducción de audio y vídeo

Cómo reproducir archivos multimedia con Media Foundation