ExoPlayer は、複数のコンテナ形式で HLS をサポートしています。含まれる音声と動画のサンプル形式もサポートしている必要があります(詳細については、サンプル形式をご覧ください)。こちらで説明されているように、HLS コンテンツ プロデューサーには高品質の HLS ストリームを生成することを強くおすすめします。
機能 | 対応 | コメント |
---|---|---|
コンテナ | ||
MPEG-TS | はい | |
FMP4/CMAF | はい | |
ADTS(AAC) | はい | |
MP3 | はい | |
字幕 | ||
CEA-608 | はい | |
CEA-708 | はい | |
WebVTT | はい | |
メタデータ | ||
ID3 | はい | |
SCTE-35 | × | |
コンテンツの保護 | ||
AES-128 | はい | |
サンプル AES-128 | × | |
Widevine | はい | API 19 以降(「cenc」スキーム)と 25 以降(「cbcs」スキーム) |
PlayReady SL2000 | はい | Android TV のみ |
サーバー コントロール | ||
差分更新 | はい | |
再生リストの再読み込みをブロックしています | はい | |
プリロード ヒントのロードのブロック | はい | 長さが未定義のバイト範囲を除く |
ライブ再生 | ||
通常のライブ再生 | はい | |
低遅延 HLS(Apple) | はい | |
低レイテンシ HLS(コミュニティ) | × | |
Common Media Client Data(CMCD) | はい | 統合ガイド |
MediaItem の使用
HLS ストリームを再生するには、HLS モジュールに依存する必要があります。
Kotlin
implementation("androidx.media3:media3-exoplayer-hls:1.3.1")
Groovy
implementation "androidx.media3:media3-exoplayer-hls:1.3.1"
次に、HLS 再生リスト URI の MediaItem
を作成してプレーヤーに渡すことができます。
Kotlin
// Create a player instance. val player = ExoPlayer.Builder(context).build() // Set the media item to be played. player.setMediaItem(MediaItem.fromUri(hlsUri)) // Prepare the player. player.prepare()
Java
// Create a player instance. ExoPlayer player = new ExoPlayer.Builder(context).build(); // Set the media item to be played. player.setMediaItem(MediaItem.fromUri(hlsUri)); // Prepare the player. player.prepare();
URI の末尾が .m3u8
ではない場合は、MimeTypes.APPLICATION_M3U8
を MediaItem.Builder
の setMimeType
に渡して、コンテンツのタイプを明示的に示すことができます。
メディア アイテムの URI は、メディア再生リストまたはマルチバリエーション再生リストのいずれかを指します。URI が、複数の #EXT-X-STREAM-INF
タグを宣言するマルチバリアント再生リストをポイントしている場合、ExoPlayer は利用可能な帯域幅とデバイス機能の両方を考慮して、バリアント間で自動的に適応します。
HlsMediaSource の使用
他のカスタマイズ オプションが必要な場合は、HlsMediaSource
を作成し、MediaItem
ではなくプレーヤーに直接渡すことができます。
Kotlin
// Create a data source factory. val dataSourceFactory: DataSource.Factory = DefaultHttpDataSource.Factory() // Create a HLS media source pointing to a playlist uri. val hlsMediaSource = HlsMediaSource.Factory(dataSourceFactory).createMediaSource(MediaItem.fromUri(hlsUri)) // Create a player instance. val player = ExoPlayer.Builder(context).build() // Set the HLS media source as the playlist with a single media item. player.setMediaSource(hlsMediaSource) // Prepare the player. player.prepare()
Java
// Create a data source factory. DataSource.Factory dataSourceFactory = new DefaultHttpDataSource.Factory(); // Create a HLS media source pointing to a playlist uri. HlsMediaSource hlsMediaSource = new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(MediaItem.fromUri(hlsUri)); // Create a player instance. ExoPlayer player = new ExoPlayer.Builder(context).build(); // Set the HLS media source as the playlist with a single media item. player.setMediaSource(hlsMediaSource); // Prepare the player. player.prepare();
マニフェストへのアクセス
現在のマニフェストを取得するには、Player.getCurrentManifest
を呼び出します。HLS の場合、返されたオブジェクトを HlsManifest
にキャストする必要があります。また、マニフェストが読み込まれるたびに、Player.Listener
の onTimelineChanged
コールバックが呼び出されます。この処理はオンデマンド コンテンツで 1 回、ライブ コンテンツで複数回行われます。次のコード スニペットは、マニフェストが読み込まれたときにアプリがなんらかの操作を行う方法を示しています。
Kotlin
player.addListener( object : Player.Listener { override fun onTimelineChanged(timeline: Timeline, @TimelineChangeReason reason: Int) { val manifest = player.currentManifest if (manifest is HlsManifest) { // Do something with the manifest. } } } )
Java
player.addListener( new Player.Listener() { @Override public void onTimelineChanged( Timeline timeline, @Player.TimelineChangeReason int reason) { Object manifest = player.getCurrentManifest(); if (manifest != null) { HlsManifest hlsManifest = (HlsManifest) manifest; // Do something with the manifest. } } });
再生のカスタマイズ
ExoPlayer には、アプリのニーズに合わせて再生エクスペリエンスを調整する方法が複数用意されています。例については、カスタマイズのページをご覧ください。
チャンクレス準備の無効化
デフォルトでは、ExoPlayer はチャンクレス準備を使用します。つまり、ExoPlayer はマルチバリエーション再生リストの情報のみを使用してストリームを準備します。これは、#EXT-X-STREAM-INF
タグに CODECS
属性が含まれている場合に機能します。
#EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS
タグを使用してマルチバリエーション再生リストで宣言されていない多重化された字幕トラックがメディア セグメントに含まれている場合は、この機能を無効にする必要があります。そうしないと、字幕トラックは検出されず、再生されません。次のスニペットに示すように、HlsMediaSource.Factory
でチャンクレス準備を無効にできます。ただし、ExoPlayer は追加のトラックを検出するためにメディア セグメントをダウンロードする必要があるため、起動時間が長くなります。マルチバリエーション再生リストで字幕トラックを宣言することをおすすめします。
Kotlin
val hlsMediaSource = HlsMediaSource.Factory(dataSourceFactory) .setAllowChunklessPreparation(false) .createMediaSource(MediaItem.fromUri(hlsUri))
Java
HlsMediaSource hlsMediaSource = new HlsMediaSource.Factory(dataSourceFactory) .setAllowChunklessPreparation(false) .createMediaSource(MediaItem.fromUri(hlsUri));
高品質な HLS コンテンツの作成
ExoPlayer を最大限に活用するため、HLS コンテンツを改善するためのガイドラインがいくつかあります。詳しくは、ExoPlayer での HLS 再生に関する Medium の投稿をご覧ください。主なポイントは次のとおりです。
- 正確なセグメントの長さを使用します。
- 連続したメディア ストリームを使用します。セグメント間でメディア構造を変更しないでください。
#EXT-X-INDEPENDENT-SEGMENTS
タグを使用します。- 動画と音声の両方を含むファイルではなく、分離ストリームを優先します。
- マルチバリエーション再生リストにできるだけ多くの情報を含めます。
以下のガイドラインは特にライブ配信に適用されます。
#EXT-X-PROGRAM-DATE-TIME
タグを使用します。#EXT-X-DISCONTINUITY-SEQUENCE
タグを使用します。- 有効期間を長くします。1 分以上であれば問題ありません。