Mulai menggunakan MFPlay
[MFPlay tersedia untuk digunakan dalam sistem operasi yang ditentukan di bagian Persyaratan. Ini mungkin diubah atau tidak tersedia dalam versi berikutnya. ]
MFPlay adalah API untuk membuat aplikasi pemutaran media di C++.
Topik ini berisi bagian berikut:
- Persyaratan
- Tentang MFPlay
- Memutar File Media
- Mengontrol Pemutaran
- Menerima Peristiwa Dari Pemutar
- Mendapatkan Informasi Tentang File Media
- Mengelola Pemutaran Video
- Batasan MFPlay
- Topik terkait
Persyaratan
MFPlay memerlukan Windows 7.
Tentang MFPlay
MFPlay memiliki model pemrograman sederhana, sekaligus menyediakan serangkaian fitur inti yang dibutuhkan sebagian besar aplikasi pemutaran. Aplikasi membuat objek pemutar yang mengontrol pemutaran. Untuk memutar file media, objek pemutar membuat item media, yang dapat digunakan untuk mendapatkan informasi tentang isi file media. Aplikasi mengontrol pemutaran melalui metode pada antarmuka IMFPMediaPlayer objek pemutar. Secara opsional, aplikasi bisa mendapatkan pemberitahuan peristiwa melalui antarmuka panggilan balik Diagram berikut mengilustrasikan proses ini.
Memutar File Media
Untuk memutar file media, panggil fungsi 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
);
}
Fungsi MFPCreateMediaPlayer membuat instans baru objek pemutar MFPlay. Fungsi ini mengambil parameter berikut:
- Parameter pertama adalah URL file yang akan dibuka. Ini bisa berupa file lokal atau file pada server media.
- Parameter kedua menentukan apakah pemutaran dimulai secara otomatis. Dengan mengatur parameter ini ke TRUE, file akan diputar segera setelah MFPlay memuatnya.
- Parameter ketiga menetapkan berbagai opsi. Untuk opsi default, teruskan nol (0).
- Parameter keempat adalah penunjuk ke antarmuka panggilan balik opsional. Parameter ini bisa NULL, seperti yang ditunjukkan. Panggilan balik dijelaskan di bagian Menerima Peristiwa Dari Pemutar.
- Parameter kelima adalah handel ke jendela aplikasi. Jika file media berisi aliran video, video akan muncul di dalam area klien jendela ini. Untuk pemutaran audio saja, parameter ini dapat berupa NULL.
Parameter terakhir menerima penunjuk ke antarmuka IMFPMediaPlayer objek pemutar.
Sebelum aplikasi dimatikan, pastikan untuk merilis pointer IMFPMediaPlayer . Anda dapat melakukan ini di handler pesan WM_CLOSE Anda.
void OnClose(HWND /*hwnd*/)
{
SafeRelease(&g_pPlayer);
SafeRelease(&g_pPlayerCB);
PostQuitMessage(0);
}
Catatan
Contoh ini menggunakan fungsi Brankas Release untuk merilis penunjuk antarmuka.
Untuk pemutaran video sederhana, itu saja kode yang Anda butuhkan. Sisa tutorial ini akan menunjukkan cara menambahkan lebih banyak fitur, dimulai dengan cara mengontrol pemutaran.
Mengontrol Pemutaran
Kode yang ditampilkan di bagian sebelumnya akan memutar file media hingga mencapai akhir file. Anda dapat menghentikan dan memulai pemutaran dengan memanggil metode berikut pada antarmuka IMFPMediaPlayer:
- IMFPMediaPlayer::P ause menjeda pemutaran. Saat pemutaran dijeda, bingkai video terbaru ditampilkan, dan audio diam.
- IMFPMediaPlayer::Menghentikan pemutaran. Tidak ada video yang ditampilkan, dan posisi pemutaran diatur ulang ke awal file.
- IMFPMediaPlayer::P lay melanjutkan pemutaran setelah berhenti atau menjeda.
Kode berikut menjeda atau melanjutkan pemutaran saat Anda menekan SPACEBAR.
//-------------------------------------------------------------------
// 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;
}
}
Contoh ini memanggil metode IMFPMediaPlayer::GetState untuk mendapatkan status pemutaran saat ini (dijeda, dihentikan, atau diputar) dan menjeda atau melanjutkan yang sesuai.
Menerima Peristiwa Dari Pemutar
MFPlay menggunakan antarmuka panggilan balik untuk mengirim peristiwa ke aplikasi Anda. Ada dua alasan untuk panggilan balik ini:
- Pemutaran terjadi pada utas terpisah. Selama pemutaran, peristiwa tertentu mungkin terjadi, seperti mencapai akhir file. MFPlay menggunakan panggilan balik untuk memberi tahu aplikasi acara Anda.
- Banyak metode IMFPMediaPlayer asinkron, yang berarti metode tersebut kembali sebelum operasi selesai. Metode asinkron memungkinkan Anda memulai operasi dari utas UI yang mungkin membutuhkan waktu lama untuk diselesaikan, tanpa menyebabkan UI Anda diblokir. Setelah operasi selesai, MFPlay memberi sinyal panggilan balik.
Untuk menerima pemberitahuan panggilan balik, terapkan antarmuka IMFPMediaPlayerCallback . Antarmuka ini mewarisi IUnknown dan mendefinisikan satu metode, OnMediaPlayerEvent. Untuk menyiapkan panggilan balik, teruskan penunjuk ke implementasi IMFPMediaPlayerCallback Anda di parameter pCallback fungsi MFPCreateMediaPlayer.
Berikut adalah contoh pertama dari tutorial ini, dimodifikasi untuk menyertakan panggilan balik.
// 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
);
}
Metode OnMediaPlayerEvent memiliki satu parameter, yang merupakan penunjuk ke struktur MFP_EVENT_HEADER. Anggota eEventType dari struktur ini memberi tahu Anda peristiwa mana yang terjadi. Misalnya, saat pemutaran dimulai, MFPlay mengirimkan peristiwa MFP_EVENT_TYPE_PLAY .
Setiap jenis peristiwa memiliki struktur data terkait yang berisi informasi untuk peristiwa tersebut. Masing-masing struktur ini dimulai dengan struktur MFP_EVENT_HEADER. Di panggilan balik Anda, transmisikan penunjuk MFP_EVENT_HEADER ke struktur data khusus peristiwa. Misalnya, jika jenis peristiwa MFP_PLAY_EVENT, struktur data MFP_PLAY_EVENT. Kode berikut menunjukkan cara menangani peristiwa ini di panggilan balik.
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.
}
}
Contoh ini menggunakan peristiwa MFP_GET_PLAY_EVENT untuk melemparkan penunjuk pEventHeader ke struktur MFP_PLAY_EVENT. HRESULT dari operasi yang memicu peristiwa disimpan di bidang hrEvent struktur.
Untuk daftar semua jenis peristiwa dan struktur data terkait, lihat MFP_EVENT_TYPE.
Catatan tentang utas: Secara default, MFPlay memanggil panggilan balik dari utas yang sama yang disebut MFPCreateMediaPlayer. Utas ini harus memiliki perulangan pesan. Atau, Anda dapat meneruskan bendera MFP_OPTION_FREE_THREADED_CALLBACK dalam parameter creationOptions MFPCreateMediaPlayer. Bendera ini menyebabkan MFPlay memanggil panggilan balik dari utas terpisah. Salah satu opsi memiliki implikasi untuk aplikasi Anda. Opsi default berarti panggilan balik Anda tidak dapat melakukan apa pun yang menunggu perulangan pesan Anda, seperti menunggu tindakan UI, karena itu akan memblokir prosedur jendela Anda. Opsi utas bebas berarti Anda perlu menggunakan bagian penting untuk melindungi data apa pun yang Anda akses di panggilan balik Anda. Dalam kebanyakan kasus, opsi default paling sederhana.
Mendapatkan Informasi Tentang File Media
Saat Anda membuka file media di MFPlay, pemutar membuat objek yang disebut item media yang mewakili file media. Objek ini mengekspos antarmuka IMFPMediaItem , yang dapat Anda gunakan untuk mendapatkan informasi tentang file media. Banyak struktur peristiwa MFPlay berisi penunjuk ke item media saat ini. Anda juga bisa mendapatkan item media saat ini dengan memanggil IMFPMediaPlayer::GetMediaItem pada pemutar.
Dua metode yang sangat berguna adalah IMFPMediaItem::HasVideo dan IMFPMediaItem::HasAudio. Metode ini mengkueri apakah sumber media berisi video atau audio.
Misalnya, kode berikut menguji apakah file media saat ini berisi aliran video.
IMFPMediaItem *pItem;
BOOL bHasVideo = FALSE;
BOOL bIsSelected = FALSE;
hr = g_pPlayer->GetMediaItem(TRUE, &pItem);
if (SUCCEEDED(hr))
{
hr = pItem->HasVideo(&bHasVideo, &bIsSelected);
pItem->Release();
}
Jika file sumber berisi aliran video yang dipilih untuk pemutaran, bHasVideo dan bIsSelected keduanya diatur ke TRUE.
Mengelola Pemutaran Video
Saat MFPlay memutar file video, MFPlay akan menggambar video di jendela yang Anda tentukan dalam fungsi MFPCreateMediaPlayer. Ini terjadi pada alur terpisah yang dimiliki oleh alur pemutaran Microsoft Media Foundation. Sebagian besar, aplikasi Anda tidak perlu mengelola proses ini. Namun, ada dua situasi di mana aplikasi harus memberi tahu MFPlay untuk memperbarui video.
- Jika pemutaran dijeda atau dihentikan, MFPlay harus diberi tahu setiap kali jendela video aplikasi menerima pesan WM_PAINT. Ini memungkinkan MFPlay untuk mengecat ulang jendela.
- Jika jendela diubah ukurannya, MFPlay harus diberi tahu sehingga dapat menskalakan video agar sesuai dengan ukuran jendela baru.
Metode IMFPMediaPlayer::UpdateVideo menangani kedua kasus. Panggil metode ini di dalam penangan pesan WM_PAINT dan WM_SIZE untuk jendela video.
Penting
Panggil fungsi GDI BeginPaint sebelum memanggil UpdateVideo.
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);
}
Kecuali Anda menentukan sebaliknya, MFPlay menunjukkan video pada rasio aspek yang benar, menggunakan kotak surat jika diperlukan. Jika Anda tidak ingin mempertahankan rasio aspek, panggil IMFPMediaPlayer::SetAspectRatioMode dengan bendera MFVideoARMode_None. Ini akan menyebabkan MFPlay meregangkan video untuk mengisi seluruh persegi panjang, tanpa kotak surat. Biasanya Anda harus menggunakan pengaturan default dan membiarkan kotak surat MFPlay video. Warna kotak surat default berwarna hitam, tetapi Anda dapat mengubahnya dengan memanggil IMFPMediaPlayer::SetBorderColor.
Batasan MFPlay
Versi MFPlay saat ini memiliki batasan berikut:
- MFPlay tidak mendukung konten yang dilindungi DRM.
- Secara default, MFPlay tidak mendukung protokol streaming jaringan. Untuk informasi selengkapnya, lihat IMFPMediaPlayer::CreateMediaItemFromURL.
- MFPlay tidak mendukung daftar putar sisi server (SSPL) atau jenis sumber lain yang memainkan lebih dari satu segmen. Dalam istilah teknis, MFPlay menghentikan pemutaran setelah presentasi pertama, dan mengabaikan peristiwa MENewPresentation apa pun dari sumber media.
- MFPlay tidak mendukung transisi yang mulus antar sumber media.
- MFPlay tidak mendukung pencampuran beberapa aliran video.
- Hanya format media yang didukung secara asli di Media Foundation yang didukung oleh MFPlay. (Ini termasuk komponen Media Foundation pihak ketiga yang mungkin diinstal pada sistem.)
Topik terkait