Programujeme pre Android 24 / Multimediálny framework

0

Určite nie je neobvyklé, že Androidové zariadenia dokážu zobrazovať a prehrávať rôzne multimediálne súbory/streamy počnúc obrázkami, jednoduchými zvukmi či kompletnými hudobnými skladbami, až po videá. Tieto multimédiá môžu byť integrované priamo v aplikáciách (APK RAW local resources), uložené vo forme samostatných súborov (URI spracovávané pomocou Content Resolverov), alebo môžu byť streamované v sieťovom prostredí (externé URI). Ich spracovanie rieši API MediaPlayer (audio/video/stream player), resp. SoundPool a to v spolupráci s triedou AudioManager.

Obr. 1 Audio aplikačné programové rozhranie operačného systému Android

MediaPlayer

Vo viacerých častiach tohto seriálu sme si uviedli základnú charakteristiku OS Android, ktorou je riešenie časovo náročných úloh v asynchrónnom režime, tzn. na pozadí bez zdržiavania hlavného procesného vlákna aktivity. Metódy triedy MediaPlayer je rovnako vhodné (odporúčané) používať asynchrónnym spôsobom. Vyplýva to najmä z potreby načítania a dekódovania údajov pred ich samotným prehraním. Ďalším dôležitým aspektom je sledovanie interných stavov objektu uvedenej triedy. Táto podmienka vyplýva z požiadaviek jednotlivých operácií, ktoré môžu byť vykonané iba ak sa výkonný proces nachádza v konkrétnom stave. Štruktúru striktného stavového stroja je možno naštudovať na portáli určenom pre vývojárov Androidových aplikácií (developer.android.com).

Jednou z možností použitia triedy MediaPlayer je aj prehrávanie multimédií na pozadí s využitím systému služieb (services). V tomto prípade však musíme reagovať na prípadné pozastavenie aktivity systémom Android pri prechode zariadenia do režimu spánku (sleep). Tomu zabránime pomocou tzv. „wake-lock“ signalizácie. Nesmieme pritom zabudnúť na fakt, že aplikácie bežiace na pozadí v období spánku zariadenia znižujú percento nabitia jeho akumulátora.

Stavy objektu triedy MediaPlayer

Na hore uvedenom „vývojárskom“ portáli systému Android je okrem iného uvedený kompletný zoznam metód, ktoré môžu, resp. nemôžu byť volané pri konkrétnych stavoch objektu triedy MediaPlayer. Pre korektné použitie musí byť tento objekt v stave Prepared, ktorý dosiahneme dvoma spôsobmi – spustením metód:

1. prepare() – synchrónny prechod do stavu Prepared ihneď po ukončení tejto metódy,

2. prepareAsync() – asynchrónny prechod kontrolovaný volaním používateľom implementovanej metódy onPrepared() rozhrania OnPreparedListener.

Samotný štart prehrávania zabezpečíme pomocou metódy start(). Po jej úspešnom vykonaní prejde objekt triedy MediaPlayer do stavu Started. Následne môžeme použiť metódu pause() na asynchrónne pozastavenie, resp. metódu stop() na zastavenie prehrávania. Pozíciu prehrávania môžeme zmeniť pomocou asynchrónnej metódy seekTo(). Opakovanie prehrávania nastavujeme metódou setLooping(). Z ďalších metód, ktoré deklaruje trieda MediaPlayer, sa ďalej určite stretneme s metódami reset() a release(). Prvá z nich je určená na prechod objektu do neinicializovaného stavu čo znamená, že objekt je nutné opakovane inicializovať pomocou nastavenia zdroja údajov a volania metódy prepare(). Metóda release() je určená na uvoľnenie alokovaných zdrojov a to v prípade ak objekt nemienime ďalej používať. Objekt sa takto dostane do konečného stavu End.

MediaPlayer focus

Systém Android riadi možné konkurentné prehrávanie multimédií pomocou prideľovania tzv. audio focusu (zámeru). Aktivita môže prehrávať médiá iba v prípade ak má pridelený focus. V opačnom prípade by mala prehrávanie buď ukončiť, alebo patrične znížiť hlasitosť (loudness). Toto správanie síce nie je systémom vynucované, avšak považuje sa za „ohľaduplné“ voči iným konkurenčne bežiacim aktivitám.

SoundPool

Trieda SoundPool nahráva médiá asynchrónne v samostatnom vlákne a oproti triede MediaPlayer, ktorá je určená na prehrávanie objemovo väčších súborov (napr. kompletných hudobných skladieb), je trieda SoundPool vhodná na prehrávanie krátkych zvukov (napr. zvukových efektov). Ide o objemovo malé médiá formátov OGG, MP3, alebo súbory bez kompresie. Pokiaľ je to možné a objekt triedy nepreplníme veľkým množstvom údajov, trieda uloží všetky načítané médiá do pamäte počítača v nekompresovanej forme vhodnej pre rýchle spracovanie.

Výrazným rozdielom voči triede MediaPlayer je možnosť prehrať jednotlivé zvukové vzorky simultánne. Každopádne pretože hardvéru určitý čas trvá pokiaľ korektne načíta a dekóduje obsah všetkých súborov, pre ich korektné prehranie je vždy nutné implementovať a volať callback metódu (listener) rozhrania OnLoadCompleteListener(). Pokiaľ sa pokúsime prehrať zvuk pred dokončením jeho dekódovania, zariadenie zostane umlčané (muted).

Prehrávanie zvukov pomocou SoundPool

Inštanciu (objekt) triedy SoundPool vytvoríme pomocou tzv. builder triedy SoundPool.Builder. Po načítaní zvukov pomocou príslušného variantu metódy int soundID load(), môžeme zvuky prehrať pomocou metódy int streamID play(), ktorá pracuje s nasledujúcimi parametrami:

parameter

súvisiaca metóda

význam

int soundID

play(soundID)

unload(soundID)

identifikátor zvuku získaný metódou load()

float leftVolume, rightVolume

setVolume(streamID)

hlasitosť streamu (ľavého/pravého kanála)

int priority

setPriority(streamID)

priorita streamu v prípade prekročenia maximálneho počtu streamov definovaných pomocou setMaxStreams()

int loop

setLoop(streamID)

počet opakovaní, resp. nekonečné prehrávanie zvukov až do explicitného volania metódy stop()

float rate

setRate(streamID)

zmena frekvencie (rýchlosti) prehrávania

Identifikátor streamID je parametrom následne používaných metód pause() - pozastavenie prehrávania, resume() - spustenie pozastaveného prehrávania a stop() - zastavenie prehrávania. Na odstránenie zvuku zo soundID použijeme metódu unload(). Podobne ako v prípade MediaPlayer zdroje alokované objektom triedy SoundPool uvoľníme pomocou metódy release().

Zobrazit Galériu

Marek Sopko

Všetky autorove články

Pridať komentár

Mohlo by vás zaujímať

Mohlo by vás zaujímať