Share via


Schritt 6: Steuern der Wiedergabe

Dieses Thema ist Schritt 6 des Tutorials Wiedergeben von Mediendateien mit Media Foundation. Der vollständige Code wird im Thema Media Session Playback Example (Beispiel für die Mediensitzungswiedergabe) angezeigt.

Dieses Thema enthält folgende Abschnitte:

Starten der Wiedergabe

Um die Wiedergabe zu starten, rufen Sie IMFMediaSession::Start auf. Der folgende Code zeigt, wie Sie mit der aktuellen Wiedergabeposition beginnen.

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

Die Start-Methode kann auch eine Startposition relativ zum Anfang der Datei angeben. Weitere Informationen finden Sie im API-Referenzthema.

Anhalten der Wiedergabe

Um die Wiedergabe anzuhalten, rufen Sie IMFMediaSession::P ause auf.

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

Beenden der Wiedergabe

Um die Wiedergabe zu beenden, rufen Sie IMFMediaSession::Stop auf. Während die Wiedergabe beendet wird, wird das Videobild gelöscht, und das Videofenster wird mit der Hintergrundfarbe (standardmäßig schwarz) gezeichnet.

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

Neulackieren des Videofensters

Der enhanced Video Renderer (EVR) zeichnet das Video in dem von der Anwendung angegebenen Fenster. Dies geschieht in einem separaten Thread, und in den meisten Fällen muss Ihre Anwendung diesen Prozess nicht verwalten. Wenn die Wiedergabe angehalten oder beendet wird, muss der EVR jedoch benachrichtigt werden, wenn das Videofenster eine WM_PAINT Nachricht empfängt. Dadurch kann der EVR das Fenster neu streichen. Um den EVR zu benachrichtigen, rufen Sie die IMFVideoDisplayControl::RepaintVideo-Methode auf:

//  Repaint the video window. Call this method on WM_PAINT.

HRESULT CPlayer::Repaint()
{
    if (m_pVideoDisplay)
    {
        return m_pVideoDisplay->RepaintVideo();
    }
    else
    {
        return S_OK;
    }
}

Der folgende Code zeigt den Handler für die WM_PAINT Meldung. Diese Funktion sollte aus der Nachrichtenschleife der Anwendung aufgerufen werden.

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

Die HasVideo -Methode gibt TRUE zurück, wenn das CPlayer Objekt über einen gültigen IMFVideoDisplayControl-Zeiger verfügt. (Siehe Schritt 1: Deklarieren der CPlayer-Klasse.)

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

Ändern der Größe des Videofensters

Wenn Sie die Größe des Videofensters ändern, aktualisieren Sie das Zielrechteck auf dem EVR, indem Sie die IMFVideoDisplayControl::SetVideoPosition-Methode aufrufen:

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

Weiter: Schritt 7: Herunterfahren der Mediensitzung

Audio-/Videowiedergabe

Wiedergeben von Mediendateien mit Media Foundation