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」スキーム)および API 25 以降(「cbcs」スキーム)
PlayReady SL2000 はい Android TV のみ
サーバー制御
差分更新 はい
ブロック中の再生リストを再読み込みしました はい
プリロード ヒントのブロック読み込み はい 長さが未定義のバイト範囲を除く
ライブ再生
通常のライブ再生 はい
低レイテンシ HLS(Apple) はい
低レイテンシ HLS(コミュニティ) ×
共通メディア クライアント データ(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_M3U8MediaItem.BuildersetMimeType に渡して、コンテンツのタイプを明示的に示すことができます。

メディア アイテムの 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 分以上で十分です。