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(コミュニティ) | いいえ | |
共通メディア クライアント データ(CMCD) | はい | 統合ガイド |
MediaItem の使用
HLS ストリームを再生するには、HLS モジュールに依存する必要があります。
Kotlin
implementation("androidx.media3:media3-exoplayer-hls:1.5.0")
Groovy
implementation "androidx.media3:media3-exoplayer-hls:1.5.0"
次に、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
で終わらない場合は、MediaItem.Builder
の setMimeType
に MimeTypes.APPLICATION_M3U8
を渡して、コンテンツのタイプを明示的に指定できます。
メディア アイテムの URI は、メディア再生リストまたはマルチバリアント再生リストのいずれかを参照できます。URI が複数の #EXT-X-STREAM-INF
タグを宣言するマルチバリアント プレイリストを指している場合、ExoPlayer は利用可能な帯域幅とデバイスの機能の両方を考慮して、バリアント間で自動的に適応します。
HlsMediaSource を使用する
より多くのカスタマイズ オプションを使用するには、MediaItem
ではなく HlsMediaSource
を作成してプレーヤーに直接渡します。
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 分以上が理想的です。