public abstract class

BasePlayer

extends java.lang.Object

implements Player

 java.lang.Object

↳androidx.media3.common.BasePlayer

Subclasses:

SimpleExoPlayer, CastPlayer, StubPlayer, StubExoPlayer

Gradle dependencies

compile group: 'androidx.media3', name: 'media3-common', version: '1.0.0-alpha03'

  • groupId: androidx.media3
  • artifactId: media3-common
  • version: 1.0.0-alpha03

Artifact androidx.media3:media3-common:1.0.0-alpha03 it located at Google repository (https://maven.google.com/)

Overview

Abstract base Player which implements common implementation independent methods.

Summary

Fields
protected final Timeline.Windowwindow

Constructors
protectedBasePlayer()

Methods
public final voidaddMediaItem(int index, MediaItem mediaItem)

public final voidaddMediaItem(MediaItem mediaItem)

public final voidaddMediaItems(java.util.List<MediaItem> mediaItems)

public final booleancanAdvertiseSession()

public final voidclearMediaItems()

public final intgetBufferedPercentage()

public final longgetContentDuration()

public final longgetCurrentLiveOffset()

public final java.lang.ObjectgetCurrentManifest()

public final MediaItemgetCurrentMediaItem()

public final intgetCurrentWindowIndex()

public final MediaItemgetMediaItemAt(int index)

public final intgetMediaItemCount()

public final intgetNextMediaItemIndex()

public final intgetNextWindowIndex()

public final intgetPreviousMediaItemIndex()

public final intgetPreviousWindowIndex()

public final booleanhasNext()

public final booleanhasNextMediaItem()

public final booleanhasNextWindow()

public final booleanhasPrevious()

public final booleanhasPreviousMediaItem()

public final booleanhasPreviousWindow()

public final booleanisCommandAvailable(int command)

public final booleanisCurrentMediaItemDynamic()

public final booleanisCurrentMediaItemLive()

public final booleanisCurrentMediaItemSeekable()

public final booleanisCurrentWindowDynamic()

public final booleanisCurrentWindowLive()

public final booleanisCurrentWindowSeekable()

public final booleanisPlaying()

public final voidmoveMediaItem(int currentIndex, int newIndex)

public final voidnext()

public final voidpause()

public final voidplay()

public final voidprevious()

public final voidremoveMediaItem(int index)

public final voidseekBack()

public final voidseekForward()

public final voidseekTo(long positionMs)

public final voidseekToDefaultPosition()

public final voidseekToDefaultPosition(int mediaItemIndex)

public final voidseekToNext()

public final voidseekToNextMediaItem()

public final voidseekToNextWindow()

public final voidseekToPrevious()

public final voidseekToPreviousMediaItem()

public final voidseekToPreviousWindow()

public final voidsetMediaItem(MediaItem mediaItem)

public final voidsetMediaItem(MediaItem mediaItem, boolean resetPosition)

public final voidsetMediaItem(MediaItem mediaItem, long startPositionMs)

public final voidsetMediaItems(java.util.List<MediaItem> mediaItems)

public final voidsetPlaybackSpeed(float speed)

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

Fields

protected final Timeline.Window window

Constructors

protected BasePlayer()

Methods

public final void setMediaItem(MediaItem mediaItem)

public final void setMediaItem(MediaItem mediaItem, long startPositionMs)

public final void setMediaItem(MediaItem mediaItem, boolean resetPosition)

public final void setMediaItems(java.util.List<MediaItem> mediaItems)

public final void addMediaItem(int index, MediaItem mediaItem)

public final void addMediaItem(MediaItem mediaItem)

public final void addMediaItems(java.util.List<MediaItem> mediaItems)

public final void moveMediaItem(int currentIndex, int newIndex)

public final void removeMediaItem(int index)

public final void clearMediaItems()

public final boolean isCommandAvailable(int command)

public final boolean canAdvertiseSession()

BasePlayer and its descendents will return true.

public final void play()

public final void pause()

public final boolean isPlaying()

public final void seekToDefaultPosition()

public final void seekToDefaultPosition(int mediaItemIndex)

public final void seekTo(long positionMs)

public final void seekBack()

public final void seekForward()

public final boolean hasPrevious()

public final boolean hasPreviousWindow()

public final boolean hasPreviousMediaItem()

public final void previous()

public final void seekToPreviousWindow()

public final void seekToPreviousMediaItem()

public final void seekToPrevious()

public final boolean hasNext()

public final boolean hasNextWindow()

public final boolean hasNextMediaItem()

public final void next()

public final void seekToNextWindow()

public final void seekToNextMediaItem()

public final void seekToNext()

public final void setPlaybackSpeed(float speed)

public final int getCurrentWindowIndex()

public final int getNextWindowIndex()

public final int getNextMediaItemIndex()

public final int getPreviousWindowIndex()

public final int getPreviousMediaItemIndex()

public final MediaItem getCurrentMediaItem()

public final int getMediaItemCount()

public final MediaItem getMediaItemAt(int index)

public final java.lang.Object getCurrentManifest()

public final int getBufferedPercentage()

public final boolean isCurrentWindowDynamic()

public final boolean isCurrentMediaItemDynamic()

public final boolean isCurrentWindowLive()

public final boolean isCurrentMediaItemLive()

public final long getCurrentLiveOffset()

public final boolean isCurrentWindowSeekable()

public final boolean isCurrentMediaItemSeekable()

public final long getContentDuration()

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.common;

import static java.lang.Math.max;
import static java.lang.Math.min;

import androidx.annotation.Nullable;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import java.util.Collections;
import java.util.List;

/** Abstract base {@link Player} which implements common implementation independent methods. */
@UnstableApi
public abstract class BasePlayer implements Player {

  protected final Timeline.Window window;

  protected BasePlayer() {
    window = new Timeline.Window();
  }

  @Override
  public final void setMediaItem(MediaItem mediaItem) {
    setMediaItems(Collections.singletonList(mediaItem));
  }

  @Override
  public final void setMediaItem(MediaItem mediaItem, long startPositionMs) {
    setMediaItems(Collections.singletonList(mediaItem), /* startWindowIndex= */ 0, startPositionMs);
  }

  @Override
  public final void setMediaItem(MediaItem mediaItem, boolean resetPosition) {
    setMediaItems(Collections.singletonList(mediaItem), resetPosition);
  }

  @Override
  public final void setMediaItems(List<MediaItem> mediaItems) {
    setMediaItems(mediaItems, /* resetPosition= */ true);
  }

  @Override
  public final void addMediaItem(int index, MediaItem mediaItem) {
    addMediaItems(index, Collections.singletonList(mediaItem));
  }

  @Override
  public final void addMediaItem(MediaItem mediaItem) {
    addMediaItems(Collections.singletonList(mediaItem));
  }

  @Override
  public final void addMediaItems(List<MediaItem> mediaItems) {
    addMediaItems(/* index= */ Integer.MAX_VALUE, mediaItems);
  }

  @Override
  public final void moveMediaItem(int currentIndex, int newIndex) {
    if (currentIndex != newIndex) {
      moveMediaItems(/* fromIndex= */ currentIndex, /* toIndex= */ currentIndex + 1, newIndex);
    }
  }

  @Override
  public final void removeMediaItem(int index) {
    removeMediaItems(/* fromIndex= */ index, /* toIndex= */ index + 1);
  }

  @Override
  public final void clearMediaItems() {
    removeMediaItems(/* fromIndex= */ 0, /* toIndex= */ Integer.MAX_VALUE);
  }

  @Override
  public final boolean isCommandAvailable(@Command int command) {
    return getAvailableCommands().contains(command);
  }

  /**
   * {@inheritDoc}
   *
   * <p>BasePlayer and its descendents will return {@code true}.
   */
  @Override
  public final boolean canAdvertiseSession() {
    return true;
  }

  @Override
  public final void play() {
    setPlayWhenReady(true);
  }

  @Override
  public final void pause() {
    setPlayWhenReady(false);
  }

  @Override
  public final boolean isPlaying() {
    return getPlaybackState() == Player.STATE_READY
        && getPlayWhenReady()
        && getPlaybackSuppressionReason() == PLAYBACK_SUPPRESSION_REASON_NONE;
  }

  @Override
  public final void seekToDefaultPosition() {
    seekToDefaultPosition(getCurrentMediaItemIndex());
  }

  @Override
  public final void seekToDefaultPosition(int mediaItemIndex) {
    seekTo(mediaItemIndex, /* positionMs= */ C.TIME_UNSET);
  }

  @Override
  public final void seekTo(long positionMs) {
    seekTo(getCurrentMediaItemIndex(), positionMs);
  }

  @Override
  public final void seekBack() {
    seekToOffset(-getSeekBackIncrement());
  }

  @Override
  public final void seekForward() {
    seekToOffset(getSeekForwardIncrement());
  }

  @Deprecated
  @Override
  public final boolean hasPrevious() {
    return hasPreviousMediaItem();
  }

  @Deprecated
  @Override
  public final boolean hasPreviousWindow() {
    return hasPreviousMediaItem();
  }

  @Override
  public final boolean hasPreviousMediaItem() {
    return getPreviousMediaItemIndex() != C.INDEX_UNSET;
  }

  @Deprecated
  @Override
  public final void previous() {
    seekToPreviousMediaItem();
  }

  @Deprecated
  @Override
  public final void seekToPreviousWindow() {
    seekToPreviousMediaItem();
  }

  @Override
  public final void seekToPreviousMediaItem() {
    int previousMediaItemIndex = getPreviousMediaItemIndex();
    if (previousMediaItemIndex != C.INDEX_UNSET) {
      seekToDefaultPosition(previousMediaItemIndex);
    }
  }

  @Override
  public final void seekToPrevious() {
    Timeline timeline = getCurrentTimeline();
    if (timeline.isEmpty() || isPlayingAd()) {
      return;
    }
    boolean hasPreviousMediaItem = hasPreviousMediaItem();
    if (isCurrentMediaItemLive() && !isCurrentMediaItemSeekable()) {
      if (hasPreviousMediaItem) {
        seekToPreviousMediaItem();
      }
    } else if (hasPreviousMediaItem && getCurrentPosition() <= getMaxSeekToPreviousPosition()) {
      seekToPreviousMediaItem();
    } else {
      seekTo(/* positionMs= */ 0);
    }
  }

  @Deprecated
  @Override
  public final boolean hasNext() {
    return hasNextMediaItem();
  }

  @Deprecated
  @Override
  public final boolean hasNextWindow() {
    return hasNextMediaItem();
  }

  @Override
  public final boolean hasNextMediaItem() {
    return getNextMediaItemIndex() != C.INDEX_UNSET;
  }

  @Deprecated
  @Override
  public final void next() {
    seekToNextMediaItem();
  }

  @Deprecated
  @Override
  public final void seekToNextWindow() {
    seekToNextMediaItem();
  }

  @Override
  public final void seekToNextMediaItem() {
    int nextMediaItemIndex = getNextMediaItemIndex();
    if (nextMediaItemIndex != C.INDEX_UNSET) {
      seekToDefaultPosition(nextMediaItemIndex);
    }
  }

  @Override
  public final void seekToNext() {
    Timeline timeline = getCurrentTimeline();
    if (timeline.isEmpty() || isPlayingAd()) {
      return;
    }
    if (hasNextMediaItem()) {
      seekToNextMediaItem();
    } else if (isCurrentMediaItemLive() && isCurrentMediaItemDynamic()) {
      seekToDefaultPosition();
    }
  }

  @Override
  public final void setPlaybackSpeed(float speed) {
    setPlaybackParameters(getPlaybackParameters().withSpeed(speed));
  }

  @Deprecated
  @Override
  public final int getCurrentWindowIndex() {
    return getCurrentMediaItemIndex();
  }

  @Deprecated
  @Override
  public final int getNextWindowIndex() {
    return getNextMediaItemIndex();
  }

  @Override
  public final int getNextMediaItemIndex() {
    Timeline timeline = getCurrentTimeline();
    return timeline.isEmpty()
        ? C.INDEX_UNSET
        : timeline.getNextWindowIndex(
            getCurrentMediaItemIndex(), getRepeatModeForNavigation(), getShuffleModeEnabled());
  }

  @Deprecated
  @Override
  public final int getPreviousWindowIndex() {
    return getPreviousMediaItemIndex();
  }

  @Override
  public final int getPreviousMediaItemIndex() {
    Timeline timeline = getCurrentTimeline();
    return timeline.isEmpty()
        ? C.INDEX_UNSET
        : timeline.getPreviousWindowIndex(
            getCurrentMediaItemIndex(), getRepeatModeForNavigation(), getShuffleModeEnabled());
  }

  @Override
  @Nullable
  public final MediaItem getCurrentMediaItem() {
    Timeline timeline = getCurrentTimeline();
    return timeline.isEmpty()
        ? null
        : timeline.getWindow(getCurrentMediaItemIndex(), window).mediaItem;
  }

  @Override
  public final int getMediaItemCount() {
    return getCurrentTimeline().getWindowCount();
  }

  @Override
  public final MediaItem getMediaItemAt(int index) {
    return getCurrentTimeline().getWindow(index, window).mediaItem;
  }

  @Override
  @Nullable
  public final Object getCurrentManifest() {
    Timeline timeline = getCurrentTimeline();
    return timeline.isEmpty()
        ? null
        : timeline.getWindow(getCurrentMediaItemIndex(), window).manifest;
  }

  @Override
  public final int getBufferedPercentage() {
    long position = getBufferedPosition();
    long duration = getDuration();
    return position == C.TIME_UNSET || duration == C.TIME_UNSET
        ? 0
        : duration == 0 ? 100 : Util.constrainValue((int) ((position * 100) / duration), 0, 100);
  }

  @Deprecated
  @Override
  public final boolean isCurrentWindowDynamic() {
    return isCurrentMediaItemDynamic();
  }

  @Override
  public final boolean isCurrentMediaItemDynamic() {
    Timeline timeline = getCurrentTimeline();
    return !timeline.isEmpty() && timeline.getWindow(getCurrentMediaItemIndex(), window).isDynamic;
  }

  @Deprecated
  @Override
  public final boolean isCurrentWindowLive() {
    return isCurrentMediaItemLive();
  }

  @Override
  public final boolean isCurrentMediaItemLive() {
    Timeline timeline = getCurrentTimeline();
    return !timeline.isEmpty() && timeline.getWindow(getCurrentMediaItemIndex(), window).isLive();
  }

  @Override
  public final long getCurrentLiveOffset() {
    Timeline timeline = getCurrentTimeline();
    if (timeline.isEmpty()) {
      return C.TIME_UNSET;
    }
    long windowStartTimeMs =
        timeline.getWindow(getCurrentMediaItemIndex(), window).windowStartTimeMs;
    if (windowStartTimeMs == C.TIME_UNSET) {
      return C.TIME_UNSET;
    }
    return window.getCurrentUnixTimeMs() - window.windowStartTimeMs - getContentPosition();
  }

  @Deprecated
  @Override
  public final boolean isCurrentWindowSeekable() {
    return isCurrentMediaItemSeekable();
  }

  @Override
  public final boolean isCurrentMediaItemSeekable() {
    Timeline timeline = getCurrentTimeline();
    return !timeline.isEmpty() && timeline.getWindow(getCurrentMediaItemIndex(), window).isSeekable;
  }

  @Override
  public final long getContentDuration() {
    Timeline timeline = getCurrentTimeline();
    return timeline.isEmpty()
        ? C.TIME_UNSET
        : timeline.getWindow(getCurrentMediaItemIndex(), window).getDurationMs();
  }

  private @RepeatMode int getRepeatModeForNavigation() {
    @RepeatMode int repeatMode = getRepeatMode();
    return repeatMode == REPEAT_MODE_ONE ? REPEAT_MODE_OFF : repeatMode;
  }

  private void seekToOffset(long offsetMs) {
    long positionMs = getCurrentPosition() + offsetMs;
    long durationMs = getDuration();
    if (durationMs != C.TIME_UNSET) {
      positionMs = min(positionMs, durationMs);
    }
    positionMs = max(positionMs, 0);
    seekTo(positionMs);
  }
}