ExoPlayer 程式庫的核心是 Player
介面。Player
提供傳統的高階媒體播放器功能
緩衝媒體、播放、暫停及跳轉。預設實作 ExoPlayer
為
不具任何假設 (因此對下列項目實施限制)
播放的媒體類型、儲存方式和位置,以及播放方式
轉譯完成的部分。與其直接實作媒體的載入與算繪作業
ExoPlayer
實作會將這項工作委派給插入的元件
建立播放器時,或新媒體來源傳遞給播放器時。
所有 ExoPlayer
實作項目通用的元件如下:
MediaSource
執行個體,這些執行個體會定義要播放的媒體、載入媒體及 可讀取已載入媒體的來源已建立MediaSource
執行個體 由播放器內部MediaSource.Factory
所選擇的MediaItem
。其他 使用媒體來源播放清單 API 直接傳遞給播放器。- 可將
MediaItem
轉換為MediaSource
的MediaSource.Factory
執行個體。MediaSource.Factory
會在建立播放器時插入。 - 算繪媒體個別元件的
Renderer
執行個體。這些 會在建立播放器時插入。 TrackSelector
,可選取MediaSource
提供的曲目 各可用Renderer
耗用的資源。已插入TrackSelector
建立播放器時。- 控制
MediaSource
緩衝更多媒體時間的LoadControl
;以及 有多少媒體進行緩衝處理系統會插入LoadControl
已建立。 - 控制直播期間播放速度的
LivePlaybackSpeedControl
讓播放器靠近已設定的即時偏移量。A 罩杯LivePlaybackSpeedControl
會在建立播放器時插入。
插入實作播放器元件的概念 都會直接套用這些功能預設實作 某些元件會將工作委派給進一步插入的元件。這樣一來 可以使用 可讓您以自訂方式設定容器
播放器自訂功能
以下列舉幾個透過插入元件自訂播放器的常見範例: 。
設定網路堆疊
歡迎參閱這個頁面,瞭解如何自訂 ExoPlayer 使用的網路堆疊。
快取從網路載入的資料
自訂伺服器互動
部分應用程式可能會想攔截 HTTP 要求和回應。建議您 插入自訂要求標頭、讀取伺服器的回應標頭、修改 要求URI 等。舉例來說,您的應用程式可以透過插入 做為請求媒體區隔的標頭格式。
以下範例說明如何透過
將自訂 DataSource.Factory
插入 DefaultMediaSourceFactory
:
Kotlin
val dataSourceFactory = DataSource.Factory { val dataSource = httpDataSourceFactory.createDataSource() // Set a custom authentication request header. dataSource.setRequestProperty("Header", "Value") dataSource } val player = ExoPlayer.Builder(context) .setMediaSourceFactory( DefaultMediaSourceFactory(context).setDataSourceFactory(dataSourceFactory) ) .build()
Java
DataSource.Factory dataSourceFactory = () -> { HttpDataSource dataSource = httpDataSourceFactory.createDataSource(); // Set a custom authentication request header. dataSource.setRequestProperty("Header", "Value"); return dataSource; }; ExoPlayer player = new ExoPlayer.Builder(context) .setMediaSourceFactory( new DefaultMediaSourceFactory(context).setDataSourceFactory(dataSourceFactory)) .build();
在上方的程式碼片段中,插入的 HttpDataSource
包含標頭
每個 HTTP 要求中的 "Header: Value"
。這個行為已在各個管道中修正
與 HTTP 來源互動
如需更詳細的方式,您可以使用
ResolvingDataSource
。下列程式碼片段說明如何插入
要求標頭,接著才與 HTTP 來源互動:
Kotlin
val dataSourceFactory: DataSource.Factory = ResolvingDataSource.Factory(httpDataSourceFactory) { dataSpec: DataSpec -> // Provide just-in-time request headers. dataSpec.withRequestHeaders(getCustomHeaders(dataSpec.uri)) }
Java
DataSource.Factory dataSourceFactory = new ResolvingDataSource.Factory( httpDataSourceFactory, // Provide just-in-time request headers. dataSpec -> dataSpec.withRequestHeaders(getCustomHeaders(dataSpec.uri)));
您也可以使用 ResolvingDataSource
來執行
及時修改 URI,如以下程式碼片段所示:
Kotlin
val dataSourceFactory: DataSource.Factory = ResolvingDataSource.Factory(httpDataSourceFactory) { dataSpec: DataSpec -> // Provide just-in-time URI resolution logic. dataSpec.withUri(resolveUri(dataSpec.uri)) }
Java
DataSource.Factory dataSourceFactory = new ResolvingDataSource.Factory( httpDataSourceFactory, // Provide just-in-time URI resolution logic. dataSpec -> dataSpec.withUri(resolveUri(dataSpec.uri)));
自訂錯誤處理機制
實作自訂 LoadErrorHandlingPolicy
可讓應用程式自訂
ExoPlayer 對載入錯誤的回應方式舉例來說,應用程式可能需要快速失敗
而非多次重試,或者您可以自訂輪詢邏輯
控制玩家每次重試的等待時間長度。下列程式碼片段
顯示如何實作自訂輪詢邏輯:
Kotlin
val loadErrorHandlingPolicy: LoadErrorHandlingPolicy = object : DefaultLoadErrorHandlingPolicy() { override fun getRetryDelayMsFor(loadErrorInfo: LoadErrorInfo): Long { // Implement custom back-off logic here. return 0 } } val player = ExoPlayer.Builder(context) .setMediaSourceFactory( DefaultMediaSourceFactory(context).setLoadErrorHandlingPolicy(loadErrorHandlingPolicy) ) .build()
Java
LoadErrorHandlingPolicy loadErrorHandlingPolicy = new DefaultLoadErrorHandlingPolicy() { @Override public long getRetryDelayMsFor(LoadErrorInfo loadErrorInfo) { // Implement custom back-off logic here. return 0; } }; ExoPlayer player = new ExoPlayer.Builder(context) .setMediaSourceFactory( new DefaultMediaSourceFactory(context) .setLoadErrorHandlingPolicy(loadErrorHandlingPolicy)) .build();
LoadErrorInfo
引數會包含關於載入失敗的詳細資訊,
並根據錯誤類型或失敗的要求自訂邏輯。
自訂擷取器旗標
擷取器標記可用來自訂個別格式的擷取方式
來自漸進式媒體這些配置可以在DefaultExtractorsFactory
提供給 DefaultMediaSourceFactory
。以下範例傳送標記
,此功能可讓系統根據索引尋找 MP3 串流。
Kotlin
val extractorsFactory = DefaultExtractorsFactory().setMp3ExtractorFlags(Mp3Extractor.FLAG_ENABLE_INDEX_SEEKING) val player = ExoPlayer.Builder(context) .setMediaSourceFactory(DefaultMediaSourceFactory(context, extractorsFactory)) .build()
Java
DefaultExtractorsFactory extractorsFactory = new DefaultExtractorsFactory().setMp3ExtractorFlags(Mp3Extractor.FLAG_ENABLE_INDEX_SEEKING); ExoPlayer player = new ExoPlayer.Builder(context) .setMediaSourceFactory(new DefaultMediaSourceFactory(context, extractorsFactory)) .build();
啟用固定位元率跳轉功能
針對 MP3、ADTS 和 AMR 串流,你可以啟用「近似跳轉」
使用 FLAG_ENABLE_CONSTANT_BITRATE_SEEKING
旗標的固定位元率。
您可以使用個別擷取器
DefaultExtractorsFactory.setXyzExtractorFlags
方法。目的地:
允許在支援特定擷取器的所有擷取器上
DefaultExtractorsFactory.setConstantBitrateSeekingEnabled
。
Kotlin
val extractorsFactory = DefaultExtractorsFactory().setConstantBitrateSeekingEnabled(true)
Java
DefaultExtractorsFactory extractorsFactory = new DefaultExtractorsFactory().setConstantBitrateSeekingEnabled(true);
接著,您就能透過 DefaultMediaSourceFactory
插入 ExtractorsFactory
,做為
。
啟用非同步緩衝區佇列
非同步緩衝區佇列是 ExoPlayer 在算繪情況下的強化項目
管道,以非同步模式運作 MediaCodec
執行個體,且
會使用其他執行緒來安排解碼及算繪資料。啟用中
以減少影格遺失和音訊截斷情形
執行 Android 12 的裝置預設會啟用非同步緩衝區佇列 (API 級別 31) 以上版本,從 Android 6.0 (API 級別 23) 開始可以手動啟用。 建議你為發現裝置掉落的特定裝置啟用這項功能 影格或音訊不足,尤其是播放受到 DRM 保護或影格速率過高時 內容。
在最簡單的情況下,您需要將 DefaultRenderersFactory
插入
方法如下:
Kotlin
val renderersFactory = DefaultRenderersFactory(context).forceEnableMediaCodecAsynchronousQueueing() val exoPlayer = ExoPlayer.Builder(context, renderersFactory).build()
Java
DefaultRenderersFactory renderersFactory = new DefaultRenderersFactory(context).forceEnableMediaCodecAsynchronousQueueing(); ExoPlayer exoPlayer = new ExoPlayer.Builder(context, renderersFactory).build();
若您直接對轉譯器執行個體化,請傳遞
AsynchronousMediaCodecAdapter.Factory
到MediaCodecVideoRenderer
和
MediaCodecAudioRenderer
建構函式建立而成。
使用 ForwardingPlayer
攔截方法呼叫
您可以將 Player
例項納入,以自訂其部分行為
ForwardingPlayer
的子類別和覆寫方法,以便執行
包括:
- 請先存取參數,再傳送至委派的
Player
。 - 請先從委派的
Player
存取傳回值,再傳回值。 - 徹底重新實作該方法。
覆寫 ForwardingPlayer
方法時,請務必確認
實作項目仍遵循 Player
的自我一致性
尤其在處理預計產生
採取完全相同或相關的行為例如:
- 如果想要覆寫每次「播放」您需要覆寫
ForwardingPlayer.play
和ForwardingPlayer.setPlayWhenReady
,因為 呼叫端預期這些方法的行為playWhenReady = true
。 - 如要變更跳轉遞增量,您必須同時覆寫
ForwardingPlayer.seekForward
,即可運用自訂內容跳轉 遞增,ForwardingPlayer.getSeekForwardIncrement
以便回報 正確的自訂遞增給呼叫端。 - 如要控管玩家要宣傳的
Player.Commands
執行個體,您必須同時覆寫Player.getAvailableCommands()
和Player.isCommandAvailable()
,以及聆聽Player.Listener.onAvailableCommandsChanged()
回呼以便接收 來自基礎播放器的變更
MediaSource 自訂
以上範例插入了自訂元件,以便在
傳遞至播放器的 MediaItem
物件。精細自訂的部分
您也能將自訂元件插入
MediaSource
例項,可以直接傳遞至播放器。範例
以下說明如何自訂 ProgressiveMediaSource
,以便使用自訂
DataSource.Factory
、ExtractorsFactory
和 LoadErrorHandlingPolicy
:
Kotlin
val mediaSource = ProgressiveMediaSource.Factory(customDataSourceFactory, customExtractorsFactory) .setLoadErrorHandlingPolicy(customLoadErrorHandlingPolicy) .createMediaSource(MediaItem.fromUri(streamUri))
Java
ProgressiveMediaSource mediaSource = new ProgressiveMediaSource.Factory(customDataSourceFactory, customExtractorsFactory) .setLoadErrorHandlingPolicy(customLoadErrorHandlingPolicy) .createMediaSource(MediaItem.fromUri(streamUri));
建立自訂元件
程式庫提供頂端所列元件的預設實作方式
請參考本頁說明,瞭解一般用途。ExoPlayer
可以使用這些元件,但
如果非標準行為,
這通常代表交易
不會十分要求關聯語意自訂導入作業的用途如下:
Renderer
:建議您實作自訂Renderer
來處理 媒體型別所支援的媒體類型, 資源庫。TrackSelector
:實作自訂TrackSelector
可讓應用程式執行 開發人員變更MediaSource
公開測試群組的方式 並選取要用於每個可用Renderer
的用量。LoadControl
:實作自訂LoadControl
可讓應用程式執行 開發人員更改玩家的緩衝處理政策。Extractor
:如果您目前需要支援某個容器格式 該程式庫支援,建議您實作自訂的Extractor
類別。MediaSource
– 實作自訂MediaSource
類別可 如果您想要取得媒體樣本並提供給轉譯器中的轉譯器使用 自訂方式,或想導入自訂MediaSource
合成選項 行為MediaSource.Factory
– 導入自訂MediaSource.Factory
可讓應用程式自訂MediaSource
的建立方式 來自MediaItem
。DataSource
:ExoPlayer 的上游套件已包含多種 針對不同用途實作DataSource
。建議您 實作自己的DataSource
類別,透過其他方式載入資料,例如 使用自訂通訊協定、自訂 HTTP 堆疊,或從自訂永久磁碟 快取。
建立自訂元件時,建議您採取下列做法:
- 如果自訂元件需要將事件回報給應用程式,建議您
您使用與現有 ExoPlayer 元件相同的模型
使用
EventDispatcher
類別,或與程式碼一起傳遞Handler
的範例 元件的建構函式。 - 建議自訂元件使用與現有 ExoPlayer 相同的模型
元件,允許應用程式在播放期間重新設定。方法如下
自訂元件應導入
PlayerMessage.Target
,並接收 變更handleMessage
方法的設定變更應用程式程式碼應 呼叫 ExoPlayer 的createMessage
方法以傳遞設定變更。 設定訊息,並使用PlayerMessage.send
。傳送要在播放執行緒上傳送的訊息 確保這些執行作業與 遊戲製作的影片