MFPlay 시작
[MFPlay는 요구 사항 섹션에 지정된 운영 체제에서 사용할 수 있습니다. 이후 버전에서는 변경되거나 제공되지 않을 수 있습니다. ]
MFPlay는 C++에서 미디어 재생 애플리케이션을 만들기 위한 API입니다.
이 항목에는 다음과 같은 섹션이 포함되어 있습니다.
요구 사항
MFPlay에는 Windows 7이 필요합니다.
MFPlay 정보
MFPlay에는 간단한 프로그래밍 모델이 있으며 대부분의 재생 애플리케이션에 필요한 핵심 기능 집합을 제공합니다. 애플리케이션은 재생을 제어하는 플레이어 개체를 만듭니다. 미디어 파일을 재생하기 위해 플레이어 개체는 미디어 파일의 내용에 대한 정보를 가져오는 데 사용할 수 있는 미디어 항목을 만듭니다. 애플리케이션은 플레이어 개체의 IMFPMediaPlayer 인터페이스에서 메서드를 통해 재생을 제어합니다. 필요에 따라 애플리케이션은 콜백 인터페이스를 통해 이벤트 알림을 받을 수 있습니다. 다음 다이어그램은 이 프로세스를 보여 줍니다.
미디어 파일 재생
미디어 파일을 재생하려면 MFPCreateMediaPlayer 함수를 호출합니다.
// Global variables
IMFPMediaPlayer *g_pPlayer = NULL;
const WCHAR *sURL = L"C:\\Users\\Public\\Videos\\example.wmv";
HRESULT PlayVideo(HWND hwnd, const WCHAR* sURL)
{
// Create the player object and play a video file.
return MFPCreateMediaPlayer(
sURL,
TRUE, // Start playback automatically?
0, // Flags.
NULL, // Callback pointer.
hwnd,
&g_pPlayer
);
}
MFPCreateMediaPlayer 함수는 MFPlay 플레이어 개체의 새 인스턴스를 만듭니다. 함수는 다음 매개 변수를 사용합니다.
- 첫 번째 매개 변수는 열 파일의 URL입니다. 로컬 파일 또는 미디어 서버의 파일일 수 있습니다.
- 두 번째 매개 변수는 재생이 자동으로 시작되는지 여부를 지정합니다. 이 매개 변수를 TRUE로 설정하면 MFPlay에서 파일을 로드하는 즉시 파일이 재생됩니다.
- 세 번째 매개 변수는 다양한 옵션을 설정합니다. 기본 옵션의 경우 0을 전달합니다.
- 네 번째 매개 변수는 선택적 콜백 인터페이스에 대한 포인터입니다. 이 매개 변수는 표시된 대로 NULL일 수 있습니다. 콜백은 플레이어에서 이벤트 수신 섹션에 설명되어 있습니다.
- 다섯 번째 매개 변수는 애플리케이션 창에 대한 핸들입니다. 미디어 파일에 비디오 스트림이 포함된 경우 비디오가 이 창의 클라이언트 영역 내에 표시됩니다. 오디오 전용 재생의 경우 이 매개 변수는 NULL일 수 있습니다.
마지막 매개 변수는 플레이어 개체의 IMFPMediaPlayer 인터페이스에 대한 포인터를 받습니다.
애플리케이션이 종료되기 전에 IMFPMediaPlayer 포인터를 해제해야 합니다. WM_CLOSE 메시지 처리기에서 이 작업을 수행할 수 있습니다.
void OnClose(HWND /*hwnd*/)
{
SafeRelease(&g_pPlayer);
SafeRelease(&g_pPlayerCB);
PostQuitMessage(0);
}
참고 항목
이 예제에서는 금고Release 함수를 사용하여 인터페이스 포인터를 해제합니다.
간단한 비디오 재생의 경우 필요한 모든 코드입니다. 이 자습서의 나머지 단계에서는 재생을 제어하는 방법부터 시작하여 더 많은 기능을 추가하는 방법을 보여 줍니다.
재생 제어
이전 섹션에 표시된 코드는 파일의 끝에 도달할 때까지 미디어 파일을 재생합니다. IMFPMediaPlayer 인터페이스에서 다음 메서드를 호출하여 재생을 중지하고 시작할 수 있습니다.
- IMFPMediaPlayer::P ause 는 재생을 일시 중지합니다. 재생이 일시 중지되는 동안 가장 최근의 비디오 프레임이 표시되고 오디오가 자동으로 표시됩니다.
- IMFPMediaPlayer::Stop 은 재생을 중지합니다. 비디오가 표시되지 않고 재생 위치가 파일의 시작 부분으로 다시 설정됩니다.
- IMFPMediaPlayer::P lay 는 중지하거나 일시 중지한 후 재생을 다시 시작합니다.
다음 코드는 스페이스바를 누르면 재생을 일시 중지하거나 다시 시작합니다.
//-------------------------------------------------------------------
// OnKeyDown
//
// Handles the WM_KEYDOWN message.
//-------------------------------------------------------------------
void OnKeyDown(HWND hwnd, UINT vk, BOOL fDown, int cRepeat, UINT flags)
{
HRESULT hr = S_OK;
switch (vk)
{
case VK_SPACE:
// Toggle between playback and paused/stopped.
if (g_pPlayer)
{
MFP_MEDIAPLAYER_STATE state = MFP_MEDIAPLAYER_STATE_EMPTY;
g_pPlayer->GetState(&state);
if (state == MFP_MEDIAPLAYER_STATE_PAUSED ||
state == MFP_MEDIAPLAYER_STATE_STOPPED)
{
g_pPlayer->Play();
}
else if (state == MFP_MEDIAPLAYER_STATE_PLAYING)
{
g_pPlayer->Pause();
}
}
break;
}
}
이 예제에서는 IMFPMediaPlayer::GetState 메서드를 호출하여 현재 재생 상태(일시 중지, 중지 또는 재생)를 가져와서 그에 따라 일시 중지하거나 다시 시작합니다.
플레이어에서 이벤트 수신
MFPlay는 콜백 인터페이스를 사용하여 애플리케이션에 이벤트를 보냅니다. 이 콜백에는 두 가지 이유가 있습니다.
- 재생은 별도의 스레드에서 발생합니다. 재생 중에 파일의 끝에 도달하는 것과 같은 특정 이벤트가 발생할 수 있습니다. MFPlay는 콜백을 사용하여 애플리케이션에 이벤트를 알립니다.
- 대부분의 IMFPMediaPlayer 메서드는 비동기이므로 작업이 완료되기 전에 반환됩니다. 비동기 메서드를 사용하면 UI를 차단하지 않고 완료하는 데 시간이 오래 걸릴 수 있는 작업을 UI 스레드에서 시작할 수 있습니다. 작업이 완료되면 MFPlay에서 콜백 신호를 전송합니다.
콜백 알림을 받으려면 IMFPMediaPlayerCallback 인터페이스를 구현합니다. 이 인터페이스는 IUnknown을 상속하고 단일 메서드인 OnMediaPlayerEvent를 정의합니다. 콜백을 설정하려면 MFPCreateMediaPlayer 함수의 pCallback 매개 변수에서 IMFPMediaPlayerCallback 구현에 대한 포인터를 전달합니다.
다음은 콜백을 포함하도록 수정된 이 자습서의 첫 번째 예제입니다.
// Global variables.
IMFPMediaPlayer *g_pPlayer = NULL;
IMFPMediaPlayerCallback *g_pCallback = NULL;
// Call an application-defined function to create the callback object.
hr = CreateMyCallback(&g_pCallback);
// Create the player object and play a video file.
const WCHAR *sURL = L"C:\\Users\\Public\\Videos\\example.wmv";
if (SUCCEEDED(hr))
{
hr = MFPCreateMediaPlayer(
sURL,
TRUE, // Start playback automatically?
0, // Flags.
g_pCallback, // Callback pointer.
hwnd,
&g_pPlayer
);
}
OnMediaPlayerEvent 메서드에는 MFP_EVENT_HEADER 구조체에 대한 포인터인 단일 매개 변수가 있습니다. 이 구조체의 eEventType 멤버는 발생한 이벤트를 알려줍니다. 예를 들어 재생이 시작되면 MFPlay는 MFP_EVENT_TYPE_PLAY 이벤트를 보냅니다.
각 이벤트 형식에는 해당 이벤트에 대한 정보가 포함된 해당 데이터 구조가 있습니다. 이러한 각 구조는 MFP_EVENT_HEADER 구조로 시작합니다. 콜백에서 MFP_EVENT_HEADER 포인터를 이벤트별 데이터 구조로 캐스팅합니다. 예를 들어 이벤트 형식이 MFP_PLAY_EVENT 데이터 구조는 MFP_PLAY_EVENT. 다음 코드는 콜백에서 이 이벤트를 처리하는 방법을 보여줍니다.
void STDMETHODCALLTYPE MediaPlayerCallback::OnMediaPlayerEvent(
MFP_EVENT_HEADER *pEventHeader
)
{
switch (pEventHeader->eEventType)
{
case MFP_EVENT_TYPE_PLAY:
OnPlay(MFP_GET_PLAY_EVENT(pEventHeader));
break;
// Other event types (not shown).
}
}
// Function to handle the event.
void OnPlay(MFP_PLAY_EVENT *pEvent)
{
if (FAILED(pEvent->header.hrEvent))
{
// Error occurred during playback.
}
}
이 예제에서는 MFP_GET_PLAY_EVENT 이벤트를 사용하여 pEventHeader 포인터를 MFP_PLAY_EVENT 구조체로 캐스팅합니다. 이벤트를 트리거한 작업의 HRESULT는 구조체의 hrEvent 필드에 저장됩니다.
모든 이벤트 유형 및 해당 데이터 구조 목록은 MFP_EVENT_TYPE 참조하세요.
스레딩에 대한 참고 사항: 기본적으로 MFPlay는 MFPCreateMediaPlayer라는 동일한 스레드에서 콜백을 호출합니다. 이 스레드에는 메시지 루프가 있어야 합니다. 또는 MFPCreateMediaPlayer의 creationOptions 매개 변수에 MFP_OPTION_FREE_THREADED_CALLBACK 플래그를 전달할 수 있습니다. 이 플래그를 사용하면 MFPlay가 별도의 스레드에서 콜백을 호출합니다. 두 옵션 모두 애플리케이션에 영향을 줍니다. 기본 옵션은 콜백이 창 프로시저를 차단하기 때문에 UI 작업 대기와 같이 메시지 루프에서 대기하는 작업을 수행할 수 없음을 의미합니다. 자유 스레드 옵션은 중요한 섹션을 사용하여 콜백에서 액세스하는 모든 데이터를 보호해야 한다는 것을 의미합니다. 대부분의 경우 기본 옵션은 가장 간단합니다.
미디어 파일에 대한 정보 가져오기
MFPlay에서 미디어 파일을 열면 플레이어는 미디어 파일을 나타내는 미디어 항목이라는 개체를 만듭니다. 이 개체는 미디어 파일에 대한 정보를 가져오는 데 사용할 수 있는 IMFPMediaItem 인터페이스를 노출합니다. MFPlay 이벤트 구조의 대부분은 현재 미디어 항목에 대한 포인터를 포함합니다. 플레이어에서 IMFPMediaPlayer::GetMediaItem을 호출하여 현재 미디어 항목을 가져올 수도 있습니다.
특히 유용한 두 가지 방법은 IMFPMediaItem::HasVideo 및 IMFPMediaItem::HasAudio입니다. 이러한 메서드는 미디어 원본에 비디오 또는 오디오가 포함되어 있는지 여부를 쿼리합니다.
예를 들어 다음 코드는 현재 미디어 파일에 비디오 스트림이 포함되어 있는지 테스트합니다.
IMFPMediaItem *pItem;
BOOL bHasVideo = FALSE;
BOOL bIsSelected = FALSE;
hr = g_pPlayer->GetMediaItem(TRUE, &pItem);
if (SUCCEEDED(hr))
{
hr = pItem->HasVideo(&bHasVideo, &bIsSelected);
pItem->Release();
}
원본 파일에 재생을 위해 선택된 비디오 스트림이 포함된 경우 bHasVideo 및 bIsSelected는 모두 TRUE로 설정됩니다.
비디오 재생 관리
MFPlay에서 비디오 파일을 재생하면 MFPCreateMediaPlayer 함수에서 지정한 창에 비디오를 그립니다. 이는 Microsoft Media Foundation 재생 파이프라인이 소유한 별도의 스레드에서 발생합니다. 대부분의 경우 애플리케이션이 이 프로세스를 관리할 필요가 없습니다. 그러나 애플리케이션이 MFPlay에 비디오를 업데이트하도록 알려야 하는 두 가지 상황이 있습니다.
- 재생이 일시 중지되거나 중지된 경우 애플리케이션의 비디오 창에서 WM_PAINT 메시지를 받을 때마다 MFPlay에 알림을 받아야 합니다. 이렇게 하면 MFPlay에서 창을 다시 칠할 수 있습니다.
- 창 크기가 조정되면 MFPlay에 새 창 크기와 일치하도록 비디오 크기를 조정할 수 있도록 알림을 받아야 합니다.
IMFPMediaPlayer::UpdateVideo 메서드는 두 경우를 모두 처리합니다. 비디오 창에 대한 WM_PAINT 및 WM_SIZE 메시지 처리기 내에서 이 메서드를 호출합니다.
Important
UpdateVideo를 호출하기 전에 GDI Begin그림판 함수를 호출합니다.
IMFPMediaPlayer *g_pPlayer; // MFPlay player object
void OnSize(HWND hwnd, UINT state, int cx, int cy)
{
HDC hdc;
PAINTSTRUCT ps;
if (g_pPlayer && (state == SIZE_RESTORED))
{
hdc = BeginPaint(hwnd, &ps);
g_pPlayer->UpdateVideo();
EndPaint(hwnd, &ps);
}
}
void OnPaint(HWND hwnd)
{
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(hwnd, &ps);
if (g_pPlayer)
{
g_pPlayer->UpdateVideo();
}
EndPaint(hwnd, &ps);
}
달리 지정하지 않는 한 MFPlay는 필요한 경우 레터박싱을 사용하여 올바른 가로 세로 비율로 비디오를 표시합니다. 가로 세로 비율을 유지하지 않으려면 MFVideoARMode_None 플래그를 사용하여 IMFPMediaPlayer::SetAspectRatioMode를 호출합니다. 이로 인해 MFPlay가 레터박싱 없이 전체 사각형을 채우기 위해 비디오를 확장합니다. 일반적으로 기본 설정을 사용하고 MFPlay 레터박스에 비디오를 허용해야 합니다. 기본 레터박스 색은 검은색이지만 IMFPMediaPlayer::SetBorderColor를 호출하여 변경할 수 있습니다.
MFPlay의 제한 사항
현재 버전의 MFPlay에는 다음과 같은 제한 사항이 있습니다.
- MFPlay는 DRM으로 보호되는 콘텐츠를 지원하지 않습니다.
- 기본적으로 MFPlay는 네트워크 스트리밍 프로토콜을 지원하지 않습니다. 자세한 내용은 IMFPMediaPlayer::CreateMediaItemFromURL을 참조하세요.
- MFPlay는 SSPL(서버 쪽 재생 목록) 또는 둘 이상의 세그먼트를 재생하는 다른 유형의 원본을 지원하지 않습니다. 기술적인 측면에서 MFPlay는 첫 번째 프레젠테이션 후 재생을 중지하고 미디어 원본에서 MENewPresentation 이벤트를 무시합니다.
- MFPlay는 미디어 원본 간의 원활한 전환을 지원하지 않습니다.
- MFPlay는 여러 비디오 스트림 혼합을 지원하지 않습니다.
- Media Foundation에서 기본적으로 지원되는 미디어 형식만 MFPlay에서 지원됩니다. (시스템에 설치될 수 있는 타사 Media Foundation 구성 요소가 포함됩니다.)
관련 항목