ExoPlayer 開發者指導

原文地址

我的其他文章
0.拼音查詞開源庫
1.ExoPlayer源碼淺析
2.Android實現LED燈顯示效果
3.Picasso源碼淺析
4.一行代碼實現RecyclerView的多選批量操作
5.Android 圖片網格布局控件
6.PaperView:像紙一樣折疊
7.TabViewPager 很好用
8.RecyclerView 學習筆記
9.發布Library到JCenter可以這么簡單

Developer guide


在Android設備中,播放視頻和音樂是非常普遍的。Android框架提供了一個對于媒體的操作的最省代碼的解決方案:MediaPlayer。它提供了低等級的媒體API,例如:MediaCodecAudioTrackMediaDrm,可以用于建立自定義媒體播放的解決方案。

ExpPlayer是一個開源的,App等級的媒體API,它的開源項目包含了library和示例:

Pros and cons


ExoPlayer相較于MediaPlayer有很多很多的優點:

  • 支持動態的自適應流HTTP(DASH) 和 平滑流,任何目前MediaPlayer支持的視頻格式(同時它還支持HTTP直播了(HLS),MP4,MP3,WebM,M4A,MPEG-TS 和 AAC).
  • 支持高級的HLS特性,例如正確處理 EXT-X-DISCONTINUITY 標簽;
  • 支持自定義和擴治你的使用場景。ExoPlayer專門為此設計;
  • 便于隨著App的升級而升級。因為ExoPlayer是一個包含在你的應用中的庫,對于你使用哪個版本有完全的控制權,并且你可以簡單的跟隨應用的升級而升級;
  • 更少的適配性問題。

值得注意的時,ExoPlayer同時有些缺點:

  • ExoPlayer的音頻和視頻組件依賴Android的 MediaCodec接口,該接口發布于Android4.1(API 等級16)。因此它不能工作于之前的Android版本。
  • ExoPlayer目前還不支持自動檢查需要播放的媒體格式。應用需要知道他想要播放的媒體格式去構建一個ExoPlayer去播放媒體。這個問題已經在Issue #438解決。

Library overview

在ExoPlayer的庫中最重要的類是ExoPlayer,這個類維護著播放器的全局狀態,和正在播放的媒體特質,例如怎么獲取到的媒體數據,它使怎么緩存或者它的格式。你可以以TrackRenderer類的方式通過ExoPlayer的prepare方法注入。

ExoPlayer提供默認的音頻和視頻渲染器,利用了Android框架中的MediaCodecAudioTrach類。這兩個都需要一個SampleSource對象中注入,用來實現媒體示例的播放。

組件的注入在當前ExoPlayer庫中是普遍存在的。圖1展示了使用一個ExoPlayer來配置和播放MP4媒體流的高級對象模型。默認的音頻和視頻渲染器已經被注解到ExoPlayer中。一個叫ExtractorSampleSource類的實現被注解到渲染器中用于提供簡單的媒體播放功能。DataSourceExtractor示例被注解到ExtractorSampleSource來支持加載媒體流和在被加載的數據中提取樣板。在這個示例中DefaultUriDataSourceMp4Extractor被用于播放從URIs中導入的MP4流。

圖1.ExoPlayer中播放MP4的對象模型

總的來說,ExoPlayer實例被用來注解支持開發者需求的組件,這個模型使定制播放器變得非常簡單,并支持自定義組件。以下部分介紹了在這個模型圖種三個最最重要的部分:TrackRender,SampleSourceDataSource

TrackRenderer

一個TrackRenderer播放特定類型的媒體,例如視頻,音頻和文字。ExoPlayer類在它的TrackRenderer上執行方法,使用單獨的線程,因此,導致每種類型的媒體被渲染全局的播放位置,ExoPlayer庫提供MediaCodecVideoTrackRenderer作為默認的實現用于渲染視頻,MediaCodecAudioTrackRender渲染音頻。兩種實現都是利用Android的 MediaCodec 去解碼每個媒體樣本。他們可以處理所有Android設備支持的音頻和視頻格式(詳細信息請看支持媒體類型)。ExoPlayer庫也提供了一個渲染文本的渲染器TextTrackRenderer

以下代碼示例使用標準的TrackRenderer 實現視頻,音頻播放需要的步驟:

//1.初始化播放器
player = ExoPlayer.Factory.newInstance(RENDERER_COUNT);
//2.構建渲染器
MediaCodecVideoTrackRender videoRender = ...
MediaCodecAudioTrackRender audioRender = ...
//3.通過prepare注入渲染器
player.prepare(videoRender,audioRender);
//4.將surface傳遞到渲染器
 player.sendMessage(videoRender,MediaCodecVideoTrackRenderer.MSG_SET_SURFACE,surface);
//5.開始播放
player.setPlayWhenReady(true);
....
player.release(); //當播放完成,別忘了釋放!

想看完整的例子,請在ExoPlayer demo app中查看PlayerActivity和DemoPlayer。其中詳細的示范如何使用ExoPlayer實例,以及ActivitySurface`的生命周期。

SampleSource

庫中提供標準的TrackRenderer實現需要SampleSource實例被注入到他們的構造方法中。一個SampleSource對象提供了格式信息,和被渲染的媒體樣本。ExoPlayer庫提供了一些不同類型的SampleSource實例:

  • ExtractorSampleSource - 用于MP3,M4A,WebM,MPEG-TS和AAC;
  • ChunkSampleSource - 用于DASH和平滑流的播放;
  • HlsSampleSource - 用于HLS 播放;

后面的部分會詳細介紹這些實例的使用。

DataSource

ExoPlayer庫提供的標準的SampleSource實例是利用了DataSource來加載媒體數據的。各種類型的實現都放在upstream包種。最最多用到的實現是:

  • DefaultUriDataSource - 用于播放本地和網絡媒體;
  • AssetDataSource - 用于播放應用中assets文件夾下的媒體。

Traditional media playbacks


Explayer庫提供了ExtractorSampleSource用于播放傳統格式的媒體,包括MP3,M4A,MP4,WebM,MPEG-TS和AAC,圖1中展示了ExoPlayer播放MP4流的對象模型,以下代碼展示了如何構造和實例化TrackRenderer

DataSource dataSource = new DefaultUriDataSource(userAgent, null);
Mp4Extractor extractor = new Mp4Extractor();
ExtractorSampleSource sampleSource = new ExtractorSampleSource(
uri, dataSource, extractor, 2, BUFFER_SIZE);
MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(
sampleSource, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT);
MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource);

每種類型的媒體格式都需要一個對應的解析器(Extractor)。在ExoPlayer庫的extractor包種包含了不同類型的解析器,你可以實現你自己的解析器,如果庫中不包含你需要的類型的話。

ExoPlayer的示例代碼中提供了一個完整的ExtractorRendererBuilder的示例。PlayerActivity使用它播放一些可用的視頻。

Adaptive media playbacks


ExoPlayer 支持自適應流,即在播放的時候,根據網絡狀況自動調節視頻質量。DASH,SmoothStreaming和HLS展示了自適應流技術。以上三種,媒體都是通過小塊的方式加載(通常2到10秒的長度)。每當一塊媒體被請求,客戶端將會選擇一種可能的規格。例如:如果網絡情況比較好,客戶端將選擇高質量的規格,如果網絡比較差則會低質量的。在兩種技術中,視頻和音頻都需要被分割。

DASH android SmoothStreaming

ExoPlayer庫通過ChunkSampleSource支持DASH和SmoothStreaming動態播放,即通過讀取獨立的媒體塊。每個ChunkSampleSOurce需要一個ChunkSource通過構造方法注入進來。ChunkSource主要負責加載和讀取樣本來提供媒體塊。DashChunkSource類使用FMP4和WebM容器格式來提供DASH播放。SmoothStreamingChunkSource類使用FMP4容器格式。

兩種類型的ChunkSource實例需要一個解析器FormatEvaluator和一個數據源DataSource通過構造的方式注入。FormatEvaluator在每個塊被加載之前選擇一種可用的格式,DataSource提供數據源。最終,ChunkSampleSource需要一個LoadControl對象去控制緩沖塊。
圖2演示了DASH動態播放通常的配置。通過FormatEvaluator實現視頻質量的動態變化,但是音頻的質量是固定的。

圖2:DASH動態播放對象模型


這部分動態視頻流暫時用不著,以后有機會翻譯...


Player events


在播放階段,你的App可以收到所有ExoPlayer產生的時間,這些事件對于提升用戶體驗有很大的幫助,如對播放的控制。一些ExoPlayer組件還提供了他們自己底層的事件,可以監聽性能。

High level events

ExoPlayer允許通過addListener()removeListener()的方式添加ExoPlayer.Listener實例,被注冊的監聽器將會得到播放狀態的回調,還要錯誤導致的播放失敗,如果需要知道更多的播放狀態和可能的狀態直接的相互轉換,請查閱ExoPlayer源碼。

Low level events

除了高級事件,個別的組件還允許監聽他們自己的時間,例如,MediaCodecVideoTrackRenderer的構造方法提供了MediaCodecVideoTrackRenderer.EventListener。在ExoPlayer的demo中,這給PlayerAcitivity調整目標surface的尺寸到合適的高度和寬度的途徑。

@Override
public void onVideoSizeChanged(int width, int height, float pixelWidthAspectRatio) {
  surfaceView.setVideoWidthHeightRatio(
      height == 0 ? 1 : (width * pixelWidthAspectRatio) / height);
}

Customization


懶得翻譯了...

轉載請注明出處:
http://www.lxweimin.com/p/3251a5189f56

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容