Étape 6 : Contrôler la lecture

Cette rubrique est l’étape 6 du didacticiel Guide pratique pour lire des fichiers multimédias avec Media Foundation. Le code complet est présenté dans la rubrique Media Session Playback Example( Exemple de lecture de session multimédia).

Cette rubrique contient les sections suivantes :

Démarrage de la lecture

Pour démarrer la lecture, appelez IMFMediaSession::Start. Le code suivant montre comment démarrer à partir de la position de lecture actuelle.

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

La méthode Start peut également spécifier une position de départ par rapport au début du fichier ; Pour plus d’informations, consultez la rubrique de référence sur les API.

Suspension de la lecture

Pour suspendre la lecture, appelez 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;
}

Arrêt de la lecture

Pour arrêter la lecture, appelez IMFMediaSession::Stop. Lorsque la lecture est arrêtée, l’image vidéo est effacée et la fenêtre vidéo est peinte avec la couleur d’arrière-plan (noir par défaut).

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

Repeint la fenêtre vidéo

Le convertisseur vidéo amélioré (EVR) dessine la vidéo dans la fenêtre spécifiée par l’application. Cela se produit sur un thread distinct, et pour la plupart, votre application n’a pas besoin de gérer ce processus. Toutefois, si la lecture est suspendue ou arrêtée, l’EVR doit être averti chaque fois que la fenêtre vidéo reçoit un message WM_PAINT . Cela permet à l’EVR de repeindre la fenêtre. Pour notifier l’EVR, appelez la méthode 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;
    }
}

Le code suivant montre le gestionnaire du message WM_PAINT . Cette fonction doit être appelée à partir de la boucle de message de l’application.

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

La HasVideo méthode retourne TRUE si l’objet CPlayer a un pointeur IMFVideoDisplayControl valide. (Voir Étape 1 : Déclarer la classe CPlayer.)

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

Redimensionnement de la fenêtre vidéo

Si vous redimensionnez la fenêtre vidéo, mettez à jour le rectangle de destination sur l’EVR en appelant la méthode 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;
    }
}

Suivant : Étape 7 : Arrêter la session multimédia

Lecture audio/vidéo

Guide pratique pour lire des fichiers multimédias avec Media Foundation