Поделиться через


Шаг 6. Управление воспроизведением

В этом разделе описывается шаг 6 руководства Воспроизведение файлов мультимедиа с помощьюMedia Foundation. Полный код показан в разделе пример воспроизведения сеансов мультимедиа.

В этом разделе содержатся следующие разделы:

Запуск воспроизведения

Чтобы начать воспроизведение, вызовите IMFMediaSession::Start. В следующем коде показано, как начать с текущей позиции воспроизведения.

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

Метод Start также может указать начальную позицию относительно начала файла; Дополнительные сведения см. в справочном разделе ПО API.

Приостановка воспроизведения

Чтобы приостановить воспроизведение, вызовите IMFMediaSession::Pause.

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

Остановка воспроизведения

Чтобы остановить воспроизведение, вызовите IMFMediaSession::Stop. При остановке воспроизведения изображение видео очищается, а окно видео окрашено цветом фона (черный по умолчанию).

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

Перерисовка окна видео

Расширенный видео рендерер (EVR) выводит видео на экран в окне, указанном приложением. Это происходит в отдельном потоке, и в большинстве случаев приложение не нуждается в управлении этим процессом. Однако, если воспроизведение приостановлено или остановлено, EVR должно быть уведомлено всякий раз, когда окно видео получает сообщение WM_PAINT. Это позволяет EVR перерисовать окно. Чтобы уведомить EVR, вызовите метод 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;
    }
}

В следующем коде показан обработчик сообщения WM_PAINT. Эта функция должна вызываться из цикла сообщений приложения.

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

Метод HasVideo возвращает TRUE, если объект CPlayer имеет допустимый указатель IMFVideoDisplayControl. (См. Шаг 1: Объявление класса CPlayer.)

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

Изменение размера окна видео

Если изменить размер окна видео, обновите прямоугольник назначения в EVR, вызвав метод 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;
    }
}

Далее: шаг 7. Завершение сеанса мультимедиа

воспроизведение звука и видео

Воспроизведение файлов мультимедиа с помощью Media Foundation