ExoPlayer結構分析

最近要做音樂播放器,經過一週的調研,最終決定使用google的ExoPlayer,對ExoPlayer的架構、流程做個分析,梳理一下調用邏輯。

先做個筆記,等項目做完了寫一個多媒體播放的大型攻略。

媒體資源的獲取

MediaSource類代表媒體資源,new出這個類的實例需要uri,DataSourceFactory和ExtractorsFactory。

uri是資源的路徑;

DataSourceFactory的作用是創建對應的DataSource實例,從uri資源中讀取文件流;

ExtractorsFactory的作用是創建Extractors實例,Extractor翻譯過來就是“抽出器”,在這裏就是把媒體文件從二進制的媒體流中抽出來。這個開源項目已經實現了mp3/mp4/flv等常見格式的抽出器,如果需要解析不支持的格式,還可以自己實現,或使用ffmpeg擴展。

MediaSource是一個接口,也沒聲明幾個方法,其中最主要的一個就是createPeriod()方法,用來創建一個MediaPeriod對象,這個對象就是真正做資源處理的。

對媒體資源的使用

ExoPlayer類代表這“播放器”的概念,就是接收媒體資源,把媒體資源解析成聲音和畫面呈現出來。ExoPlayer是一個接口,它有很多實現,我們以SimpleExoPlayer爲例子。new出一個SimpleExoPlayer實例需要RenderersFactory、TrackSelector和LoadControl三個參數。

RenderersFactory是用來生產Renderer數組的。Renderer翻譯過來就是渲染器的意思,就是把音頻、視頻、文字源顯示在畫面上或輸出成聲音。音視頻文件的錄製都是二進制的,只是時間間隔非常短,所以輸出時讓人感覺是連續的,而Renderer的工作就是“快速、連續地輸出這些文件”。爲什麼是數組呢,因爲一個媒體文件可能有音頻、視頻等多個軌道,一個Render對應一個軌道;

TrackSelector翻譯過來就是軌道選擇器的意思,它在這裏的作用就是軌道選擇,它有個方法selectTracks(),返回TrackSelection數組,TrackSelection就是對軌道進行解析的。一個媒體文件會包含多個軌道,音軌、視頻軌、文字軌等,所以需要多個TrackSelection;

LoadControl主要是解析的一些進度控制、參數控制等,主要是記錄一些position;

整個播放邏輯流程

上面分析了資源的獲取和資源的使用,現在就分析下ExoPlayer是如何啓動整個流程、控制整個流程的。

ExoPlayer通過prepare(MediaSource m,xxx,xxx)方法啓動,方法裏面調用ExoPlayerImpl的prepare方法,裏面又調用ExoPlayerImplInternal的prepare方法,這個類就是真正的邏輯實現。

ExoPlayerImplInternal裏面會通過Handler發送MSG_PREPARE消息,然後最終會調用prepareInternal方法。這個方法裏面進行一些初始化操作後,就會發送MSG_DO_SOME_WORK消息,最終調用doSomeWork方法。

doSomeWork方法裏首先會調用updatePeriods方法更新Period。播放由三個MediaPeriodHolder實例控制,MediaPeriodHolder是什麼呢?它持有MediaPeriod、MediaSource、Render等所有實例,這裏面就是真正完成所有邏輯的。這三個實例分別是loadingPeriodHolder、readingPeriodHolder和playingPeriodHolder。

updatePeriods方法會調用setPlayingPeriodHolder方法,設置將要播放的MediaPeriod。setPlayingPeriodHolder方法最後會調用enableRenderers方法,該方法會遍歷render數組(創建ExoPlayer實例時傳入的參數),調用render的start方法,這裏面會執行一些狀態的重置、通知。

然後再回到doSomeWork方法,接着往下走,會調用render的render方法,這個方法就是真正的解析、渲染了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章