在這之前筆者使用原生的MediaPlayer、B站開源的IJKVideoView等播放器。直到發現ExoPlayer,這款由YouTube開發的播放器真的是非常強大。對於自定義播放器非常友好,裡面將很多模塊抽象成獨立的組件可供使用者自行定製,當然官方也提供了一些默認的實現。如果你正在開發視頻類功能,強烈推薦你嘗試一下ExoPlayer。
預備知識DRM:Digital Rights Management,即數字版權管理。指的是出版者用來控制被保護對象的使用權的一些技術,這些技術保護的有數位化內容(例如:軟體、音樂、電影)。
PlayReady:PlayReady是微軟推出的一種DRM解決方案,其工作原理讀者可自行查閱相關資料。
Widevine:同上,Widevine屬於谷歌的一種DRM解決方案。
在不同Android版本和不同的手機設備上擁有更統一的行為表現,更少的設備差異帶來的問題。
作為一個獨立的庫,可以很輕易的升級。
可以根據用戶的需求方便的對播放器行為進行定製和擴展,ExoPlayer中的很多組件都支持自定義和擴展。
支持播放視頻列表,並且可以支持對視頻的裁剪、合併,以及循環播放設置。
支持更多的視頻格式,包括MediaPlayer不支持的DASH、SmoothStreaming。
支持 Widevine功能,這個功能可以下載和播放經過Google加密的視頻文件。
能夠方便的集成額外的擴展庫,比如IMA擴展庫。
缺點ExoPlayer支持大部分流媒體格式,並且對DRM的支持也比較友好,比如下方就是官方提供的支持的設備情況:
用例Android版本號Android API LevelAudio Playback4.116Video Playback4.116DASH(no DRM)4.116DASH(Widevine CENC; 「cenc」 scheme)4.419DASH (ClearKey)5.021SmoothStreaming (no DRM)4.116SmoothStreaming (PlayReady SL2000)AndroidTVAndroidTVHLS (no DRM)4.116HLS (AES-128 encryption)4.116HLS (Widevine CENC; 「cenc」 scheme)4.419HLS (Widevine CENC; 「cbcs」 scheme)7.125我們只要按照下面的步驟就能簡單的將ExoPlayer使用起來了:
上面已經整體介紹了使用ExoPlayer去播放視頻的步驟。下面我們就針對每一個步驟詳細的去介紹下如何具體地落實到代碼中去。
添加ExoPlayer的依賴首先我們要保證在項目根目錄的build.gradle中包含Google和JCenter倉庫:
repositories {
google()
jcenter()
}
在app module的build.gradle中添加對ExoPlayer的依賴:
implementation 'com.google.android.exoplayer:exoplayer:2.8.4'
當然2.8.4不是唯一的版本,你可以使用任意一個release版本。注意,如果你依賴比較高版本的ExoPlayer,恰好的你的項目中有依賴support包,由於高版本的ExoPlay依賴Androidx,所以會出現衝突。所以,在使用高版本ExoPlayer之前,需要將support包和Androidx之間的衝突先解決。
另外需要注意的是,在所有有依賴ExoPlayer庫的模塊中都需要打開對Java8的支持,需要在模塊的build.gradle中添加如下代碼:
compileOptions {
targetCompatibility JavaVersion.VERSION_1_8
}
ExoPlayer提供了一個工廠類ExoPlayerFactory用來實例化不同的ExoPlayer的對象。工廠類裡面提供了很多可自定義的一些參數用來定製個性化的播放器實例。例如我們下面使用的例子就是通過newSimpleInstance方法實例化一個SimpleExoPlayer對象。
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory videoTackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector = new DefaultTrackSelector(videoTackSelectionFactory);
LoadControl loadControl = new DefaultLoadControl();
mExoPlayer = ExoPlayerFactory.newSimpleInstance(this, trackSelector, loadControl);
ExoPlayer庫本身給我們提供了一個將播放控制操作,字幕以及surface封裝好的PlayerView。我們可以直接在我們的布局文件中引用PlayerView。並通過下面的方式和播放器綁定:
playerView.setPlayer(mExoPlayer);
對於ExoPlayer而言,所有被用來進行播放的資源都使用MediaSource進行包裝。所以當需要播放媒體資源時,你得先創建一個和資源相關的MediaSource對象,然後通過ExoPlayer.prepare方法將封裝的對象傳入。ExoPlayer提供了非常豐富的MediaSource類型,可用來播放DASH(DashMediaSource)、SmoothStreaming(SsMediaSource)、HLS(HlsMediaSource),以及用來播放多資源拼接的(ConcatenatingMediaSource)等等。示例如下:
ConcatenatingMediaSource concatenatingMediaSource = new ConcatenatingMediaSource(mediaSources);
mExoPlayer.setRepeatMode(Player.REPEAT_MODE_ALL);
mExoPlayer.prepare(concatenatingMediaSource);
當播放準備好了以後,我們可以通過setPlayWhenReady方法控制播放,當然ExoPlayer也提供了豐富的API去控制播放的過程。我們可以參考官方的API說明:官方文檔
釋放播放器當我們不再使用播放器的時候,將手機有限的資源進行釋放是非常的必要的。我們可以使用下面的代碼對播放器進行釋放:
mExoPlayer.release();
本文簡單介紹下EXOPlayer的基本使用。如果筆者感興趣可以去官方項目地址學習源碼。也可以閱讀官方的文檔。既然是Yutube使用的播放器,如何強大讀者自行去挖掘,也可挖掘源碼中的設計架構。
項目地址:https:
官方文檔:https: