public final class

BundledHlsMediaChunkExtractor

extends java.lang.Object

implements HlsMediaChunkExtractor

 java.lang.Object

↳androidx.media3.exoplayer.hls.BundledHlsMediaChunkExtractor

Gradle dependencies

compile group: 'androidx.media3', name: 'media3-exoplayer-hls', version: '1.5.0-alpha01'

  • groupId: androidx.media3
  • artifactId: media3-exoplayer-hls
  • version: 1.5.0-alpha01

Artifact androidx.media3:media3-exoplayer-hls:1.5.0-alpha01 it located at Google repository (https://maven.google.com/)

Overview

HlsMediaChunkExtractor implementation that uses ExoPlayer app-bundled Extractors.

Summary

Constructors
publicBundledHlsMediaChunkExtractor(Extractor extractor, Format multivariantPlaylistFormat, TimestampAdjuster timestampAdjuster)

Creates a new instance.

Methods
public voidinit(ExtractorOutput extractorOutput)

public booleanisPackedAudioExtractor()

public booleanisReusable()

public voidonTruncatedSegmentParsed()

public booleanread(ExtractorInput extractorInput)

public HlsMediaChunkExtractorrecreate()

from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructors

public BundledHlsMediaChunkExtractor(Extractor extractor, Format multivariantPlaylistFormat, TimestampAdjuster timestampAdjuster)

Creates a new instance.

Parameters:

extractor: The underlying Extractor.
multivariantPlaylistFormat: The Format obtained from the multivariant playlist.
timestampAdjuster: A TimestampAdjuster to adjust sample timestamps.

Methods

public void init(ExtractorOutput extractorOutput)

public boolean read(ExtractorInput extractorInput)

public boolean isPackedAudioExtractor()

public boolean isReusable()

public HlsMediaChunkExtractor recreate()

public void onTruncatedSegmentParsed()

Source

/*
 * Copyright 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package androidx.media3.exoplayer.hls;

import static androidx.media3.common.util.Assertions.checkState;

import androidx.annotation.VisibleForTesting;
import androidx.media3.common.Format;
import androidx.media3.common.util.TimestampAdjuster;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.extractor.Extractor;
import androidx.media3.extractor.ExtractorInput;
import androidx.media3.extractor.ExtractorOutput;
import androidx.media3.extractor.PositionHolder;
import androidx.media3.extractor.mp3.Mp3Extractor;
import androidx.media3.extractor.mp4.FragmentedMp4Extractor;
import androidx.media3.extractor.text.SubtitleParser;
import androidx.media3.extractor.ts.Ac3Extractor;
import androidx.media3.extractor.ts.Ac4Extractor;
import androidx.media3.extractor.ts.AdtsExtractor;
import androidx.media3.extractor.ts.TsExtractor;
import java.io.IOException;

/**
 * {@link HlsMediaChunkExtractor} implementation that uses ExoPlayer app-bundled {@link Extractor
 * Extractors}.
 */
@UnstableApi
public final class BundledHlsMediaChunkExtractor implements HlsMediaChunkExtractor {

  private static final PositionHolder POSITION_HOLDER = new PositionHolder();

  @VisibleForTesting /* package */ final Extractor extractor;
  private final Format multivariantPlaylistFormat;
  private final TimestampAdjuster timestampAdjuster;
  private final SubtitleParser.Factory subtitleParserFactory;
  private final boolean parseSubtitlesDuringExtraction;

  /**
   * Creates a new instance.
   *
   * @param extractor The underlying {@link Extractor}.
   * @param multivariantPlaylistFormat The {@link Format} obtained from the multivariant playlist.
   * @param timestampAdjuster A {@link TimestampAdjuster} to adjust sample timestamps.
   */
  public BundledHlsMediaChunkExtractor(
      Extractor extractor, Format multivariantPlaylistFormat, TimestampAdjuster timestampAdjuster) {
    this(
        extractor,
        multivariantPlaylistFormat,
        timestampAdjuster,
        SubtitleParser.Factory.UNSUPPORTED,
        /* parseSubtitlesDuringExtraction= */ false);
  }

  /**
   * Creates a new instance.
   *
   * @param extractor The underlying {@link Extractor}.
   * @param multivariantPlaylistFormat The {@link Format} obtained from the multivariant playlist.
   * @param timestampAdjuster A {@link TimestampAdjuster} to adjust sample timestamps.
   * @param subtitleParserFactory A {@link SubtitleParser.Factory} to be used with WebVTT subtitles.
   *     If the value is null, subtitles will be parsed during decoding, otherwise - during
   *     extraction. Decoding will only work if this subtitleParserFactory supports the provided
   *     multivariantPlaylistFormat.
   */
  // TODO(b/289983417): Once the subtitle-parsing-during-extraction is the only available flow, make
  // this constructor public and remove parseSubtitlesDuringExtraction parameter
  /* package */ BundledHlsMediaChunkExtractor(
      Extractor extractor,
      Format multivariantPlaylistFormat,
      TimestampAdjuster timestampAdjuster,
      SubtitleParser.Factory subtitleParserFactory,
      boolean parseSubtitlesDuringExtraction) {
    this.extractor = extractor;
    this.multivariantPlaylistFormat = multivariantPlaylistFormat;
    this.timestampAdjuster = timestampAdjuster;
    this.subtitleParserFactory = subtitleParserFactory;
    this.parseSubtitlesDuringExtraction = parseSubtitlesDuringExtraction;
  }

  @Override
  public void init(ExtractorOutput extractorOutput) {
    extractor.init(extractorOutput);
  }

  @Override
  public boolean read(ExtractorInput extractorInput) throws IOException {
    return extractor.read(extractorInput, POSITION_HOLDER) == Extractor.RESULT_CONTINUE;
  }

  @Override
  public boolean isPackedAudioExtractor() {
    Extractor underlyingExtractor = extractor.getUnderlyingImplementation();
    return underlyingExtractor instanceof AdtsExtractor
        || underlyingExtractor instanceof Ac3Extractor
        || underlyingExtractor instanceof Ac4Extractor
        || underlyingExtractor instanceof Mp3Extractor;
  }

  @Override
  public boolean isReusable() {
    Extractor underlyingExtractor = extractor.getUnderlyingImplementation();
    return underlyingExtractor instanceof TsExtractor
        || underlyingExtractor instanceof FragmentedMp4Extractor;
  }

  @Override
  public HlsMediaChunkExtractor recreate() {
    checkState(!isReusable());
    checkState(
        extractor.getUnderlyingImplementation() == extractor,
        "Can't recreate wrapped extractors. Outer type: " + extractor.getClass());
    Extractor newExtractorInstance;
    // LINT.IfChange(extractor_instantiation)
    if (extractor instanceof WebvttExtractor) {
      newExtractorInstance =
          new WebvttExtractor(
              multivariantPlaylistFormat.language,
              timestampAdjuster,
              subtitleParserFactory,
              parseSubtitlesDuringExtraction);
    } else if (extractor instanceof AdtsExtractor) {
      newExtractorInstance = new AdtsExtractor();
    } else if (extractor instanceof Ac3Extractor) {
      newExtractorInstance = new Ac3Extractor();
    } else if (extractor instanceof Ac4Extractor) {
      newExtractorInstance = new Ac4Extractor();
    } else if (extractor instanceof Mp3Extractor) {
      newExtractorInstance = new Mp3Extractor();
    } else {
      throw new IllegalStateException(
          "Unexpected extractor type for recreation: " + extractor.getClass().getSimpleName());
    }
    return new BundledHlsMediaChunkExtractor(
        newExtractorInstance,
        multivariantPlaylistFormat,
        timestampAdjuster,
        subtitleParserFactory,
        parseSubtitlesDuringExtraction);
  }

  @Override
  public void onTruncatedSegmentParsed() {
    extractor.seek(/* position= */ 0, /* timeUs= */ 0);
  }
}