HLS

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.4.1")

Groovy

implementation "androidx.media3:media3-exoplayer-hls:1.4.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 で終わらない場合は、MediaItem.BuildersetMimeTypeMimeTypes.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.ListeneronTimelineChanged コールバックも呼び出されます。これは、オンデマンド コンテンツの場合は 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 分以上が理想的です。