다음을 통해 공유


6단계: 컨트롤 재생

이 항목은 Media Foundation 사용하여 미디어 파일을 재생하는 방법에자습서의 6단계입니다. 전체 코드는 미디어 세션 재생 예제 항목에 나와 있습니다.

이 항목에는 다음 섹션이 포함되어 있습니다.

재생 시작

재생을 시작하려면 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::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;
}

재생 중지

재생을 중지하려면 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(Enhanced Video Renderer)은 애플리케이션에서 지정한 창에 비디오를 그립니다. 이는 별도의 스레드에서 발생하며 대부분의 경우 애플리케이션에서 이 프로세스를 관리할 필요가 없습니다. 그러나 재생이 일시 중지되거나 중지된 경우 비디오 창에서 WM_PAINT 메시지를 받을 때마다 EVR에 알림을 받아야 합니다. 이렇게 하면 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 메서드는 CPlayer 개체에 유효한 IMFVideoDisplayControl 포인터가 있는 경우 TRUE 반환합니다. (1단계: CPlayer 클래스선언 참조)

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

비디오 창 크기 조정

비디오 창의 크기를 조정하는 경우 IMFVideoDisplayControl::SetVideoPosition 메서드를 호출하여 EVR에서 대상 사각형을 업데이트합니다.

//  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 사용하여 미디어 파일을 재생하는 방법