Snímek obrazovky: Aplikace YouTube pro Android
ExoPlayer je multimediální přehrávač na úrovni aplikace postavený nad nízkoúrovňovými rozhraními API pro média v systému Android. ExoPlayer má oproti vestavěnému MediaPlayeru v systému Android řadu výhod. Podporuje mnoho stejných mediálních formátů jako MediaPlayer a navíc adaptivní formáty, například DASH a SmoothStreaming. Přehrávač ExoPlayer je vysoce přizpůsobitelný a rozšiřitelný, takže umožňuje mnoho pokročilých případů použití. Jedná se o projekt s otevřeným zdrojovým kódem, který používají aplikace Google, včetně YouTube a Google Play Movies & TV.
- Předpoklady
- Co budete dělat
- Co budete potřebovat
- Získání kódu
- Struktura adresáře
- Import počátečního projektu
- app/build.gradle
- Přidejte závislost ExoPlayer
- player-lib/build.gradle
- Přidejte prvek PlayerView
- activity_player.xml
- PlayerActivity.java
- Vytvoření ExoPlayeru
- PlayerActivity.java
- Vytvořte mediální prvek
- PlayerActivity.java
- Pěkně si pohrát s životním cyklem Activity
- PlayerActivity.java
- PlayerActivity.java
- PlayerActivity.java
- PlayerActivity.java
- Závěrečná příprava
- PlayerActivity.java
- Přehrát zvuk
- Test životního cyklu aktivity
- Přehrávání videa
- PlayerActivity.java
- PlayerActivity.java
- Adaptivní výběr stop
- PlayerActivity.java
- Sestavení adaptivního MediaItem
- PlayerActivity.java
- Další adaptivní formáty streamování
- Poslouchat
- PlayerActivity.java
- PlayerActivity.java
- PlayerActivity.java
- Registrujte svého posluchače
- PlayerActivity.java
- PlayerActivity.java
- Jděte hlouběji
- activity_player.xml
- activity_player.xml
- Přizpůsobte chování
- activity_player.xml
- Přizpůsobení vzhledu
- activity_player.xml
- custom_player_control_view.xml
- custom_player_control_view.xml
- Přepsat výchozí styl
- activity_player.xml
- exo_player**_control_view.xml**
- Další informace
Předpoklady
- Mírná znalost vývoje pro Android a Android Studio
Co budete dělat
- Vytvoříte instanci
SimpleExoPlayer
, která připravuje a přehrává média z různých zdrojů. - Integrujte přehrávač ExoPlayer s životním cyklem aktivity aplikace, abyste mohli podporovat přehrávání na pozadí, v popředí a obnovení přehrávání v prostředí jednoho nebo více oken.
- Pomocí
MediaItem
vytvoříte seznam skladeb. - Přehrávat adaptivní videostreamy, které přizpůsobují kvalitu médií dostupné šířce pásma.
- Registrovat posluchače událostí pro sledování stavu přehrávání a ukázat, jak lze posluchače použít k měření kvality přehrávání.
- Používejte standardní komponenty uživatelského rozhraní ExoPlayer a poté je přizpůsobte stylu své aplikace.
Co budete potřebovat
- Android Studio verze 3.5 nebo vyšší
- Zařízení se systémem Android s JellyBean (4.1) nebo vyšší, ideálně s Nougatem (7.1) nebo vyšším, protože podporuje více oken.
Získání kódu
Chcete-li začít, stáhněte si projekt Android Studio:
Stáhnout zip
Alternativně můžete klonovat repozitář GitHub:
git clone https://github.com/googlecodelabs/exoplayer-intro.git
Struktura adresáře
Klonováním nebo rozbalením získáte kořenovou složku (exoplayer-intro
), která obsahuje jednu složku pro každý krok tohoto codelabu spolu se všemi potřebnými zdroji:
/PATH/TO/YOUR/FOLDER/exoplayer-intro/exoplayer-codelab-00/PATH/TO/YOUR/FOLDER/exoplayer-intro/exoplayer-codelab-01/PATH/TO/YOUR/FOLDER/exoplayer-intro/exoplayer-codelab-02/PATH/TO/YOUR/FOLDER/exoplayer-intro/exoplayer-codelab-03/PATH/TO/YOUR/FOLDER/exoplayer-intro/exoplayer-codelab-04
Složky exoplayer-codelab-N
(kde N
jsou 00
až 04
) obsahují požadovaný konečný stav každého kroku tohoto codelabu. Jedná se o samostatné projekty aplikace Android Studio, z nichž každý lze importovat.
Import počátečního projektu
- Spustit aplikaci Android Studio.
- Zvolit Soubor > Nový > Importovat projekt*.*
- Importovat počáteční projekt z
exoplayer-codelab-00
.
Snímek obrazovky: Struktura projektu při importu
Po dokončení sestavení se zobrazí dva moduly: modul app
(typu aplikace) a modul player-lib
(typu knihovna). Modul app
je ve skutečnosti prázdný, má pouze manifest. Vše z modulu player-lib
se sloučí při sestavování aplikace pomocí závislosti gradle v app/build.gradle
.
app/build.gradle
dependencies { implementation project(":player-lib")}
Vaše aktivita multimediálního přehrávače je uložena v modulu player-lib
. Důvodem pro její uchovávání v samostatném modulu knihovny je možnost jejího sdílení mezi soubory APK zaměřenými na různé platformy, například mobilní a Android TV. Umožňuje vám to také využívat funkce, jako je Dynamické doručování, které umožňují, aby se vaše funkce přehrávání médií nainstalovala pouze tehdy, když ji uživatel potřebuje.
- Deployujte a spusťte aplikaci, abyste zkontrolovali, zda je vše v pořádku. Aplikace by měla vyplnit obrazovku s černým pozadím.
Snímek obrazovky: Prázdná aplikace běží
Přidejte závislost ExoPlayer
ExoPlayer je open source projekt hostovaný na GitHubu. Každé vydání je distribuováno prostřednictvím jCenter, což je jeden z výchozích repozitářů balíčků používaných aplikacemi Android Studio a Gradle. Každé vydání je jednoznačně identifikováno řetězcem v následujícím formátu:
com.google.android.exoplayer:exoplayer:rX.X.X
Přehrávač ExoPlayer můžete do svého projektu přidat jednoduše importem jeho tříd a komponent uživatelského rozhraní. Je poměrně malý, má zmenšenou stopu asi 70 až 300 kB v závislosti na zahrnutých funkcích a podporovaných formátech. Knihovna ExoPlayer je rozdělena do modulů, aby vývojáři mohli importovat pouze ty funkce, které potřebují. Další informace o modulární struktuře ExoPlayeru najdete v části Přidání modulů ExoPlayeru.
- Otevřete soubor
build.gradle
moduluplayer-lib
. - Přidejte následující řádky do sekce
dependencies
a synchronizujte projekt.
player-lib/build.gradle
dependencies { implementation 'com.google.android.exoplayer:exoplayer-core:2.12.0'implementation 'com.google.android.exoplayer:exoplayer-dash:2.12.0'implementation 'com.google.android.exoplayer:exoplayer-ui:2.12.0'}
Přidejte prvek PlayerView
- Otevřete soubor layout resource
activity_player.xml
z moduluplayer-lib
. - Umístěte kurzor do prvku
FrameLayout
. - Začněte psát
<PlayerView
a nechte Android Studio automaticky doplnit prvekPlayerView
. - Použijte
match_parent
prowidth
aheight
. - Deklarujte id jako
video_view
.
activity_player.xml
<com.google.android.exoplayer2.ui.PlayerView android:id="@+id/video_view" android:layout_width="match_parent" android:layout_height="match_parent"/>
Dále budete tento prvek uživatelského rozhraní označovat jako zobrazení videa.
- V třídě
PlayerActivity
nyní musíte najít zobrazení videa, abyste jej mohli správně nastavit v metoděonCreate
aktivity.
PlayerActivity.java
@Overrideprotected void onCreate(Bundle savedInstanceState) { playerView = findViewById(R.id.video_view);}
- Přidejte do třídy
PlayerActivity
pole členaplayerView
. Ujistěte se, že typ zobrazení jePlayerView
.
Poznámka: Pomocí funkce Quick Fix v aplikaci Android Studio přidáte členské pole automaticky. Nezapomeňte nastavit typ na
PlayerView
než výchozí
View
Snímek obrazovky: Rychlá oprava nabídky pro vytvoření členského pole
Vytvoření ExoPlayeru
Pro přehrávání streamovaných médií potřebujete objekt ExoPlayer
. Nejjednodušším způsobem jeho vytvoření je použití třídy SimpleExoPlayer.Builder
. Jak název napovídá, ta používá vzor builder k vytvoření instance SimpleExoPlayer
.
SimpleExoPlayer
je pohodlná, univerzální implementace rozhraní ExoPlayer
.
Přidejte soukromou metodu initializePlayer
pro vytvoření vašeho SimpleExoPlayer
.
PlayerActivity.java
private SimpleExoPlayer player;private void initializePlayer() { player = new SimpleExoPlayer.Builder(this).build(); playerView.setPlayer(player);}
Vytvořte SimpleExoPlayer.Builder
pomocí vašeho kontextu a pak zavolejte build
pro vytvoření vašeho objektu SimpleExoPlayer
. Ten pak přiřadíte objektu player
, který musíte deklarovat jako členské pole. Poté pomocí playerView.setPlayer
přiřadíte player
k příslušnému zobrazení.
Vytvořte mediální prvek
Váš player
nyní potřebuje nějaký obsah, který bude přehrávat. Za tímto účelem vytvoříte MediaItem
. Existuje mnoho různých typů MediaItem
, ale začněte tím, že vytvoříte jeden pro soubor MP3 na internetu.
Nejjednodušší způsob, jak vytvořit MediaItem
, je použít MediaItem.fromUri
, který přijímá URI mediálního souboru. Přidejte MediaItem
do player
pomocí player.setMediaItem
.
- Přidejte následující kód do
initializePlayer
:
PlayerActivity.java
private void initializePlayer() { MediaItem mediaItem = MediaItem.fromUri(getString(R.string.media_url_mp3)); player.setMediaItem(mediaItem);}
Všimněte si, že R.string.media_url_mp3
je definován jako https://storage.googleapis.com/exoplayer-test-media-0/play.mp3 v strings.xml
.
Pěkně si pohrát s životním cyklem Activity
Naše player
může zabírat spoustu prostředků včetně paměti, procesoru, síťových připojení a hardwarových kodeků. Mnohé z těchto prostředků jsou nedostatkové, zejména v případě hardwarových kodeků, kde může být k dispozici pouze jeden. Je důležité, abyste tyto prostředky uvolnili pro ostatní aplikace, aby je mohly používat, když je nepoužíváte, například když je vaše aplikace přepnuta na pozadí.
Jinak řečeno, životní cyklus vašeho přehrávače by měl být svázán s životním cyklem vaší aplikace. Abyste to mohli implementovat, musíte přepsat čtyři metody PlayerActivity
: onStart
, onResume
, onPause
a onStop
.
- Po otevření
PlayerActivity
klepněte na nabídku Code > Override methods…. - Zvolte
onStart
,onResume
,onPause
aonStop
. - Inicializujte přehrávač ve zpětném volání
onStart
neboonResume
v závislosti na úrovni API.
PlayerActivity.java
@Overridepublic void onStart() { super.onStart(); if (Util.SDK_INT >= 24) { initializePlayer(); }}@Overridepublic void onResume() { super.onResume(); hideSystemUi(); if ((Util.SDK_INT < 24 || player == null)) { initializePlayer(); }}
Android API úrovně 24 a vyšší podporuje více oken. Protože vaše aplikace může být viditelná, ale ne aktivní v režimu rozděleného okna, musíte přehrávač inicializovat v onStart
. Úroveň rozhraní Android API 24 a nižší vyžaduje, abyste počkali co nejdéle, než získáte prostředky, takže před inicializací přehrávače počkáte do onResume
.
- Přidejte metodu
hideSystemUi
.
PlayerActivity.java
@SuppressLint("InlinedApi")private void hideSystemUi() { playerView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);}
hideSystemUi
je pomocná metoda volaná v onResume
, která vám umožňuje celoobrazovkové prostředí.
- Uvolněte prostředky pomocí
releasePlayer
(kterou vytvoříte zanedlouho) vonPause
aonStop
.
PlayerActivity.java
@Overridepublic void onPause() { super.onPause(); if (Util.SDK_INT < 24) { releasePlayer(); }}@Overridepublic void onStop() { super.onStop(); if (Util.SDK_INT >= 24) { releasePlayer(); }}
Při úrovni API 24 a nižší není zaručeno, že bude zavolána onStop
, takže musíte hráče uvolnit co nejdříve v onPause
. S rozhraním API úrovně 24 a vyšší (které přineslo režim více a rozdělených oken) je volání onStop
zaručeno. V pozastaveném stavu je vaše aktivita stále viditelná, takže s uvolněním hráče počkáte až na onStop
.
Nyní musíte vytvořit metodu releasePlayer
, která uvolní prostředky hráče a zničí ho.
- Přidejte do aktivity následující kód:
PlayerActivity.java
private boolean playWhenReady = true;private int currentWindow = 0;private long playbackPosition = 0;private void releasePlayer() { if (player != null) { playWhenReady = player.getPlayWhenReady(); playbackPosition = player.getCurrentPosition(); currentWindow = player.getCurrentWindowIndex(); player.release(); player = null; }}
Před uvolněním a zničením přehrávače uložte následující informace:
- Stav přehrávání/pauzy pomocí
getPlayWhenReady
. - Aktuální pozice přehrávání pomocí
getCurrentPosition
. - Aktuální index okna pomocí
getCurrentWindowIndex
. Další informace o oknech naleznete v části Časová osa.
To umožňuje obnovit přehrávání od místa, kde uživatel skončil. Jediné, co musíte udělat, je dodat tyto informace o stavu při inicializaci přehrávače.
Závěrečná příprava
Jediné, co nyní musíte udělat, je dodat přehrávači informace o stavu uložené v releasePlayer
při inicializaci.
- Přidejte do souboru
initializePlayer
:
PlayerActivity.java
private void initializePlayer() { player.setPlayWhenReady(playWhenReady); player.seekTo(currentWindow, playbackPosition); player.prepare();}
Takto se děje:
-
setPlayWhenReady
říká přehrávači, zda má začít hrát, jakmile získá všechny zdroje pro přehrávání. ProtožeplayWhenReady
je zpočátkutrue
, přehrávání se spustí automaticky při prvním spuštění aplikace. -
seekTo
říká přehrávači, aby vyhledal určitou pozici v určitém okně. JakcurrentWindow
, takplaybackPosition
jsou inicializovány na nulu, takže přehrávání začne od samého začátku při prvním spuštění aplikace. -
prepare
říká přehrávači, aby získal všechny prostředky potřebné pro přehrávání.
Přehrát zvuk
Konečně jste hotovi! Spusťte aplikaci a přehrajte soubor MP3 a prohlédněte si vložené umělecké dílo.
Snímek obrazovky:
Test životního cyklu aktivity
Vyzkoušejte, zda aplikace funguje ve všech různých stavech životního cyklu aktivity.
- Spusťte jinou aplikaci a dejte svou aplikaci opět do popředí. Obnoví se ve správné pozici?“
- Pozastavte aplikaci a přesuňte ji do pozadí a poté opět do popředí. Zůstane v pozastaveném stavu, když je v pozastaveném stavu na pozadí?
- Přemístěte aplikaci. Jak se chová, když změníte orientaci ze svislé na vodorovnou a zpět?
Přehrávání videa
Pokud chcete přehrávat video, je to stejně snadné jako úprava URI položky média na soubor MP4.
- Změňte URI v
initializePlayer
naR.string.media_url_mp4
. - Znovu spusťte aplikaci a vyzkoušejte chování po jejím spuštění na pozadí i s přehráváním videa.
PlayerActivity.java
private void initializePlayer() { MediaItem mediaItem = MediaItem.fromUri(getString(R.string.media_url_mp3)); }
Všechno dělá PlayerView
. Místo uměleckého díla se video vykresluje na celou obrazovku.
Snímek obrazovky: Aplikace přehrává video.
Jste skvělí! Právě jste vytvořili aplikaci pro streamování médií na celou obrazovku v systému Android, doplněnou o správu životního cyklu, uložený stav a ovládací prvky uživatelského rozhraní!
Vaše současná aplikace přehrává jeden mediální soubor, ale co když chcete přehrávat více mediálních souborů, jeden po druhém? K tomu potřebujete seznam skladeb.
Seznamy skladeb lze vytvořit přidáním dalších MediaItem
do player
pomocí addMediaItem
. To umožňuje plynulé přehrávání a vyrovnávací paměť se zpracovává na pozadí, takže uživatel při změně položek médií nevidí točítko vyrovnávací paměti.
- Přidejte následující kód do
initializePlayer
:
PlayerActivity.java
private void initializePlayer() { player.setMediaItem(mediaItem); // Existing code MediaItem secondMediaItem = MediaItem.fromUri(getString(R.string.media_url_mp3)); player.addMediaItem(secondMediaItem); }
Zkontrolujte, jak se chovají ovládací prvky přehrávače. Pomocí a můžete procházet posloupnost položek médií.
Snímek obrazovky: Ovládací prvky přehrávání zobrazují tlačítko další a předchozí
To je docela šikovné! Další informace naleznete v dokumentaci pro vývojáře k položkám médií a seznamům skladeb a v tomto článku o rozhraní API seznamu skladeb.
Adaptivní streamování je technika pro streamování médií pomocí změny kvality streamu v závislosti na dostupné šířce pásma sítě. Uživatel tak může využívat média v nejlepší kvalitě, kterou mu umožňuje šířka pásma.
Typicky je stejný mediální obsah rozdělen do více stop s různou kvalitou (bitovou rychlostí a rozlišením). Přehrávač vybírá stopu na základě dostupné šířky pásma sítě.
Každá stopa je rozdělena na části o dané délce, obvykle mezi 2 a 10 sekundami. To umožňuje přehrávači rychle přepínat mezi stopami podle toho, jak se mění dostupná šířka pásma. Přehrávač je zodpovědný za spojování těchto částí dohromady pro plynulé přehrávání.
Adaptivní výběr stop
Jádrem adaptivního streamování je výběr nejvhodnější stopy pro aktuální prostředí. Aktualizujte svou aplikaci pro přehrávání adaptivních streamovaných médií pomocí adaptivního výběru stop.
- Aktualizujte
initializePlayer
pomocí následujícího kódu:
PlayerActivity.java
private void initializePlayer() { if (player == null) { DefaultTrackSelector trackSelector = new DefaultTrackSelector(this); trackSelector.setParameters( trackSelector.buildUponParameters().setMaxVideoSizeSd()); player = new SimpleExoPlayer.Builder(this) .setTrackSelector(trackSelector) .build(); } // Remove or comment out. // player = new SimpleExoPlayer.Builder(this).build(); }
Nejprve vytvořte DefaultTrackSelector
, který je zodpovědný za výběr stop v položce médií. Pak řekněte svému trackSelector
, aby vybíral pouze stopy se standardním nebo nižším rozlišením – dobrý způsob, jak ušetřit uživatelská data na úkor kvality. Nakonec předejte svůj trackSelector
sestavovateli, aby byl použit při sestavování instance SimpleExoPlayer
.
Sestavení adaptivního MediaItem
DASH je široce používaný formát adaptivního streamování. Chcete-li streamovat obsah DASH, musíte vytvořit MediaItem
jako dříve. Tentokrát však musíme použít MediaItem.Builder
namísto fromUri
.
Je to proto, že fromUri
používá příponu souboru k určení základního formátu média, ale náš URI DASH příponu souboru nemá, takže při konstrukci MediaItem
musíme zadat typ MIME APPLICATION_MPD
.
- Aktualizujte
initializePlayer
takto:
PlayerActivity.java
private void initializePlayer() { // Replace this line MediaItem mediaItem = MediaItem.fromUri(getString(R.string.media_url_mp4)); // With this MediaItem mediaItem = new MediaItem.Builder() .setUri(getString(R.string.media_url_dash)) .setMimeType(MimeTypes.APPLICATION_MPD) .build(); // Also remove the following lines MediaItem secondMediaItem = MediaItem.fromUri(getString(R.string.media_url_mp3)); player.addMediaItem(secondMediaItem);}
- Znovu spusťte aplikaci a uvidíte adaptivní streamování videa pomocí DASH v akci. S přehrávačem ExoPlayer je to docela snadné!
Další adaptivní formáty streamování
HLS (MimeTypes.APPLICATION_M3U8
) a SmoothStreaming (MimeTypes.APPLICATION_SS
) jsou další běžně používané adaptivní formáty streamování, které přehrávač ExoPlayer podporuje. Další informace o konstrukci dalších adaptivních mediálních zdrojů naleznete v ukázkové aplikaci ExoPlayer.
V předchozích krocích jste se naučili streamovat progresivní a adaptivní mediální streamy. Přehrávač ExoPlayer za vás v zákulisí odvádí spoustu práce, včetně následující:
- Alokování paměti
- Stahování souborů kontejneru
- Vytahování metadat z kontejneru
- Dekódování dat
- Vyobrazení videa, zvuku a textu na obrazovku a do reproduktorů
Někdy je užitečné vědět, co přehrávač ExoPlayer za běhu dělá, abyste pochopili a zlepšili zážitek z přehrávání pro své uživatele.
Například můžete chtít reflektovat změny stavu přehrávání v uživatelském rozhraní následujícími způsoby:
- Zobrazení načítacího spinneru, když přehrávač přejde do stavu vyrovnávací paměti
- Zobrazení překryvného okna s možností „sledovat další“, když skladba skončila
ExoPlayer nabízí několik rozhraní posluchačů, která poskytují zpětná volání pro užitečné události. Pomocí posluchače můžete zaznamenat, v jakém stavu se přehrávač nachází.
Poslouchat
- Deklarovat soukromý člen typu
PlaybackStateListener
vPlayerActivity
. - Vytvořit konstantu
TAG
, kterou později použijete pro zaznamenávání.
PlayerActivity.java
private PlaybackStateListener playbackStateListener;private static final String TAG = PlayerActivity.class.getName();
- Vytvořte
playbackStateListener
na začátkuonCreate
(zatím se nezkompiluje, ale to brzy napravíte).
PlayerActivity.java
@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_player); playbackStateListener = new PlaybackStateListener();
- Pomocí Quick Fix automaticky vytvořte vnitřní třídu
PlaybackStateListener
.
Screenshot: Nabídka Rychlá oprava pro vytvoření chybějící třídy
- Doplňte rozhraní
Player.EventListener
. To slouží k informování o důležitých událostech přehrávače, včetně chyb a změn stavu přehrávání. - Překryjte
onPlaybackStateChanged
přidáním následujícího kódu:
PlayerActivity.java
private class PlaybackStateListener implements Player.EventListener { @Override public void onPlaybackStateChanged(int playbackState) { String stateString; switch (playbackState) { case ExoPlayer.STATE_IDLE: stateString = "ExoPlayer.STATE_IDLE -"; break; case ExoPlayer.STATE_BUFFERING: stateString = "ExoPlayer.STATE_BUFFERING -"; break; case ExoPlayer.STATE_READY: stateString = "ExoPlayer.STATE_READY -"; break; case ExoPlayer.STATE_ENDED: stateString = "ExoPlayer.STATE_ENDED -"; break; default: stateString = "UNKNOWN_STATE -"; break; } Log.d(TAG, "changed state to " + stateString); }}
onPlaybackStateChanged
je voláno při změně stavu přehrávání. Nový stav je dán parametrem playbackState
.
Přehrávač může být v jednom z následujících čtyř stavů:
State |
Popis |
|
Přehrávač byl instancován, ale ještě nebyl připraven. |
|
Přehrávač není schopen hrát z aktuální pozice, protože nebyl připraven dostatek dat do vyrovnávací paměti. |
|
Přehrávač je schopen okamžitě hrát z aktuální pozice. To znamená, že přehrávač začne automaticky přehrávat média, pokud je vlastnost playWhenReady přehrávače |
|
Přehrávač dokončil přehrávání médií. |
Registrujte svého posluchače
Chcete-li, aby vaše zpětná volání byla volána, musíte zaregistrovat svůj playbackStateListener
přehrávač. To udělejte v initializePlayer
.
- Zaregistrujte posluchače před přípravou přehrávání.
PlayerActivity.java
private void initializePlayer() { if (player == null) { player.addListener(playbackStateListener); player.prepare();}
Znovu musíte udělat pořádek, abyste se vyhnuli visícím referencím z přehrávače, které by mohly způsobit únik paměti.
- Odstraňte posluchače v
releasePlayer
:
PlayerActivity.java
private void releasePlayer() { if (player != null) { player.removeListener(playbackStateListener); player.release(); player = null; }}
- Otevřete logcat a spusťte aplikaci.
- Pro vyhledávání, pozastavení a obnovení přehrávání použijte ovládací prvky uživatelského rozhraní. V protokolech byste měli vidět změnu stavu přehrávání.
Jděte hlouběji
ExoPlayer nabízí řadu dalších posluchačů, kteří jsou užiteční pro pochopení zkušeností uživatele s přehráváním. K dispozici jsou posluchači pro zvuk a video a také AnalyticsListener
, který obsahuje zpětná volání všech posluchačů. Mezi nejdůležitější metody patří následující:
-
onRenderedFirstFrame
je volána při vykreslení prvního snímku videa. Pomocí ní můžete vypočítat, jak dlouho musel uživatel čekat, než se na obrazovce zobrazil smysluplný obsah. -
onDroppedVideoFrames
je volána, když byly vypuštěny snímky videa. Zahozené snímky znamenají, že přehrávání je trhané a uživatelský zážitek bude pravděpodobně špatný. -
onAudioUnderrun
je voláno, když došlo k nedotažení zvuku. Underrun způsobuje slyšitelné záškuby zvuku a je patrnější než vypadlé snímky videa.
AnalyticsListener
lze přidat k player
pomocí addAnalyticsListener
. Existují také odpovídající metody pro posluchače zvuku a videa.
Přemýšlejte, jaké události jsou pro vaši aplikaci a uživatele důležité. Další informace naleznete v části Naslouchání událostem přehrávače. To je k posluchačům událostí vše!“
Dosud jste používali PlayerControlView
přehrávač ExoPlayer k zobrazení ovladače přehrávání uživateli.
Snímek obrazovky: Výchozí ovladač přehrávání
Co když chcete změnit funkčnost nebo vzhled těchto ovládacích prvků? Naštěstí jsou tyto ovladače velmi dobře přizpůsobitelné.
První jednoduché přizpůsobení je ovladač vůbec nepoužívat. To lze snadno provést pomocí atributu use_controller
na elementu PlayerView
uvnitř activity_player.xml
.
- Nastavte
use_controller
nafalse
a ovládací prvek se již nezobrazí:
activity_player.xml
<com.google.android.exoplayer2.ui.PlayerView app:use_controller="false"/>
- Přidejte do svého
FrameLayout
následující jmenný prostor:
activity_player.xml
<FrameLayout xmlns:app="http://schemas.android.com/apk/res-auto">
Zkuste to nyní.
Přizpůsobte chování
PlayerControlView
má několik atributů, které ovlivňují jeho chování. Pomocí show_timeout
, fastforward_increment
a rewind_increment
můžete přizpůsobit chování ovladače.
- Odstraňte
app:use_controller="false"
. - Změňte zobrazení hráče tak, aby používalo
show_timeout
,fastforward_increment
arewind_increment
:
activity_player.xml
<com.google.android.exoplayer2.ui.PlayerView android:id="@+id/video_view" android:layout_width="match_parent" android:layout_height="match_parent" app:show_timeout="10000" app:fastforward_increment="30000" app:rewind_increment="30000"/>
- Hodnota
show_timeout
udáváPlayerView
zpoždění v milisekundách, než se ovládací prvek skryje po poslední interakci uživatele s ním. - Hodnoty
fastforward_increment
arewind_increment
říkají přehrávači dobu v milisekundách, za kterou se přeskočí vpřed nebo vzad, když uživatel klepne na tlačítko pro rychlé přetáčení vpřed nebo vzad.
Atributy PlayerControlView
lze také nastavit programově.
Přizpůsobení vzhledu
No, to je dobrý začátek. Ale co když chcete, aby PlayerControlView
vypadal jinak nebo aby se změnilo, která tlačítka se zobrazují? Implementace PlayerControlView
nepředpokládá existenci žádných tlačítek, takže je lze snadno odstranit a přidat nová.
Podívejte se, jak můžete PlayerControlView
přizpůsobit.
- Vytvořte nový soubor rozvržení
custom_player_control_view.xml
ve složceplayer-lib/res/layout/
. - V kontextové nabídce složky rozvržení vyberte Nový – Soubor prostředků rozvržení a pojmenujte jej
custom_player_control_view.xml
.
Snímek obrazovky:
- Zde zkopírujte původní soubor rozvržení do
custom_player_control_view.xml
. - Odstraňte prvky
ImageButton
s id@id/exo_prev
a@id/exo_next
.
Chcete-li použít vlastní rozvržení, musíte nastavit atribut app:controller_layout_id
elementu PlayerView
v souboru activity_player.xml
.
- Použijte ID rozvržení vlastního souboru jako v následujícím úryvku kódu:
activity_player.xml
<com.google.android.exoplayer2.ui.PlayerView android:id="@+id/video_view" android:layout_width="match_parent" android:layout_height="match_parent" app:controller_layout_id="@layout/custom_player_control_view"/>
- Znovu spusťte aplikaci. Zobrazení ovládání hráče již nemá tlačítka předchozí a další.
Snímek obrazovky: Vlastní zobrazení ovládání přehrávače bez tlačítek předchozí a další
V souboru rozvržení můžete použít libovolné změny. Ve výchozím nastavení jsou zvoleny barvy motivu Android. Můžete je přepsat tak, aby odpovídaly designu vaší aplikace.
- Přidejte ke každému elementu
ImageButton
atributandroid:tint
:
custom_player_control_view.xml
<ImageButton android:id="@id/exo_rew" android:tint="#FF00A6FF" style="@style/ExoMediaButton.Rewind"/>
- Změňte všechny atributy
android:textColor
, které najdete ve vlastním souboru, na stejnou barvu:#FF00A6FF
.
custom_player_control_view.xml
<TextView android:id="@id/exo_position" android:textColor="#FF00A6FF"/><TextView android:id="@id/exo_duration" android:textColor="#FF00A6FF"/>
- Spustit aplikaci. Nyní máte krásné barevné komponenty uživatelského rozhraní!
Snímek obrazovky:
Přepsat výchozí styl
Právě jste vytvořili vlastní soubor rozvržení a odkázali na něj pomocí controller_layout_id
v activity_player.xml
.
Jiný přístup je přepsat výchozí soubor rozvržení, který používá PlayerControlView
. Zdrojový kód PlayerControlView
nám říká, že pro rozvržení používá R.layout.exo_player_control_view
. Pokud vytvoříme vlastní soubor rozvržení se stejným názvem, PlayerControlView
použije místo něj váš soubor.
- Odstraňte právě přidaný atribut
controller_layout_id
. - Smažte soubor
custom_player_control_view.xml
.
Soubor PlayerView
v activity_player.xml
by nyní měl vypadat takto:
activity_player.xml
<com.google.android.exoplayer2.ui.PlayerView android:id="@+id/video_view" android:layout_width="match_parent" android:layout_height="match_parent"/>
- Vytvořte soubor s názvem
exo_player_control_view.xml
ve složceres/layout
modulu knihovnyplayer-lib
. - Vložte do
exo_player_control_view.xml
následující kód a přidejte tlačítko přehrávání, tlačítko pauzy aImageView
s logem:
exo_player**_control_view.xml**
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:layoutDirection="ltr" android:background="#CC000000" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:paddingTop="4dp" android:orientation="horizontal"> <ImageButton android:id="@id/exo_play" style="@style/ExoMediaButton.Play"/> <ImageButton android:id="@id/exo_pause" style="@style/ExoMediaButton.Pause"/> </LinearLayout> <ImageView android:contentDescription="@string/logo" android:src="@drawable/google_logo" android:layout_width="match_parent" android:layout_height="wrap_content"/></LinearLayout>
Tento příklad ukazuje, jak sem můžete přidat vlastní prvky a smíchat je se standardními ovládacími prvky. ExoPlayerView
Nyní používá váš vlastní ovládací prvek a veškerá logika skrývání a zobrazování při interakci s ovládacím prvkem je zachována.
Gratulujeme! Dozvěděli jste se mnoho nového o integraci přehrávače ExoPlayer do vaší aplikace.
Další informace
.