V tomto článku si ukážeme, jak vytvořit vlastní přehrávač multimediálních souborů pomocí rozhraní MCI (Media Control Interface).
Příkazy MCI nám umožňují relativně jednoduchým způsobem, bez použití prvku ActiveX MediaPlayer (nebo jiných „externích“ prvků), aplikovat funkce přehrávače (ale i záznamu), včetně takových možností, jako je ovládání rychlosti přehrávání, zoom apod.
Jaké typy multimediálních souborů lze tímto způsobem přehrávat? Zjednodušeně lze říci, že jakékoli, pro které máme v systému nainstalován příslušný kodek.
Abychom mohli v projektu použít zmíněné MCI funkce, musíme do zdrojového kódu přidat hlavičkový soubor vfw.h (video for windows) a do projektu přidat knihovnu vfw32.lib.
Obvyklým způsobem použití MCI rozhraní je vytvoření okna třídy MCIWndClass, kde pak můžeme posílat příslušné zprávy, jež řídí přehrávání klipu. Kromě přímého posílání zpráv (funkcí SendMessage) můžeme použít sady MCI maker, které nám „zapouzdřují“ tyto zprávy.
Pro vytvoření zmíněného MCI okna můžeme použít funkci
HWND MCIWndCreate(
HWND hwndParent, // “rodičovské” okna
HINSTANCE hInstance, // handle instance
DWORD dwStyle, // styl okna
LPSTR szFile // jméno multimediálního souboru
);
Parametr dwStyle určuje další styly okna specifické pro MCI okna. Úplný přehled možných hodnot s jejich popisem naleznete v dokumentaci (MSDN). Parametrem hwndParent můžeme určit, zda má okno přehrávače být samostatným „top-level“ oknem (když neuvedeme handle rodičovského okna – tedy uvedeme hodnotu NULL), nebo zda má běžet jako „dětské okno“ uvedeného okna naší aplikace. Pomocí parametru dwStyle máme pak například možnost specifikovat, zda se má zobrazovat panel umožňující uživateli ovládat funkce přehrávače přímo, tedy aniž bychom museli v programu vytvářet vlastní ovládací interface. Když v parametru dwStyle uvedeme hodnotu MCIWNDF_NOPLAYBAR, tento řídící panel se nebude zobrazovat. Dále můžeme pomocí hodnot MCIWNDF_SHOWxxxx určit, jaké informace o přehrávaném souboru a stavu přehrávání se mají v okně zobrazovat. Máme na výběr z těchto hodnot:
- MCIWNDF_SHOWMODE – v titulkovém pruhu okna (pokud přehrávač běží jako samostatné okno) se zobrazuje aktuální stav „přehrávání“, tedy např. zda se přehrává, zda je pauza atd.
- MCIWNDF_SHOWNAME – zobrazuje v titulkovém pruhu jméno přehrávaného souboru.
- MCIWNDF_SHOWPOS – zobrazuje aktuální pozici v souboru
- MCIWNDF_SHOWALL – tímto jedním parametrem můžeme specifikovat všechny 3 uvedené styly současně.
Pokud uvedeme přímo v této funkci parametr szFile jako platný multimediální soubor, přehrávání se spustí bezprostředně. Máme však také možnost pouze vytvořit okno přehrávače, soubor neuvádět a teprve později použít makro
LONG MCIWndOpen(
hwnd,
szFile,
wFlags
);
kde hwnd je handle MCI okna vytvořeného nejčastěji předchozím voláním funkce MCIWndCreate.
Pro vlastní programové ovládání přehrávače máme k dispozici několik maker (která odesílají příslušné funkce, což můžeme realizovat přímo, jak jsem se již zmínil). Jsou to hlavně makra:
LONG MCIWndPlay(hwnd );
LONG MCIWndPause(hwnd );
LONG MCIWndStop(hwnd );
Dále můžeme upřesnit rozsah přehrávané části například pomocí makra, které přehraje část klipu specifikovanou pozicemi „od“ a „do“:
LONG MCIWndPlayFromTo(
hwnd,
lStart,
lEnd
);
Ukažme si nyní prakticky vytvoření jednoduchého přehrávače multimediálních souborů, který bude kromě již zmíněných možností umět specifikovat zoom, rychlost přehrávání a hlasitost.
Ukázkový projekt je MFC aplikace založená na dialogu. Přidáme si novou třídu „Generic Class“, která bude představovat náš přehrávač (CRPJPlayer). Přidáme si následují členské proměnné a funkce:
class CRPJPlayer
{
public:
CRPJPlayer();
virtual ~CRPJPlayer();
public:
BOOL ResetAll();
BOOL m_ShowPlaybar;
BOOL m_ShowAll;
BOOL VolumeDown(LONG step = 100);
BOOL VolumeUp(LONG step = 100);
BOOL Pause();
BOOL Play();
BOOL Stop();
LRESULT SendMessage(UINT Msg, WPARAM wParam, LPARAM lParam);
BOOL SpeedDown(LONG step = 100);
BOOL SpeedUp(LONG step = 100);
BOOL ZoomOut(UINT step = 10);
BOOL ZoomIn(UINT step = 10);
BOOL m_AutoPlay;
BOOL Close();
BOOL Open(LPCTSTR lpFileName, HWND hwndParent = NULL);
protected:
LONG m_volume;
LONG m_speed;
UINT m_zoom;
HWND m_hwnd;
};
Funkce Open bude integrovat vytvoření a spuštění klipu. V případě, že bude proměnná m_AutoPlay nastavena na TRUE, přehrávání se spustí ihned po vytvoření MCI okna.
BOOL CRPJPlayer::Open(LPCTSTR lpFileName, HWND hwndParent)
{
if ( m_hwnd != NULL )
if ( !Close() )
return FALSE;
DWORD dwStyle = 0;
if ( m_ShowAll )
dwStyle |= MCIWNDF_SHOWALL;
if ( !m_ShowPlaybar )
dwStyle |= MCIWNDF_NOPLAYBAR;
m_hwnd = MCIWndCreate(hwndParent, AfxGetInstanceHandle(),
dwStyle, lpFileName);
if ( m_AutoPlay )
MCIWndPlay(m_hwnd);
return TRUE;
}
Dále si vytvoříme funkce na zvýšení a snížení zoomu. Normální velikost je určena hodnotou 100. Následující funkce budou zvyšovat nebo snižovat hodnotu zoomu a určený krok, v případě neuvedení hodnoty kroku použijeme hodnotu 10:
BOOL CRPJPlayer::ZoomIn(UINT step)
{
if ( m_hwnd == NULL )
return FALSE;
m_zoom += step;
MCIWndSetZoom(m_hwnd, m_zoom);
return TRUE;
}
BOOL CRPJPlayer::ZoomOut(UINT step)
{
if ( m_hwnd == NULL )
return FALSE;
if ( m_zoom <= step )
return FALSE;
m_zoom -= step;
MCIWndSetZoom(m_hwnd, m_zoom);
return TRUE;
}
Podobně je tomu s rychlostí přehrávání, s tím rozdílem, že zde je normální hodnota rychlosti rovna 1000.
BOOL CRPJPlayer::SpeedUp(LONG step)
{
if ( m_hwnd == NULL )
return FALSE;
if ( m_speed <= step )
return FALSE;
m_speed += step;
return ( MCIWndSetSpeed(m_hwnd, m_speed) == 0);
}
BOOL CRPJPlayer::SpeedDown(LONG step)
{
if ( m_hwnd == NULL )
return FALSE;
m_speed -= step;
return ( MCIWndSetSpeed(m_hwnd, m_speed) == 0);
}
Nakonec si ještě vytvořme obdobným způsobem funkce pro ovládání hlasitosti:
BOOL CRPJPlayer::VolumeUp(LONG step)
{
if ( m_hwnd == NULL )
return FALSE;
m_volume += step;
return ( MCIWndSetVolume(m_hwnd, m_volume) == 0);
}
BOOL CRPJPlayer::VolumeDown(LONG step)
{
if ( m_hwnd == NULL )
return FALSE;
if ( m_volume <= step )
return FALSE;
m_volume += step;
return ( MCIWndSetVolume(m_hwnd, m_volume) == 0);
}
Základní funkce pro ovládání přehrávání, tedy spuštění, zastavení a pauza, vypadají takto:
BOOL CRPJPlayer::Stop()
{
return ( MCIWndStop(m_hwnd) == 0);
}
BOOL CRPJPlayer::Play()
{
return ( MCIWndPlay(m_hwnd) == 0);
}
BOOL CRPJPlayer::Pause()
{
return ( MCIWndPause(m_hwnd) == 0);
}
Na závěr si přidáme ještě funkci, která nám nastaví výchozí hodnoty zoomu, rychlosti a hlasitosti:
BOOL CRPJPlayer::ResetAll()
{
BOOL bResult = TRUE;
m_speed = 1000; // normální rychlost
if ( MCIWndSetSpeed(m_hwnd, m_speed) != 0)
bResult = FALSE;
m_volume = 1000; // normální hlasitost
if ( MCIWndSetVolume(m_hwnd, m_volume) != 0)
bResult = FALSE;
m_zoom = 100; // skutečná velikost
MCIWndSetZoom(m_hwnd, m_zoom); // toto makro nevrací informaci o chybě :-(
return bResult;
}
Zde si můžete stáhnout ukázkový příklad: mci_player.zip (37 kB)