Étape 6 : contrôler la lecture

Cette rubrique est l’étape 6 du didacticiel Comment lire des fichiers multimédias avec Media Foundation. Le code complet est présenté dans la rubrique 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. Pendant l’arrêt de la lecture, 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;
}

Redessiner 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 l’essentiel, votre application n’a pas besoin de gérer ce processus. Toutefois, si la lecture est suspendue ou arrêtée, le EVR doit être notifié chaque fois que la fenêtre vidéo reçoit un message de _ peinture WM . Cela permet à EVR de repeindre la fenêtre. Pour notifier le 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 la valeur true si l' CPlayer objet 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 le 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

Comment lire des fichiers multimédias avec Media Foundation