public abstract class

BaseMediaSource

extends java.lang.Object

implements MediaSource

 java.lang.Object

↳androidx.media3.exoplayer.source.BaseMediaSource

Subclasses:

ImaServerSideAdInsertionMediaSource, RtspMediaSource, HlsMediaSource, SsMediaSource, DashMediaSource, MaskingMediaSource, CompositeMediaSource<T>, ConcatenatingMediaSource2, WrappingMediaSource, MergingMediaSource, SilenceMediaSource, ExternallyLoadedMediaSource, ClippingMediaSource, ProgressiveMediaSource, FilteringMediaSource, ConcatenatingMediaSource, LoopingMediaSource, SingleSampleMediaSource, AdsMediaSource, ServerSideAdInsertionMediaSource, PreloadMediaSource, FakeMediaSource, FakeAdaptiveMediaSource

Gradle dependencies

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

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

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

Overview

Base MediaSource implementation to handle parallel reuse and to keep a list of MediaSourceEventListeners.

Whenever an implementing subclass needs to provide a new timeline, it must call BaseMediaSource.refreshSourceInfo(Timeline) to notify all listeners.

Summary

Constructors
publicBaseMediaSource()

Methods
public final voidaddDrmEventListener(Handler handler, DrmSessionEventListener eventListener)

public final voidaddEventListener(Handler handler, MediaSourceEventListener eventListener)

protected final DrmSessionEventListener.EventDispatchercreateDrmEventDispatcher(int windowIndex, MediaSource.MediaPeriodId mediaPeriodId)

Returns a which dispatches all events to the registered listeners with the specified window index and .

protected final DrmSessionEventListener.EventDispatchercreateDrmEventDispatcher(MediaSource.MediaPeriodId mediaPeriodId)

Returns a which dispatches all events to the registered listeners with the specified

protected final MediaSourceEventListener.EventDispatchercreateEventDispatcher(int windowIndex, MediaSource.MediaPeriodId mediaPeriodId)

Returns a MediaSourceEventListener.EventDispatcher which dispatches all events to the registered listeners with the specified window index and .

protected final MediaSourceEventListener.EventDispatchercreateEventDispatcher(int windowIndex, MediaSource.MediaPeriodId mediaPeriodId, long mediaTimeOffsetMs)

Note: The mediaTimeOffsetMs passed to this method is ignored and not added to media times in any way.

protected final MediaSourceEventListener.EventDispatchercreateEventDispatcher(MediaSource.MediaPeriodId mediaPeriodId)

Returns a MediaSourceEventListener.EventDispatcher which dispatches all events to the registered listeners with the specified .

protected final MediaSourceEventListener.EventDispatchercreateEventDispatcher(MediaSource.MediaPeriodId mediaPeriodId, long mediaTimeOffsetMs)

Note: The mediaTimeOffsetMs passed to this method is ignored and not added to media times in any way.

public final voiddisable(MediaSource.MediaSourceCaller caller)

protected voiddisableInternal()

Disables the source, see MediaSource.disable(MediaSource.MediaSourceCaller).

public final voidenable(MediaSource.MediaSourceCaller caller)

protected voidenableInternal()

Enables the source, see MediaSource.enable(MediaSource.MediaSourceCaller).

protected final PlayerIdgetPlayerId()

Returns the PlayerId of the player using this media source.

protected final booleanisEnabled()

Returns whether the source is enabled.

public final voidprepareSource(MediaSource.MediaSourceCaller caller, TransferListener mediaTransferListener)

public final voidprepareSource(MediaSource.MediaSourceCaller caller, TransferListener mediaTransferListener, PlayerId playerId)

protected final booleanprepareSourceCalled()

Returns whether the source has MediaSource.prepareSource(MediaSource.MediaSourceCaller, TransferListener, PlayerId) called.

protected abstract voidprepareSourceInternal(TransferListener mediaTransferListener)

Starts source preparation and enables the source, see MediaSource.prepareSource(MediaSource.MediaSourceCaller, TransferListener, PlayerId).

protected final voidrefreshSourceInfo(Timeline timeline)

Updates timeline and manifest and notifies all listeners of the update.

public final voidreleaseSource(MediaSource.MediaSourceCaller caller)

protected abstract voidreleaseSourceInternal()

Releases the source, see MediaSource.releaseSource(MediaSource.MediaSourceCaller).

public final voidremoveDrmEventListener(DrmSessionEventListener eventListener)

public final voidremoveEventListener(MediaSourceEventListener eventListener)

protected final voidsetPlayerId(PlayerId playerId)

Sets the PlayerId of the player using this media source.

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

Constructors

public BaseMediaSource()

Methods

protected abstract void prepareSourceInternal(TransferListener mediaTransferListener)

Starts source preparation and enables the source, see MediaSource.prepareSource(MediaSource.MediaSourceCaller, TransferListener, PlayerId). This method is called at most once until the next call to BaseMediaSource.releaseSourceInternal().

Parameters:

mediaTransferListener: The transfer listener which should be informed of any media data transfers. May be null if no listener is available. Note that this listener should usually be only informed of transfers related to the media loads and not of auxiliary loads for manifests and other data.

protected void enableInternal()

Enables the source, see MediaSource.enable(MediaSource.MediaSourceCaller).

protected void disableInternal()

Disables the source, see MediaSource.disable(MediaSource.MediaSourceCaller).

protected abstract void releaseSourceInternal()

Releases the source, see MediaSource.releaseSource(MediaSource.MediaSourceCaller). This method is called exactly once after each call to BaseMediaSource.prepareSourceInternal(TransferListener).

protected final void refreshSourceInfo(Timeline timeline)

Updates timeline and manifest and notifies all listeners of the update.

Parameters:

timeline: The new Timeline.

protected final MediaSourceEventListener.EventDispatcher createEventDispatcher(MediaSource.MediaPeriodId mediaPeriodId)

Returns a MediaSourceEventListener.EventDispatcher which dispatches all events to the registered listeners with the specified .

Parameters:

mediaPeriodId: The to be reported with the events. May be null, if the events do not belong to a specific media period.

Returns:

An event dispatcher with pre-configured media period id.

protected final MediaSourceEventListener.EventDispatcher createEventDispatcher(int windowIndex, MediaSource.MediaPeriodId mediaPeriodId)

Returns a MediaSourceEventListener.EventDispatcher which dispatches all events to the registered listeners with the specified window index and .

Parameters:

windowIndex: The timeline window index to be reported with the events.
mediaPeriodId: The to be reported with the events. May be null, if the events do not belong to a specific media period.

Returns:

An event dispatcher with pre-configured media period id.

protected final MediaSourceEventListener.EventDispatcher createEventDispatcher(MediaSource.MediaPeriodId mediaPeriodId, long mediaTimeOffsetMs)

Deprecated: Use BaseMediaSource instead.

Note: The mediaTimeOffsetMs passed to this method is ignored and not added to media times in any way.

protected final MediaSourceEventListener.EventDispatcher createEventDispatcher(int windowIndex, MediaSource.MediaPeriodId mediaPeriodId, long mediaTimeOffsetMs)

Deprecated: Use BaseMediaSource instead.

Note: The mediaTimeOffsetMs passed to this method is ignored and not added to media times in any way.

protected final DrmSessionEventListener.EventDispatcher createDrmEventDispatcher(MediaSource.MediaPeriodId mediaPeriodId)

Returns a which dispatches all events to the registered listeners with the specified

Parameters:

mediaPeriodId: The to be reported with the events. May be null, if the events do not belong to a specific media period.

Returns:

An event dispatcher with pre-configured media period id.

protected final DrmSessionEventListener.EventDispatcher createDrmEventDispatcher(int windowIndex, MediaSource.MediaPeriodId mediaPeriodId)

Returns a which dispatches all events to the registered listeners with the specified window index and .

Parameters:

windowIndex: The timeline window index to be reported with the events.
mediaPeriodId: The to be reported with the events. May be null, if the events do not belong to a specific media period.

Returns:

An event dispatcher with pre-configured media period id and time offset.

protected final boolean isEnabled()

Returns whether the source is enabled.

protected final PlayerId getPlayerId()

Returns the PlayerId of the player using this media source.

Must only be used when the media source is prepared or has a player ID set.

protected final void setPlayerId(PlayerId playerId)

Sets the PlayerId of the player using this media source.

Parameters:

playerId: The player ID to be set.

protected final boolean prepareSourceCalled()

Returns whether the source has MediaSource.prepareSource(MediaSource.MediaSourceCaller, TransferListener, PlayerId) called.

public final void addEventListener(Handler handler, MediaSourceEventListener eventListener)

public final void removeEventListener(MediaSourceEventListener eventListener)

public final void addDrmEventListener(Handler handler, DrmSessionEventListener eventListener)

public final void removeDrmEventListener(DrmSessionEventListener eventListener)

public final void prepareSource(MediaSource.MediaSourceCaller caller, TransferListener mediaTransferListener)

public final void prepareSource(MediaSource.MediaSourceCaller caller, TransferListener mediaTransferListener, PlayerId playerId)

public final void enable(MediaSource.MediaSourceCaller caller)

public final void disable(MediaSource.MediaSourceCaller caller)

public final void releaseSource(MediaSource.MediaSourceCaller caller)

Source

/*
 * Copyright (C) 2018 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.source;

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

import android.os.Handler;
import android.os.Looper;
import androidx.annotation.Nullable;
import androidx.media3.common.Timeline;
import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.datasource.TransferListener;
import androidx.media3.exoplayer.analytics.PlayerId;
import androidx.media3.exoplayer.drm.DrmSessionEventListener;
import java.util.ArrayList;
import java.util.HashSet;

/**
 * Base {@link MediaSource} implementation to handle parallel reuse and to keep a list of {@link
 * MediaSourceEventListener}s.
 *
 * <p>Whenever an implementing subclass needs to provide a new timeline, it must call {@link
 * #refreshSourceInfo(Timeline)} to notify all listeners.
 */
@UnstableApi
public abstract class BaseMediaSource implements MediaSource {

  private final ArrayList<MediaSourceCaller> mediaSourceCallers;
  private final HashSet<MediaSourceCaller> enabledMediaSourceCallers;
  private final MediaSourceEventListener.EventDispatcher eventDispatcher;
  private final DrmSessionEventListener.EventDispatcher drmEventDispatcher;

  @Nullable private Looper looper;
  @Nullable private Timeline timeline;
  @Nullable private PlayerId playerId;

  public BaseMediaSource() {
    mediaSourceCallers = new ArrayList<>(/* initialCapacity= */ 1);
    enabledMediaSourceCallers = new HashSet<>(/* initialCapacity= */ 1);
    eventDispatcher = new MediaSourceEventListener.EventDispatcher();
    drmEventDispatcher = new DrmSessionEventListener.EventDispatcher();
  }

  /**
   * Starts source preparation and enables the source, see {@link #prepareSource(MediaSourceCaller,
   * TransferListener, PlayerId)}. This method is called at most once until the next call to {@link
   * #releaseSourceInternal()}.
   *
   * @param mediaTransferListener The transfer listener which should be informed of any media data
   *     transfers. May be null if no listener is available. Note that this listener should usually
   *     be only informed of transfers related to the media loads and not of auxiliary loads for
   *     manifests and other data.
   */
  protected abstract void prepareSourceInternal(@Nullable TransferListener mediaTransferListener);

  /** Enables the source, see {@link #enable(MediaSourceCaller)}. */
  protected void enableInternal() {}

  /** Disables the source, see {@link #disable(MediaSourceCaller)}. */
  protected void disableInternal() {}

  /**
   * Releases the source, see {@link #releaseSource(MediaSourceCaller)}. This method is called
   * exactly once after each call to {@link #prepareSourceInternal(TransferListener)}.
   */
  protected abstract void releaseSourceInternal();

  /**
   * Updates timeline and manifest and notifies all listeners of the update.
   *
   * @param timeline The new {@link Timeline}.
   */
  protected final void refreshSourceInfo(Timeline timeline) {
    this.timeline = timeline;
    for (MediaSourceCaller caller : mediaSourceCallers) {
      caller.onSourceInfoRefreshed(/* source= */ this, timeline);
    }
  }

  /**
   * Returns a {@link MediaSourceEventListener.EventDispatcher} which dispatches all events to the
   * registered listeners with the specified {@link MediaPeriodId}.
   *
   * @param mediaPeriodId The {@link MediaPeriodId} to be reported with the events. May be null, if
   *     the events do not belong to a specific media period.
   * @return An event dispatcher with pre-configured media period id.
   */
  protected final MediaSourceEventListener.EventDispatcher createEventDispatcher(
      @Nullable MediaPeriodId mediaPeriodId) {
    return eventDispatcher.withParameters(/* windowIndex= */ 0, mediaPeriodId);
  }

  /**
   * Returns a {@link MediaSourceEventListener.EventDispatcher} which dispatches all events to the
   * registered listeners with the specified window index and {@link MediaPeriodId}.
   *
   * @param windowIndex The timeline window index to be reported with the events.
   * @param mediaPeriodId The {@link MediaPeriodId} to be reported with the events. May be null, if
   *     the events do not belong to a specific media period.
   * @return An event dispatcher with pre-configured media period id.
   */
  protected final MediaSourceEventListener.EventDispatcher createEventDispatcher(
      int windowIndex, @Nullable MediaPeriodId mediaPeriodId) {
    return eventDispatcher.withParameters(windowIndex, mediaPeriodId);
  }

  /**
   * Note: The {@code mediaTimeOffsetMs} passed to this method is ignored and not added to media
   * times in any way.
   *
   * @deprecated Use {@link #createEventDispatcher(MediaPeriodId)} instead.
   */
  @Deprecated
  protected final MediaSourceEventListener.EventDispatcher createEventDispatcher(
      MediaPeriodId mediaPeriodId, long mediaTimeOffsetMs) {
    Assertions.checkNotNull(mediaPeriodId);
    return eventDispatcher.withParameters(/* windowIndex= */ 0, mediaPeriodId);
  }

  /**
   * Note: The {@code mediaTimeOffsetMs} passed to this method is ignored and not added to media
   * times in any way.
   *
   * @deprecated Use {@link #createEventDispatcher(int, MediaPeriodId)} instead.
   */
  @Deprecated
  protected final MediaSourceEventListener.EventDispatcher createEventDispatcher(
      int windowIndex, @Nullable MediaPeriodId mediaPeriodId, long mediaTimeOffsetMs) {
    return eventDispatcher.withParameters(windowIndex, mediaPeriodId);
  }

  /**
   * Returns a {@link DrmSessionEventListener.EventDispatcher} which dispatches all events to the
   * registered listeners with the specified {@link MediaPeriodId}
   *
   * @param mediaPeriodId The {@link MediaPeriodId} to be reported with the events. May be null, if
   *     the events do not belong to a specific media period.
   * @return An event dispatcher with pre-configured media period id.
   */
  protected final DrmSessionEventListener.EventDispatcher createDrmEventDispatcher(
      @Nullable MediaPeriodId mediaPeriodId) {
    return drmEventDispatcher.withParameters(/* windowIndex= */ 0, mediaPeriodId);
  }

  /**
   * Returns a {@link DrmSessionEventListener.EventDispatcher} which dispatches all events to the
   * registered listeners with the specified window index and {@link MediaPeriodId}.
   *
   * @param windowIndex The timeline window index to be reported with the events.
   * @param mediaPeriodId The {@link MediaPeriodId} to be reported with the events. May be null, if
   *     the events do not belong to a specific media period.
   * @return An event dispatcher with pre-configured media period id and time offset.
   */
  protected final DrmSessionEventListener.EventDispatcher createDrmEventDispatcher(
      int windowIndex, @Nullable MediaPeriodId mediaPeriodId) {
    return drmEventDispatcher.withParameters(windowIndex, mediaPeriodId);
  }

  /** Returns whether the source is enabled. */
  protected final boolean isEnabled() {
    return !enabledMediaSourceCallers.isEmpty();
  }

  /**
   * Returns the {@link PlayerId} of the player using this media source.
   *
   * <p>Must only be used when the media source is {@link #prepareSourceInternal(TransferListener)
   * prepared} or has {@linkplain #setPlayerId a player ID set}.
   */
  protected final PlayerId getPlayerId() {
    return checkStateNotNull(playerId);
  }

  /**
   * Sets the {@link PlayerId} of the player using this media source.
   *
   * @param playerId The player ID to be set.
   */
  protected final void setPlayerId(PlayerId playerId) {
    this.playerId = playerId;
  }

  /**
   * Returns whether the source has {@link MediaSource#prepareSource(MediaSourceCaller,
   * TransferListener, PlayerId)} called.
   */
  protected final boolean prepareSourceCalled() {
    return !mediaSourceCallers.isEmpty();
  }

  @UnstableApi
  @Override
  public final void addEventListener(Handler handler, MediaSourceEventListener eventListener) {
    Assertions.checkNotNull(handler);
    Assertions.checkNotNull(eventListener);
    eventDispatcher.addEventListener(handler, eventListener);
  }

  @UnstableApi
  @Override
  public final void removeEventListener(MediaSourceEventListener eventListener) {
    eventDispatcher.removeEventListener(eventListener);
  }

  @UnstableApi
  @Override
  public final void addDrmEventListener(Handler handler, DrmSessionEventListener eventListener) {
    Assertions.checkNotNull(handler);
    Assertions.checkNotNull(eventListener);
    drmEventDispatcher.addEventListener(handler, eventListener);
  }

  @UnstableApi
  @Override
  public final void removeDrmEventListener(DrmSessionEventListener eventListener) {
    drmEventDispatcher.removeEventListener(eventListener);
  }

  @UnstableApi
  @SuppressWarnings("deprecation") // Overriding deprecated method to make it final.
  @Override
  public final void prepareSource(
      MediaSourceCaller caller, @Nullable TransferListener mediaTransferListener) {
    prepareSource(caller, mediaTransferListener, PlayerId.UNSET);
  }

  @UnstableApi
  @Override
  public final void prepareSource(
      MediaSourceCaller caller,
      @Nullable TransferListener mediaTransferListener,
      PlayerId playerId) {
    Looper looper = Looper.myLooper();
    Assertions.checkArgument(this.looper == null || this.looper == looper);
    this.playerId = playerId;
    @Nullable Timeline timeline = this.timeline;
    mediaSourceCallers.add(caller);
    if (this.looper == null) {
      this.looper = looper;
      enabledMediaSourceCallers.add(caller);
      prepareSourceInternal(mediaTransferListener);
    } else if (timeline != null) {
      enable(caller);
      caller.onSourceInfoRefreshed(/* source= */ this, timeline);
    }
  }

  @UnstableApi
  @Override
  public final void enable(MediaSourceCaller caller) {
    Assertions.checkNotNull(looper);
    boolean wasDisabled = enabledMediaSourceCallers.isEmpty();
    enabledMediaSourceCallers.add(caller);
    if (wasDisabled) {
      enableInternal();
    }
  }

  @UnstableApi
  @Override
  public final void disable(MediaSourceCaller caller) {
    boolean wasEnabled = !enabledMediaSourceCallers.isEmpty();
    enabledMediaSourceCallers.remove(caller);
    if (wasEnabled && enabledMediaSourceCallers.isEmpty()) {
      disableInternal();
    }
  }

  @UnstableApi
  @Override
  public final void releaseSource(MediaSourceCaller caller) {
    mediaSourceCallers.remove(caller);
    if (mediaSourceCallers.isEmpty()) {
      looper = null;
      timeline = null;
      playerId = null;
      enabledMediaSourceCallers.clear();
      releaseSourceInternal();
    } else {
      disable(caller);
    }
  }
}