2458 lines
91 KiB
Java
2458 lines
91 KiB
Java
![]() |
/*
|
||
|
* Copyright (C) 2017 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 com.google.android.exoplayer2;
|
||
|
|
||
|
import static java.lang.annotation.ElementType.FIELD;
|
||
|
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
|
||
|
import static java.lang.annotation.ElementType.METHOD;
|
||
|
import static java.lang.annotation.ElementType.PARAMETER;
|
||
|
import static java.lang.annotation.ElementType.TYPE_USE;
|
||
|
|
||
|
import android.os.Bundle;
|
||
|
import android.os.Looper;
|
||
|
import android.view.Surface;
|
||
|
import android.view.SurfaceHolder;
|
||
|
import android.view.SurfaceView;
|
||
|
import android.view.TextureView;
|
||
|
import androidx.annotation.FloatRange;
|
||
|
import androidx.annotation.IntDef;
|
||
|
import androidx.annotation.IntRange;
|
||
|
import androidx.annotation.Nullable;
|
||
|
import com.google.android.exoplayer2.audio.AudioAttributes;
|
||
|
import com.google.android.exoplayer2.metadata.Metadata;
|
||
|
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||
|
import com.google.android.exoplayer2.text.Cue;
|
||
|
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||
|
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||
|
import com.google.android.exoplayer2.trackselection.TrackSelectionParameters;
|
||
|
import com.google.android.exoplayer2.util.BundleableUtil;
|
||
|
import com.google.android.exoplayer2.util.FlagSet;
|
||
|
import com.google.android.exoplayer2.util.Util;
|
||
|
import com.google.android.exoplayer2.video.VideoSize;
|
||
|
import com.google.common.base.Objects;
|
||
|
import java.lang.annotation.Documented;
|
||
|
import java.lang.annotation.Retention;
|
||
|
import java.lang.annotation.RetentionPolicy;
|
||
|
import java.lang.annotation.Target;
|
||
|
import java.util.ArrayList;
|
||
|
import java.util.List;
|
||
|
|
||
|
/**
|
||
|
* A media player interface defining traditional high-level functionality, such as the ability to
|
||
|
* play, pause, seek and query properties of the currently playing media.
|
||
|
*
|
||
|
* <p>This interface includes some convenience methods that can be implemented by calling other
|
||
|
* methods in the interface. {@link BasePlayer} implements these convenience methods so inheriting
|
||
|
* {@link BasePlayer} is recommended when implementing the interface so that only the minimal set of
|
||
|
* required methods can be implemented.
|
||
|
*
|
||
|
* <p>Some important properties of media players that implement this interface are:
|
||
|
*
|
||
|
* <ul>
|
||
|
* <li>They can provide a {@link Timeline} representing the structure of the media being played,
|
||
|
* which can be obtained by calling {@link #getCurrentTimeline()}.
|
||
|
* <li>They can provide a {@link TracksInfo} defining the currently available tracks and which are
|
||
|
* selected to be rendered, which can be obtained by calling {@link #getCurrentTracksInfo()}.
|
||
|
* </ul>
|
||
|
*/
|
||
|
public interface Player {
|
||
|
|
||
|
/**
|
||
|
* Listener of changes in player state.
|
||
|
*
|
||
|
* <p>All methods have no-op default implementations to allow selective overrides.
|
||
|
*
|
||
|
* <p>Listeners can choose to implement individual events (e.g. {@link
|
||
|
* #onIsPlayingChanged(boolean)}) or {@link #onEvents(Player, Events)}, which is called after one
|
||
|
* or more events occurred together.
|
||
|
*
|
||
|
* @deprecated Use {@link Player.Listener}.
|
||
|
*/
|
||
|
@Deprecated
|
||
|
interface EventListener {
|
||
|
|
||
|
/**
|
||
|
* Called when the timeline has been refreshed.
|
||
|
*
|
||
|
* <p>Note that the current {@link MediaItem} or playback position may change as a result of a
|
||
|
* timeline change. If playback can't continue smoothly because of this timeline change, a
|
||
|
* separate {@link #onPositionDiscontinuity(PositionInfo, PositionInfo, int)} callback will be
|
||
|
* triggered.
|
||
|
*
|
||
|
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||
|
* other events that happen in the same {@link Looper} message queue iteration.
|
||
|
*
|
||
|
* @param timeline The latest timeline. Never null, but may be empty.
|
||
|
* @param reason The {@link TimelineChangeReason} responsible for this timeline change.
|
||
|
*/
|
||
|
default void onTimelineChanged(Timeline timeline, @TimelineChangeReason int reason) {}
|
||
|
|
||
|
/**
|
||
|
* Called when playback transitions to a media item or starts repeating a media item according
|
||
|
* to the current {@link #getRepeatMode() repeat mode}.
|
||
|
*
|
||
|
* <p>Note that this callback is also called when the playlist becomes non-empty or empty as a
|
||
|
* consequence of a playlist change.
|
||
|
*
|
||
|
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||
|
* other events that happen in the same {@link Looper} message queue iteration.
|
||
|
*
|
||
|
* @param mediaItem The {@link MediaItem}. May be null if the playlist becomes empty.
|
||
|
* @param reason The reason for the transition.
|
||
|
*/
|
||
|
default void onMediaItemTransition(
|
||
|
@Nullable MediaItem mediaItem, @MediaItemTransitionReason int reason) {}
|
||
|
|
||
|
/**
|
||
|
* Called when the available or selected tracks change.
|
||
|
*
|
||
|
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||
|
* other events that happen in the same {@link Looper} message queue iteration.
|
||
|
*
|
||
|
* @param trackGroups The available tracks. Never null, but may be of length zero.
|
||
|
* @param trackSelections The selected tracks. Never null, but may contain null elements. A
|
||
|
* concrete implementation may include null elements if it has a fixed number of renderer
|
||
|
* components, wishes to report a TrackSelection for each of them, and has one or more
|
||
|
* renderer components that is not assigned any selected tracks.
|
||
|
* @deprecated Use {@link #onTracksInfoChanged(TracksInfo)} instead.
|
||
|
*/
|
||
|
@Deprecated
|
||
|
default void onTracksChanged(
|
||
|
TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {}
|
||
|
|
||
|
/**
|
||
|
* Called when the available or selected tracks change.
|
||
|
*
|
||
|
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||
|
* other events that happen in the same {@link Looper} message queue iteration.
|
||
|
*
|
||
|
* @param tracksInfo The available tracks information. Never null, but may be of length zero.
|
||
|
*/
|
||
|
default void onTracksInfoChanged(TracksInfo tracksInfo) {}
|
||
|
|
||
|
/**
|
||
|
* Called when the combined {@link MediaMetadata} changes.
|
||
|
*
|
||
|
* <p>The provided {@link MediaMetadata} is a combination of the {@link MediaItem#mediaMetadata}
|
||
|
* and the static and dynamic metadata from the {@link TrackSelection#getFormat(int) track
|
||
|
* selections' formats} and {@link Listener#onMetadata(Metadata)}. If a field is populated in
|
||
|
* the {@link MediaItem#mediaMetadata}, it will be prioritised above the same field coming from
|
||
|
* static or dynamic metadata.
|
||
|
*
|
||
|
* <p>This method may be called multiple times in quick succession.
|
||
|
*
|
||
|
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||
|
* other events that happen in the same {@link Looper} message queue iteration.
|
||
|
*
|
||
|
* @param mediaMetadata The combined {@link MediaMetadata}.
|
||
|
*/
|
||
|
default void onMediaMetadataChanged(MediaMetadata mediaMetadata) {}
|
||
|
|
||
|
/** Called when the playlist {@link MediaMetadata} changes. */
|
||
|
default void onPlaylistMetadataChanged(MediaMetadata mediaMetadata) {}
|
||
|
|
||
|
/**
|
||
|
* Called when the player starts or stops loading the source.
|
||
|
*
|
||
|
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||
|
* other events that happen in the same {@link Looper} message queue iteration.
|
||
|
*
|
||
|
* @param isLoading Whether the source is currently being loaded.
|
||
|
*/
|
||
|
default void onIsLoadingChanged(boolean isLoading) {}
|
||
|
|
||
|
/** @deprecated Use {@link #onIsLoadingChanged(boolean)} instead. */
|
||
|
@Deprecated
|
||
|
default void onLoadingChanged(boolean isLoading) {}
|
||
|
|
||
|
/**
|
||
|
* Called when the value returned from {@link #isCommandAvailable(int)} changes for at least one
|
||
|
* {@link Command}.
|
||
|
*
|
||
|
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||
|
* other events that happen in the same {@link Looper} message queue iteration.
|
||
|
*
|
||
|
* @param availableCommands The available {@link Commands}.
|
||
|
*/
|
||
|
default void onAvailableCommandsChanged(Commands availableCommands) {}
|
||
|
|
||
|
/**
|
||
|
* Called when the value returned from {@link #getTrackSelectionParameters()} changes.
|
||
|
*
|
||
|
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||
|
* other events that happen in the same {@link Looper} message queue iteration.
|
||
|
*
|
||
|
* @param parameters The new {@link TrackSelectionParameters}.
|
||
|
*/
|
||
|
default void onTrackSelectionParametersChanged(TrackSelectionParameters parameters) {}
|
||
|
|
||
|
/**
|
||
|
* @deprecated Use {@link #onPlaybackStateChanged(int)} and {@link
|
||
|
* #onPlayWhenReadyChanged(boolean, int)} instead.
|
||
|
*/
|
||
|
@Deprecated
|
||
|
default void onPlayerStateChanged(boolean playWhenReady, @State int playbackState) {}
|
||
|
|
||
|
/**
|
||
|
* Called when the value returned from {@link #getPlaybackState()} changes.
|
||
|
*
|
||
|
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||
|
* other events that happen in the same {@link Looper} message queue iteration.
|
||
|
*
|
||
|
* @param playbackState The new playback {@link State state}.
|
||
|
*/
|
||
|
default void onPlaybackStateChanged(@State int playbackState) {}
|
||
|
|
||
|
/**
|
||
|
* Called when the value returned from {@link #getPlayWhenReady()} changes.
|
||
|
*
|
||
|
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||
|
* other events that happen in the same {@link Looper} message queue iteration.
|
||
|
*
|
||
|
* @param playWhenReady Whether playback will proceed when ready.
|
||
|
* @param reason The {@link PlayWhenReadyChangeReason reason} for the change.
|
||
|
*/
|
||
|
default void onPlayWhenReadyChanged(
|
||
|
boolean playWhenReady, @PlayWhenReadyChangeReason int reason) {}
|
||
|
|
||
|
/**
|
||
|
* Called when the value returned from {@link #getPlaybackSuppressionReason()} changes.
|
||
|
*
|
||
|
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||
|
* other events that happen in the same {@link Looper} message queue iteration.
|
||
|
*
|
||
|
* @param playbackSuppressionReason The current {@link PlaybackSuppressionReason}.
|
||
|
*/
|
||
|
default void onPlaybackSuppressionReasonChanged(
|
||
|
@PlaybackSuppressionReason int playbackSuppressionReason) {}
|
||
|
|
||
|
/**
|
||
|
* Called when the value of {@link #isPlaying()} changes.
|
||
|
*
|
||
|
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||
|
* other events that happen in the same {@link Looper} message queue iteration.
|
||
|
*
|
||
|
* @param isPlaying Whether the player is playing.
|
||
|
*/
|
||
|
default void onIsPlayingChanged(boolean isPlaying) {}
|
||
|
|
||
|
/**
|
||
|
* Called when the value of {@link #getRepeatMode()} changes.
|
||
|
*
|
||
|
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||
|
* other events that happen in the same {@link Looper} message queue iteration.
|
||
|
*
|
||
|
* @param repeatMode The {@link RepeatMode} used for playback.
|
||
|
*/
|
||
|
default void onRepeatModeChanged(@RepeatMode int repeatMode) {}
|
||
|
|
||
|
/**
|
||
|
* Called when the value of {@link #getShuffleModeEnabled()} changes.
|
||
|
*
|
||
|
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||
|
* other events that happen in the same {@link Looper} message queue iteration.
|
||
|
*
|
||
|
* @param shuffleModeEnabled Whether shuffling of {@link MediaItem media items} is enabled.
|
||
|
*/
|
||
|
default void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {}
|
||
|
|
||
|
/**
|
||
|
* Called when an error occurs. The playback state will transition to {@link #STATE_IDLE}
|
||
|
* immediately after this method is called. The player instance can still be used, and {@link
|
||
|
* #release()} must still be called on the player should it no longer be required.
|
||
|
*
|
||
|
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||
|
* other events that happen in the same {@link Looper} message queue iteration.
|
||
|
*
|
||
|
* <p>Implementations of Player may pass an instance of a subclass of {@link PlaybackException}
|
||
|
* to this method in order to include more information about the error.
|
||
|
*
|
||
|
* @param error The error.
|
||
|
*/
|
||
|
default void onPlayerError(PlaybackException error) {}
|
||
|
|
||
|
/**
|
||
|
* Called when the {@link PlaybackException} returned by {@link #getPlayerError()} changes.
|
||
|
*
|
||
|
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||
|
* other events that happen in the same {@link Looper} message queue iteration.
|
||
|
*
|
||
|
* <p>Implementations of Player may pass an instance of a subclass of {@link PlaybackException}
|
||
|
* to this method in order to include more information about the error.
|
||
|
*
|
||
|
* @param error The new error, or null if the error is being cleared.
|
||
|
*/
|
||
|
default void onPlayerErrorChanged(@Nullable PlaybackException error) {}
|
||
|
|
||
|
/**
|
||
|
* @deprecated Use {@link #onPositionDiscontinuity(PositionInfo, PositionInfo, int)} instead.
|
||
|
*/
|
||
|
@Deprecated
|
||
|
default void onPositionDiscontinuity(@DiscontinuityReason int reason) {}
|
||
|
|
||
|
/**
|
||
|
* Called when a position discontinuity occurs.
|
||
|
*
|
||
|
* <p>A position discontinuity occurs when the playing period changes, the playback position
|
||
|
* jumps within the period currently being played, or when the playing period has been skipped
|
||
|
* or removed.
|
||
|
*
|
||
|
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||
|
* other events that happen in the same {@link Looper} message queue iteration.
|
||
|
*
|
||
|
* @param oldPosition The position before the discontinuity.
|
||
|
* @param newPosition The position after the discontinuity.
|
||
|
* @param reason The {@link DiscontinuityReason} responsible for the discontinuity.
|
||
|
*/
|
||
|
default void onPositionDiscontinuity(
|
||
|
PositionInfo oldPosition, PositionInfo newPosition, @DiscontinuityReason int reason) {}
|
||
|
|
||
|
/**
|
||
|
* Called when the current playback parameters change. The playback parameters may change due to
|
||
|
* a call to {@link #setPlaybackParameters(PlaybackParameters)}, or the player itself may change
|
||
|
* them (for example, if audio playback switches to passthrough or offload mode, where speed
|
||
|
* adjustment is no longer possible).
|
||
|
*
|
||
|
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||
|
* other events that happen in the same {@link Looper} message queue iteration.
|
||
|
*
|
||
|
* @param playbackParameters The playback parameters.
|
||
|
*/
|
||
|
default void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {}
|
||
|
|
||
|
/**
|
||
|
* Called when the value of {@link #getSeekBackIncrement()} changes.
|
||
|
*
|
||
|
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||
|
* other events that happen in the same {@link Looper} message queue iteration.
|
||
|
*
|
||
|
* @param seekBackIncrementMs The {@link #seekBack()} increment, in milliseconds.
|
||
|
*/
|
||
|
default void onSeekBackIncrementChanged(long seekBackIncrementMs) {}
|
||
|
|
||
|
/**
|
||
|
* Called when the value of {@link #getSeekForwardIncrement()} changes.
|
||
|
*
|
||
|
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||
|
* other events that happen in the same {@link Looper} message queue iteration.
|
||
|
*
|
||
|
* @param seekForwardIncrementMs The {@link #seekForward()} increment, in milliseconds.
|
||
|
*/
|
||
|
default void onSeekForwardIncrementChanged(long seekForwardIncrementMs) {}
|
||
|
|
||
|
/**
|
||
|
* Called when the value of {@link #getMaxSeekToPreviousPosition()} changes.
|
||
|
*
|
||
|
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||
|
* other events that happen in the same {@link Looper} message queue iteration.
|
||
|
*
|
||
|
* @param maxSeekToPreviousPositionMs The maximum position for which {@link #seekToPrevious()}
|
||
|
* seeks to the previous position, in milliseconds.
|
||
|
*/
|
||
|
default void onMaxSeekToPreviousPositionChanged(long maxSeekToPreviousPositionMs) {}
|
||
|
|
||
|
/**
|
||
|
* @deprecated Seeks are processed without delay. Listen to {@link
|
||
|
* #onPositionDiscontinuity(PositionInfo, PositionInfo, int)} with reason {@link
|
||
|
* #DISCONTINUITY_REASON_SEEK} instead.
|
||
|
*/
|
||
|
@Deprecated
|
||
|
default void onSeekProcessed() {}
|
||
|
|
||
|
/**
|
||
|
* Called when one or more player states changed.
|
||
|
*
|
||
|
* <p>State changes and events that happen within one {@link Looper} message queue iteration are
|
||
|
* reported together and only after all individual callbacks were triggered.
|
||
|
*
|
||
|
* <p>Only state changes represented by {@link Event events} are reported through this method.
|
||
|
*
|
||
|
* <p>Listeners should prefer this method over individual callbacks in the following cases:
|
||
|
*
|
||
|
* <ul>
|
||
|
* <li>They intend to trigger the same logic for multiple events (e.g. when updating a UI for
|
||
|
* both {@link #onPlaybackStateChanged(int)} and {@link #onPlayWhenReadyChanged(boolean,
|
||
|
* int)}).
|
||
|
* <li>They need access to the {@link Player} object to trigger further events (e.g. to call
|
||
|
* {@link Player#seekTo(long)} after a {@link #onMediaItemTransition(MediaItem, int)}).
|
||
|
* <li>They intend to use multiple state values together or in combination with {@link Player}
|
||
|
* getter methods. For example using {@link #getCurrentMediaItemIndex()} with the {@code
|
||
|
* timeline} provided in {@link #onTimelineChanged(Timeline, int)} is only safe from
|
||
|
* within this method.
|
||
|
* <li>They are interested in events that logically happened together (e.g {@link
|
||
|
* #onPlaybackStateChanged(int)} to {@link #STATE_BUFFERING} because of {@link
|
||
|
* #onMediaItemTransition(MediaItem, int)}).
|
||
|
* </ul>
|
||
|
*
|
||
|
* @param player The {@link Player} whose state changed. Use the getters to obtain the latest
|
||
|
* states.
|
||
|
* @param events The {@link Events} that happened in this iteration, indicating which player
|
||
|
* states changed.
|
||
|
*/
|
||
|
default void onEvents(Player player, Events events) {}
|
||
|
}
|
||
|
|
||
|
/** A set of {@link Event events}. */
|
||
|
final class Events {
|
||
|
|
||
|
private final FlagSet flags;
|
||
|
|
||
|
/**
|
||
|
* Creates an instance.
|
||
|
*
|
||
|
* @param flags The {@link FlagSet} containing the {@link Event events}.
|
||
|
*/
|
||
|
public Events(FlagSet flags) {
|
||
|
this.flags = flags;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns whether the given {@link Event} occurred.
|
||
|
*
|
||
|
* @param event The {@link Event}.
|
||
|
* @return Whether the {@link Event} occurred.
|
||
|
*/
|
||
|
public boolean contains(@Event int event) {
|
||
|
return flags.contains(event);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns whether any of the given {@link Event events} occurred.
|
||
|
*
|
||
|
* @param events The {@link Event events}.
|
||
|
* @return Whether any of the {@link Event events} occurred.
|
||
|
*/
|
||
|
public boolean containsAny(@Event int... events) {
|
||
|
return flags.containsAny(events);
|
||
|
}
|
||
|
|
||
|
/** Returns the number of events in the set. */
|
||
|
public int size() {
|
||
|
return flags.size();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the {@link Event} at the given index.
|
||
|
*
|
||
|
* <p>Although index-based access is possible, it doesn't imply a particular order of these
|
||
|
* events.
|
||
|
*
|
||
|
* @param index The index. Must be between 0 (inclusive) and {@link #size()} (exclusive).
|
||
|
* @return The {@link Event} at the given index.
|
||
|
* @throws IndexOutOfBoundsException If index is outside the allowed range.
|
||
|
*/
|
||
|
public @Event int get(int index) {
|
||
|
return flags.get(index);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public int hashCode() {
|
||
|
return flags.hashCode();
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean equals(@Nullable Object obj) {
|
||
|
if (this == obj) {
|
||
|
return true;
|
||
|
}
|
||
|
if (!(obj instanceof Events)) {
|
||
|
return false;
|
||
|
}
|
||
|
Events other = (Events) obj;
|
||
|
return flags.equals(other.flags);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/** Position info describing a playback position involved in a discontinuity. */
|
||
|
final class PositionInfo implements Bundleable {
|
||
|
|
||
|
/**
|
||
|
* The UID of the window, or {@code null} if the timeline is {@link Timeline#isEmpty() empty}.
|
||
|
*/
|
||
|
@Nullable public final Object windowUid;
|
||
|
/** @deprecated Use {@link #mediaItemIndex} instead. */
|
||
|
@Deprecated public final int windowIndex;
|
||
|
/** The media item index. */
|
||
|
public final int mediaItemIndex;
|
||
|
/** The media item, or {@code null} if the timeline is {@link Timeline#isEmpty() empty}. */
|
||
|
@Nullable public final MediaItem mediaItem;
|
||
|
/**
|
||
|
* The UID of the period, or {@code null} if the timeline is {@link Timeline#isEmpty() empty}.
|
||
|
*/
|
||
|
@Nullable public final Object periodUid;
|
||
|
/** The period index. */
|
||
|
public final int periodIndex;
|
||
|
/** The playback position, in milliseconds. */
|
||
|
public final long positionMs;
|
||
|
/**
|
||
|
* The content position, in milliseconds.
|
||
|
*
|
||
|
* <p>If {@link #adGroupIndex} is {@link C#INDEX_UNSET}, this is the same as {@link
|
||
|
* #positionMs}.
|
||
|
*/
|
||
|
public final long contentPositionMs;
|
||
|
/**
|
||
|
* The ad group index if the playback position is within an ad, {@link C#INDEX_UNSET} otherwise.
|
||
|
*/
|
||
|
public final int adGroupIndex;
|
||
|
/**
|
||
|
* The index of the ad within the ad group if the playback position is within an ad, {@link
|
||
|
* C#INDEX_UNSET} otherwise.
|
||
|
*/
|
||
|
public final int adIndexInAdGroup;
|
||
|
|
||
|
/**
|
||
|
* @deprecated Use {@link #PositionInfo(Object, int, MediaItem, Object, int, long, long, int,
|
||
|
* int)} instead.
|
||
|
*/
|
||
|
@Deprecated
|
||
|
public PositionInfo(
|
||
|
@Nullable Object windowUid,
|
||
|
int mediaItemIndex,
|
||
|
@Nullable Object periodUid,
|
||
|
int periodIndex,
|
||
|
long positionMs,
|
||
|
long contentPositionMs,
|
||
|
int adGroupIndex,
|
||
|
int adIndexInAdGroup) {
|
||
|
this(
|
||
|
windowUid,
|
||
|
mediaItemIndex,
|
||
|
MediaItem.EMPTY,
|
||
|
periodUid,
|
||
|
periodIndex,
|
||
|
positionMs,
|
||
|
contentPositionMs,
|
||
|
adGroupIndex,
|
||
|
adIndexInAdGroup);
|
||
|
}
|
||
|
|
||
|
/** Creates an instance. */
|
||
|
public PositionInfo(
|
||
|
@Nullable Object windowUid,
|
||
|
int mediaItemIndex,
|
||
|
@Nullable MediaItem mediaItem,
|
||
|
@Nullable Object periodUid,
|
||
|
int periodIndex,
|
||
|
long positionMs,
|
||
|
long contentPositionMs,
|
||
|
int adGroupIndex,
|
||
|
int adIndexInAdGroup) {
|
||
|
this.windowUid = windowUid;
|
||
|
this.windowIndex = mediaItemIndex;
|
||
|
this.mediaItemIndex = mediaItemIndex;
|
||
|
this.mediaItem = mediaItem;
|
||
|
this.periodUid = periodUid;
|
||
|
this.periodIndex = periodIndex;
|
||
|
this.positionMs = positionMs;
|
||
|
this.contentPositionMs = contentPositionMs;
|
||
|
this.adGroupIndex = adGroupIndex;
|
||
|
this.adIndexInAdGroup = adIndexInAdGroup;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean equals(@Nullable Object o) {
|
||
|
if (this == o) {
|
||
|
return true;
|
||
|
}
|
||
|
if (o == null || getClass() != o.getClass()) {
|
||
|
return false;
|
||
|
}
|
||
|
PositionInfo that = (PositionInfo) o;
|
||
|
return mediaItemIndex == that.mediaItemIndex
|
||
|
&& periodIndex == that.periodIndex
|
||
|
&& positionMs == that.positionMs
|
||
|
&& contentPositionMs == that.contentPositionMs
|
||
|
&& adGroupIndex == that.adGroupIndex
|
||
|
&& adIndexInAdGroup == that.adIndexInAdGroup
|
||
|
&& Objects.equal(windowUid, that.windowUid)
|
||
|
&& Objects.equal(periodUid, that.periodUid)
|
||
|
&& Objects.equal(mediaItem, that.mediaItem);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public int hashCode() {
|
||
|
return Objects.hashCode(
|
||
|
windowUid,
|
||
|
mediaItemIndex,
|
||
|
mediaItem,
|
||
|
periodUid,
|
||
|
periodIndex,
|
||
|
positionMs,
|
||
|
contentPositionMs,
|
||
|
adGroupIndex,
|
||
|
adIndexInAdGroup);
|
||
|
}
|
||
|
|
||
|
// Bundleable implementation.
|
||
|
@Documented
|
||
|
@Retention(RetentionPolicy.SOURCE)
|
||
|
@IntDef({
|
||
|
FIELD_MEDIA_ITEM_INDEX,
|
||
|
FIELD_MEDIA_ITEM,
|
||
|
FIELD_PERIOD_INDEX,
|
||
|
FIELD_POSITION_MS,
|
||
|
FIELD_CONTENT_POSITION_MS,
|
||
|
FIELD_AD_GROUP_INDEX,
|
||
|
FIELD_AD_INDEX_IN_AD_GROUP
|
||
|
})
|
||
|
private @interface FieldNumber {}
|
||
|
|
||
|
private static final int FIELD_MEDIA_ITEM_INDEX = 0;
|
||
|
private static final int FIELD_MEDIA_ITEM = 1;
|
||
|
private static final int FIELD_PERIOD_INDEX = 2;
|
||
|
private static final int FIELD_POSITION_MS = 3;
|
||
|
private static final int FIELD_CONTENT_POSITION_MS = 4;
|
||
|
private static final int FIELD_AD_GROUP_INDEX = 5;
|
||
|
private static final int FIELD_AD_INDEX_IN_AD_GROUP = 6;
|
||
|
|
||
|
/**
|
||
|
* {@inheritDoc}
|
||
|
*
|
||
|
* <p>It omits the {@link #windowUid} and {@link #periodUid} fields. The {@link #windowUid} and
|
||
|
* {@link #periodUid} of an instance restored by {@link #CREATOR} will always be {@code null}.
|
||
|
*/
|
||
|
@Override
|
||
|
public Bundle toBundle() {
|
||
|
Bundle bundle = new Bundle();
|
||
|
bundle.putInt(keyForField(FIELD_MEDIA_ITEM_INDEX), mediaItemIndex);
|
||
|
bundle.putBundle(keyForField(FIELD_MEDIA_ITEM), BundleableUtil.toNullableBundle(mediaItem));
|
||
|
bundle.putInt(keyForField(FIELD_PERIOD_INDEX), periodIndex);
|
||
|
bundle.putLong(keyForField(FIELD_POSITION_MS), positionMs);
|
||
|
bundle.putLong(keyForField(FIELD_CONTENT_POSITION_MS), contentPositionMs);
|
||
|
bundle.putInt(keyForField(FIELD_AD_GROUP_INDEX), adGroupIndex);
|
||
|
bundle.putInt(keyForField(FIELD_AD_INDEX_IN_AD_GROUP), adIndexInAdGroup);
|
||
|
return bundle;
|
||
|
}
|
||
|
|
||
|
/** Object that can restore {@link PositionInfo} from a {@link Bundle}. */
|
||
|
public static final Creator<PositionInfo> CREATOR = PositionInfo::fromBundle;
|
||
|
|
||
|
private static PositionInfo fromBundle(Bundle bundle) {
|
||
|
int mediaItemIndex =
|
||
|
bundle.getInt(keyForField(FIELD_MEDIA_ITEM_INDEX), /* defaultValue= */ C.INDEX_UNSET);
|
||
|
@Nullable
|
||
|
MediaItem mediaItem =
|
||
|
BundleableUtil.fromNullableBundle(
|
||
|
MediaItem.CREATOR, bundle.getBundle(keyForField(FIELD_MEDIA_ITEM)));
|
||
|
int periodIndex =
|
||
|
bundle.getInt(keyForField(FIELD_PERIOD_INDEX), /* defaultValue= */ C.INDEX_UNSET);
|
||
|
long positionMs =
|
||
|
bundle.getLong(keyForField(FIELD_POSITION_MS), /* defaultValue= */ C.TIME_UNSET);
|
||
|
long contentPositionMs =
|
||
|
bundle.getLong(keyForField(FIELD_CONTENT_POSITION_MS), /* defaultValue= */ C.TIME_UNSET);
|
||
|
int adGroupIndex =
|
||
|
bundle.getInt(keyForField(FIELD_AD_GROUP_INDEX), /* defaultValue= */ C.INDEX_UNSET);
|
||
|
int adIndexInAdGroup =
|
||
|
bundle.getInt(keyForField(FIELD_AD_INDEX_IN_AD_GROUP), /* defaultValue= */ C.INDEX_UNSET);
|
||
|
return new PositionInfo(
|
||
|
/* windowUid= */ null,
|
||
|
mediaItemIndex,
|
||
|
mediaItem,
|
||
|
/* periodUid= */ null,
|
||
|
periodIndex,
|
||
|
positionMs,
|
||
|
contentPositionMs,
|
||
|
adGroupIndex,
|
||
|
adIndexInAdGroup);
|
||
|
}
|
||
|
|
||
|
private static String keyForField(@FieldNumber int field) {
|
||
|
return Integer.toString(field, Character.MAX_RADIX);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* A set of {@link Command commands}.
|
||
|
*
|
||
|
* <p>Instances are immutable.
|
||
|
*/
|
||
|
final class Commands implements Bundleable {
|
||
|
|
||
|
/** A builder for {@link Commands} instances. */
|
||
|
public static final class Builder {
|
||
|
|
||
|
@Command
|
||
|
private static final int[] SUPPORTED_COMMANDS = {
|
||
|
COMMAND_PLAY_PAUSE,
|
||
|
COMMAND_PREPARE,
|
||
|
COMMAND_STOP,
|
||
|
COMMAND_SEEK_TO_DEFAULT_POSITION,
|
||
|
COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM,
|
||
|
COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM,
|
||
|
COMMAND_SEEK_TO_PREVIOUS,
|
||
|
COMMAND_SEEK_TO_NEXT_MEDIA_ITEM,
|
||
|
COMMAND_SEEK_TO_NEXT,
|
||
|
COMMAND_SEEK_TO_MEDIA_ITEM,
|
||
|
COMMAND_SEEK_BACK,
|
||
|
COMMAND_SEEK_FORWARD,
|
||
|
COMMAND_SET_SPEED_AND_PITCH,
|
||
|
COMMAND_SET_SHUFFLE_MODE,
|
||
|
COMMAND_SET_REPEAT_MODE,
|
||
|
COMMAND_GET_CURRENT_MEDIA_ITEM,
|
||
|
COMMAND_GET_TIMELINE,
|
||
|
COMMAND_GET_MEDIA_ITEMS_METADATA,
|
||
|
COMMAND_SET_MEDIA_ITEMS_METADATA,
|
||
|
COMMAND_CHANGE_MEDIA_ITEMS,
|
||
|
COMMAND_GET_AUDIO_ATTRIBUTES,
|
||
|
COMMAND_GET_VOLUME,
|
||
|
COMMAND_GET_DEVICE_VOLUME,
|
||
|
COMMAND_SET_VOLUME,
|
||
|
COMMAND_SET_DEVICE_VOLUME,
|
||
|
COMMAND_ADJUST_DEVICE_VOLUME,
|
||
|
COMMAND_SET_VIDEO_SURFACE,
|
||
|
COMMAND_GET_TEXT,
|
||
|
COMMAND_SET_TRACK_SELECTION_PARAMETERS,
|
||
|
COMMAND_GET_TRACK_INFOS,
|
||
|
};
|
||
|
|
||
|
private final FlagSet.Builder flagsBuilder;
|
||
|
|
||
|
/** Creates a builder. */
|
||
|
public Builder() {
|
||
|
flagsBuilder = new FlagSet.Builder();
|
||
|
}
|
||
|
|
||
|
private Builder(Commands commands) {
|
||
|
flagsBuilder = new FlagSet.Builder();
|
||
|
flagsBuilder.addAll(commands.flags);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Adds a {@link Command}.
|
||
|
*
|
||
|
* @param command A {@link Command}.
|
||
|
* @return This builder.
|
||
|
* @throws IllegalStateException If {@link #build()} has already been called.
|
||
|
*/
|
||
|
public Builder add(@Command int command) {
|
||
|
flagsBuilder.add(command);
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Adds a {@link Command} if the provided condition is true. Does nothing otherwise.
|
||
|
*
|
||
|
* @param command A {@link Command}.
|
||
|
* @param condition A condition.
|
||
|
* @return This builder.
|
||
|
* @throws IllegalStateException If {@link #build()} has already been called.
|
||
|
*/
|
||
|
public Builder addIf(@Command int command, boolean condition) {
|
||
|
flagsBuilder.addIf(command, condition);
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Adds {@link Command commands}.
|
||
|
*
|
||
|
* @param commands The {@link Command commands} to add.
|
||
|
* @return This builder.
|
||
|
* @throws IllegalStateException If {@link #build()} has already been called.
|
||
|
*/
|
||
|
public Builder addAll(@Command int... commands) {
|
||
|
flagsBuilder.addAll(commands);
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Adds {@link Commands}.
|
||
|
*
|
||
|
* @param commands The set of {@link Command commands} to add.
|
||
|
* @return This builder.
|
||
|
* @throws IllegalStateException If {@link #build()} has already been called.
|
||
|
*/
|
||
|
public Builder addAll(Commands commands) {
|
||
|
flagsBuilder.addAll(commands.flags);
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Adds all existing {@link Command commands}.
|
||
|
*
|
||
|
* @return This builder.
|
||
|
* @throws IllegalStateException If {@link #build()} has already been called.
|
||
|
*/
|
||
|
public Builder addAllCommands() {
|
||
|
flagsBuilder.addAll(SUPPORTED_COMMANDS);
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Removes a {@link Command}.
|
||
|
*
|
||
|
* @param command A {@link Command}.
|
||
|
* @return This builder.
|
||
|
* @throws IllegalStateException If {@link #build()} has already been called.
|
||
|
*/
|
||
|
public Builder remove(@Command int command) {
|
||
|
flagsBuilder.remove(command);
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Removes a {@link Command} if the provided condition is true. Does nothing otherwise.
|
||
|
*
|
||
|
* @param command A {@link Command}.
|
||
|
* @param condition A condition.
|
||
|
* @return This builder.
|
||
|
* @throws IllegalStateException If {@link #build()} has already been called.
|
||
|
*/
|
||
|
public Builder removeIf(@Command int command, boolean condition) {
|
||
|
flagsBuilder.removeIf(command, condition);
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Removes {@link Command commands}.
|
||
|
*
|
||
|
* @param commands The {@link Command commands} to remove.
|
||
|
* @return This builder.
|
||
|
* @throws IllegalStateException If {@link #build()} has already been called.
|
||
|
*/
|
||
|
public Builder removeAll(@Command int... commands) {
|
||
|
flagsBuilder.removeAll(commands);
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Builds a {@link Commands} instance.
|
||
|
*
|
||
|
* @throws IllegalStateException If this method has already been called.
|
||
|
*/
|
||
|
public Commands build() {
|
||
|
return new Commands(flagsBuilder.build());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/** An empty set of commands. */
|
||
|
public static final Commands EMPTY = new Builder().build();
|
||
|
|
||
|
private final FlagSet flags;
|
||
|
|
||
|
private Commands(FlagSet flags) {
|
||
|
this.flags = flags;
|
||
|
}
|
||
|
|
||
|
/** Returns a {@link Builder} initialized with the values of this instance. */
|
||
|
public Builder buildUpon() {
|
||
|
return new Builder(this);
|
||
|
}
|
||
|
|
||
|
/** Returns whether the set of commands contains the specified {@link Command}. */
|
||
|
public boolean contains(@Command int command) {
|
||
|
return flags.contains(command);
|
||
|
}
|
||
|
|
||
|
/** Returns the number of commands in this set. */
|
||
|
public int size() {
|
||
|
return flags.size();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the {@link Command} at the given index.
|
||
|
*
|
||
|
* @param index The index. Must be between 0 (inclusive) and {@link #size()} (exclusive).
|
||
|
* @return The {@link Command} at the given index.
|
||
|
* @throws IndexOutOfBoundsException If index is outside the allowed range.
|
||
|
*/
|
||
|
public @Command int get(int index) {
|
||
|
return flags.get(index);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean equals(@Nullable Object obj) {
|
||
|
if (this == obj) {
|
||
|
return true;
|
||
|
}
|
||
|
if (!(obj instanceof Commands)) {
|
||
|
return false;
|
||
|
}
|
||
|
Commands commands = (Commands) obj;
|
||
|
return flags.equals(commands.flags);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public int hashCode() {
|
||
|
return flags.hashCode();
|
||
|
}
|
||
|
|
||
|
// Bundleable implementation.
|
||
|
|
||
|
@Documented
|
||
|
@Retention(RetentionPolicy.SOURCE)
|
||
|
@IntDef({FIELD_COMMANDS})
|
||
|
private @interface FieldNumber {}
|
||
|
|
||
|
private static final int FIELD_COMMANDS = 0;
|
||
|
|
||
|
@Override
|
||
|
public Bundle toBundle() {
|
||
|
Bundle bundle = new Bundle();
|
||
|
ArrayList<Integer> commandsBundle = new ArrayList<>();
|
||
|
for (int i = 0; i < flags.size(); i++) {
|
||
|
commandsBundle.add(flags.get(i));
|
||
|
}
|
||
|
bundle.putIntegerArrayList(keyForField(FIELD_COMMANDS), commandsBundle);
|
||
|
return bundle;
|
||
|
}
|
||
|
|
||
|
/** Object that can restore {@link Commands} from a {@link Bundle}. */
|
||
|
public static final Creator<Commands> CREATOR = Commands::fromBundle;
|
||
|
|
||
|
private static Commands fromBundle(Bundle bundle) {
|
||
|
@Nullable
|
||
|
ArrayList<Integer> commands = bundle.getIntegerArrayList(keyForField(FIELD_COMMANDS));
|
||
|
if (commands == null) {
|
||
|
return Commands.EMPTY;
|
||
|
}
|
||
|
Builder builder = new Builder();
|
||
|
for (int i = 0; i < commands.size(); i++) {
|
||
|
builder.add(commands.get(i));
|
||
|
}
|
||
|
return builder.build();
|
||
|
}
|
||
|
|
||
|
private static String keyForField(@FieldNumber int field) {
|
||
|
return Integer.toString(field, Character.MAX_RADIX);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Listener of all changes in the Player.
|
||
|
*
|
||
|
* <p>All methods have no-op default implementations to allow selective overrides.
|
||
|
*/
|
||
|
interface Listener extends EventListener {
|
||
|
|
||
|
@Override
|
||
|
default void onTimelineChanged(Timeline timeline, @TimelineChangeReason int reason) {}
|
||
|
|
||
|
@Override
|
||
|
default void onMediaItemTransition(
|
||
|
@Nullable MediaItem mediaItem, @MediaItemTransitionReason int reason) {}
|
||
|
|
||
|
@Override
|
||
|
default void onTracksInfoChanged(TracksInfo tracksInfo) {}
|
||
|
|
||
|
@Override
|
||
|
default void onIsLoadingChanged(boolean isLoading) {}
|
||
|
|
||
|
@Override
|
||
|
default void onAvailableCommandsChanged(Commands availableCommands) {}
|
||
|
|
||
|
@Override
|
||
|
default void onPlaybackStateChanged(@State int playbackState) {}
|
||
|
|
||
|
@Override
|
||
|
default void onPlayWhenReadyChanged(
|
||
|
boolean playWhenReady, @PlayWhenReadyChangeReason int reason) {}
|
||
|
|
||
|
@Override
|
||
|
default void onPlaybackSuppressionReasonChanged(
|
||
|
@PlaybackSuppressionReason int playbackSuppressionReason) {}
|
||
|
|
||
|
@Override
|
||
|
default void onIsPlayingChanged(boolean isPlaying) {}
|
||
|
|
||
|
@Override
|
||
|
default void onRepeatModeChanged(@RepeatMode int repeatMode) {}
|
||
|
|
||
|
@Override
|
||
|
default void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {}
|
||
|
|
||
|
@Override
|
||
|
default void onPlayerError(PlaybackException error) {}
|
||
|
|
||
|
@Override
|
||
|
default void onPlayerErrorChanged(@Nullable PlaybackException error) {}
|
||
|
|
||
|
@Override
|
||
|
default void onPositionDiscontinuity(
|
||
|
PositionInfo oldPosition, PositionInfo newPosition, @DiscontinuityReason int reason) {}
|
||
|
|
||
|
@Override
|
||
|
default void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {}
|
||
|
|
||
|
@Override
|
||
|
default void onSeekForwardIncrementChanged(long seekForwardIncrementMs) {}
|
||
|
|
||
|
@Override
|
||
|
default void onSeekBackIncrementChanged(long seekBackIncrementMs) {}
|
||
|
|
||
|
/**
|
||
|
* Called when the audio session ID changes.
|
||
|
*
|
||
|
* @param audioSessionId The audio session ID.
|
||
|
*/
|
||
|
default void onAudioSessionIdChanged(int audioSessionId) {}
|
||
|
|
||
|
/**
|
||
|
* Called when the audio attributes change.
|
||
|
*
|
||
|
* @param audioAttributes The audio attributes.
|
||
|
*/
|
||
|
default void onAudioAttributesChanged(AudioAttributes audioAttributes) {}
|
||
|
|
||
|
/**
|
||
|
* Called when the volume changes.
|
||
|
*
|
||
|
* @param volume The new volume, with 0 being silence and 1 being unity gain.
|
||
|
*/
|
||
|
default void onVolumeChanged(float volume) {}
|
||
|
|
||
|
/**
|
||
|
* Called when skipping silences is enabled or disabled in the audio stream.
|
||
|
*
|
||
|
* @param skipSilenceEnabled Whether skipping silences in the audio stream is enabled.
|
||
|
*/
|
||
|
default void onSkipSilenceEnabledChanged(boolean skipSilenceEnabled) {}
|
||
|
|
||
|
/** Called when the device information changes. */
|
||
|
default void onDeviceInfoChanged(DeviceInfo deviceInfo) {}
|
||
|
|
||
|
/** Called when the device volume or mute state changes. */
|
||
|
default void onDeviceVolumeChanged(int volume, boolean muted) {}
|
||
|
|
||
|
@Override
|
||
|
default void onEvents(Player player, Events events) {}
|
||
|
|
||
|
/**
|
||
|
* Called each time there's a change in the size of the video being rendered.
|
||
|
*
|
||
|
* @param videoSize The new size of the video.
|
||
|
*/
|
||
|
default void onVideoSizeChanged(VideoSize videoSize) {}
|
||
|
|
||
|
/**
|
||
|
* Called each time there's a change in the size of the surface onto which the video is being
|
||
|
* rendered.
|
||
|
*
|
||
|
* @param width The surface width in pixels. May be {@link C#LENGTH_UNSET} if unknown, or 0 if
|
||
|
* the video is not rendered onto a surface.
|
||
|
* @param height The surface height in pixels. May be {@link C#LENGTH_UNSET} if unknown, or 0 if
|
||
|
* the video is not rendered onto a surface.
|
||
|
*/
|
||
|
default void onSurfaceSizeChanged(int width, int height) {}
|
||
|
|
||
|
/**
|
||
|
* Called when a frame is rendered for the first time since setting the surface, or since the
|
||
|
* renderer was reset, or since the stream being rendered was changed.
|
||
|
*/
|
||
|
default void onRenderedFirstFrame() {}
|
||
|
|
||
|
/**
|
||
|
* Called when there is a change in the {@link Cue Cues}.
|
||
|
*
|
||
|
* <p>{@code cues} is in ascending order of priority. If any of the cue boxes overlap when
|
||
|
* displayed, the {@link Cue} nearer the end of the list should be shown on top.
|
||
|
*
|
||
|
* @param cues The {@link Cue Cues}. May be empty.
|
||
|
*/
|
||
|
default void onCues(List<Cue> cues) {}
|
||
|
|
||
|
/**
|
||
|
* Called when there is metadata associated with the current playback time.
|
||
|
*
|
||
|
* @param metadata The metadata.
|
||
|
*/
|
||
|
default void onMetadata(Metadata metadata) {}
|
||
|
|
||
|
@Override
|
||
|
default void onMediaMetadataChanged(MediaMetadata mediaMetadata) {}
|
||
|
|
||
|
@Override
|
||
|
default void onPlaylistMetadataChanged(MediaMetadata mediaMetadata) {}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Playback state. One of {@link #STATE_IDLE}, {@link #STATE_BUFFERING}, {@link #STATE_READY} or
|
||
|
* {@link #STATE_ENDED}.
|
||
|
*/
|
||
|
@Documented
|
||
|
@Retention(RetentionPolicy.SOURCE)
|
||
|
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE, TYPE_USE})
|
||
|
@IntDef({STATE_IDLE, STATE_BUFFERING, STATE_READY, STATE_ENDED})
|
||
|
@interface State {}
|
||
|
/**
|
||
|
* The player is idle, meaning it holds only limited resources. The player must be {@link
|
||
|
* #prepare() prepared} before it will play the media.
|
||
|
*/
|
||
|
int STATE_IDLE = 1;
|
||
|
/**
|
||
|
* The player is not able to immediately play the media, but is doing work toward being able to do
|
||
|
* so. This state typically occurs when the player needs to buffer more data before playback can
|
||
|
* start.
|
||
|
*/
|
||
|
int STATE_BUFFERING = 2;
|
||
|
/**
|
||
|
* The player is able to immediately play from its current position. The player will be playing if
|
||
|
* {@link #getPlayWhenReady()} is true, and paused otherwise.
|
||
|
*/
|
||
|
int STATE_READY = 3;
|
||
|
/** The player has finished playing the media. */
|
||
|
int STATE_ENDED = 4;
|
||
|
|
||
|
/**
|
||
|
* Reasons for {@link #getPlayWhenReady() playWhenReady} changes. One of {@link
|
||
|
* #PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST}, {@link
|
||
|
* #PLAY_WHEN_READY_CHANGE_REASON_AUDIO_FOCUS_LOSS}, {@link
|
||
|
* #PLAY_WHEN_READY_CHANGE_REASON_AUDIO_BECOMING_NOISY}, {@link
|
||
|
* #PLAY_WHEN_READY_CHANGE_REASON_REMOTE} or {@link
|
||
|
* #PLAY_WHEN_READY_CHANGE_REASON_END_OF_MEDIA_ITEM}.
|
||
|
*/
|
||
|
@Documented
|
||
|
@Retention(RetentionPolicy.SOURCE)
|
||
|
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE, TYPE_USE})
|
||
|
@IntDef({
|
||
|
PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST,
|
||
|
PLAY_WHEN_READY_CHANGE_REASON_AUDIO_FOCUS_LOSS,
|
||
|
PLAY_WHEN_READY_CHANGE_REASON_AUDIO_BECOMING_NOISY,
|
||
|
PLAY_WHEN_READY_CHANGE_REASON_REMOTE,
|
||
|
PLAY_WHEN_READY_CHANGE_REASON_END_OF_MEDIA_ITEM
|
||
|
})
|
||
|
@interface PlayWhenReadyChangeReason {}
|
||
|
/** Playback has been started or paused by a call to {@link #setPlayWhenReady(boolean)}. */
|
||
|
int PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST = 1;
|
||
|
/** Playback has been paused because of a loss of audio focus. */
|
||
|
int PLAY_WHEN_READY_CHANGE_REASON_AUDIO_FOCUS_LOSS = 2;
|
||
|
/** Playback has been paused to avoid becoming noisy. */
|
||
|
int PLAY_WHEN_READY_CHANGE_REASON_AUDIO_BECOMING_NOISY = 3;
|
||
|
/** Playback has been started or paused because of a remote change. */
|
||
|
int PLAY_WHEN_READY_CHANGE_REASON_REMOTE = 4;
|
||
|
/** Playback has been paused at the end of a media item. */
|
||
|
int PLAY_WHEN_READY_CHANGE_REASON_END_OF_MEDIA_ITEM = 5;
|
||
|
|
||
|
/**
|
||
|
* Reason why playback is suppressed even though {@link #getPlayWhenReady()} is {@code true}. One
|
||
|
* of {@link #PLAYBACK_SUPPRESSION_REASON_NONE} or {@link
|
||
|
* #PLAYBACK_SUPPRESSION_REASON_TRANSIENT_AUDIO_FOCUS_LOSS}.
|
||
|
*/
|
||
|
@Documented
|
||
|
@Retention(RetentionPolicy.SOURCE)
|
||
|
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE, TYPE_USE})
|
||
|
@IntDef({
|
||
|
PLAYBACK_SUPPRESSION_REASON_NONE,
|
||
|
PLAYBACK_SUPPRESSION_REASON_TRANSIENT_AUDIO_FOCUS_LOSS
|
||
|
})
|
||
|
@interface PlaybackSuppressionReason {}
|
||
|
/** Playback is not suppressed. */
|
||
|
int PLAYBACK_SUPPRESSION_REASON_NONE = 0;
|
||
|
/** Playback is suppressed due to transient audio focus loss. */
|
||
|
int PLAYBACK_SUPPRESSION_REASON_TRANSIENT_AUDIO_FOCUS_LOSS = 1;
|
||
|
|
||
|
/**
|
||
|
* Repeat modes for playback. One of {@link #REPEAT_MODE_OFF}, {@link #REPEAT_MODE_ONE} or {@link
|
||
|
* #REPEAT_MODE_ALL}.
|
||
|
*/
|
||
|
@Documented
|
||
|
@Retention(RetentionPolicy.SOURCE)
|
||
|
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE, TYPE_USE})
|
||
|
@IntDef({REPEAT_MODE_OFF, REPEAT_MODE_ONE, REPEAT_MODE_ALL})
|
||
|
@interface RepeatMode {}
|
||
|
/**
|
||
|
* Normal playback without repetition. "Previous" and "Next" actions move to the previous and next
|
||
|
* {@link MediaItem} respectively, and do nothing when there is no previous or next {@link
|
||
|
* MediaItem} to move to.
|
||
|
*/
|
||
|
int REPEAT_MODE_OFF = 0;
|
||
|
/**
|
||
|
* Repeats the currently playing {@link MediaItem} infinitely during ongoing playback. "Previous"
|
||
|
* and "Next" actions behave as they do in {@link #REPEAT_MODE_OFF}, moving to the previous and
|
||
|
* next {@link MediaItem} respectively, and doing nothing when there is no previous or next {@link
|
||
|
* MediaItem} to move to.
|
||
|
*/
|
||
|
int REPEAT_MODE_ONE = 1;
|
||
|
/**
|
||
|
* Repeats the entire timeline infinitely. "Previous" and "Next" actions behave as they do in
|
||
|
* {@link #REPEAT_MODE_OFF}, but with looping at the ends so that "Previous" when playing the
|
||
|
* first {@link MediaItem} will move to the last {@link MediaItem}, and "Next" when playing the
|
||
|
* last {@link MediaItem} will move to the first {@link MediaItem}.
|
||
|
*/
|
||
|
int REPEAT_MODE_ALL = 2;
|
||
|
|
||
|
/**
|
||
|
* Reasons for position discontinuities. One of {@link #DISCONTINUITY_REASON_AUTO_TRANSITION},
|
||
|
* {@link #DISCONTINUITY_REASON_SEEK}, {@link #DISCONTINUITY_REASON_SEEK_ADJUSTMENT}, {@link
|
||
|
* #DISCONTINUITY_REASON_SKIP}, {@link #DISCONTINUITY_REASON_REMOVE} or {@link
|
||
|
* #DISCONTINUITY_REASON_INTERNAL}.
|
||
|
*/
|
||
|
@Documented
|
||
|
@Retention(RetentionPolicy.SOURCE)
|
||
|
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE, TYPE_USE})
|
||
|
@IntDef({
|
||
|
DISCONTINUITY_REASON_AUTO_TRANSITION,
|
||
|
DISCONTINUITY_REASON_SEEK,
|
||
|
DISCONTINUITY_REASON_SEEK_ADJUSTMENT,
|
||
|
DISCONTINUITY_REASON_SKIP,
|
||
|
DISCONTINUITY_REASON_REMOVE,
|
||
|
DISCONTINUITY_REASON_INTERNAL
|
||
|
})
|
||
|
@interface DiscontinuityReason {}
|
||
|
/**
|
||
|
* Automatic playback transition from one period in the timeline to the next. The period index may
|
||
|
* be the same as it was before the discontinuity in case the current period is repeated.
|
||
|
*
|
||
|
* <p>This reason also indicates an automatic transition from the content period to an inserted ad
|
||
|
* period or vice versa. Or a transition caused by another player (e.g. multiple controllers can
|
||
|
* control the same playback on a remote device).
|
||
|
*/
|
||
|
int DISCONTINUITY_REASON_AUTO_TRANSITION = 0;
|
||
|
/** Seek within the current period or to another period. */
|
||
|
int DISCONTINUITY_REASON_SEEK = 1;
|
||
|
/**
|
||
|
* Seek adjustment due to being unable to seek to the requested position or because the seek was
|
||
|
* permitted to be inexact.
|
||
|
*/
|
||
|
int DISCONTINUITY_REASON_SEEK_ADJUSTMENT = 2;
|
||
|
/** Discontinuity introduced by a skipped period (for instance a skipped ad). */
|
||
|
int DISCONTINUITY_REASON_SKIP = 3;
|
||
|
/** Discontinuity caused by the removal of the current period from the {@link Timeline}. */
|
||
|
int DISCONTINUITY_REASON_REMOVE = 4;
|
||
|
/** Discontinuity introduced internally (e.g. by the source). */
|
||
|
int DISCONTINUITY_REASON_INTERNAL = 5;
|
||
|
|
||
|
/**
|
||
|
* Reasons for timeline changes. One of {@link #TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED} or {@link
|
||
|
* #TIMELINE_CHANGE_REASON_SOURCE_UPDATE}.
|
||
|
*/
|
||
|
@Documented
|
||
|
@Retention(RetentionPolicy.SOURCE)
|
||
|
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE, TYPE_USE})
|
||
|
@IntDef({TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED, TIMELINE_CHANGE_REASON_SOURCE_UPDATE})
|
||
|
@interface TimelineChangeReason {}
|
||
|
/** Timeline changed as a result of a change of the playlist items or the order of the items. */
|
||
|
int TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED = 0;
|
||
|
/**
|
||
|
* Timeline changed as a result of a source update (e.g. result of a dynamic update by the played
|
||
|
* media).
|
||
|
*
|
||
|
* <p>This reason also indicates a change caused by another player (e.g. multiple controllers can
|
||
|
* control the same playback on the remote device).
|
||
|
*/
|
||
|
int TIMELINE_CHANGE_REASON_SOURCE_UPDATE = 1;
|
||
|
|
||
|
/**
|
||
|
* Reasons for media item transitions. One of {@link #MEDIA_ITEM_TRANSITION_REASON_REPEAT}, {@link
|
||
|
* #MEDIA_ITEM_TRANSITION_REASON_AUTO}, {@link #MEDIA_ITEM_TRANSITION_REASON_SEEK} or {@link
|
||
|
* #MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED}.
|
||
|
*/
|
||
|
@Documented
|
||
|
@Retention(RetentionPolicy.SOURCE)
|
||
|
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE, TYPE_USE})
|
||
|
@IntDef({
|
||
|
MEDIA_ITEM_TRANSITION_REASON_REPEAT,
|
||
|
MEDIA_ITEM_TRANSITION_REASON_AUTO,
|
||
|
MEDIA_ITEM_TRANSITION_REASON_SEEK,
|
||
|
MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED
|
||
|
})
|
||
|
@interface MediaItemTransitionReason {}
|
||
|
/** The media item has been repeated. */
|
||
|
int MEDIA_ITEM_TRANSITION_REASON_REPEAT = 0;
|
||
|
/**
|
||
|
* Playback has automatically transitioned to the next media item.
|
||
|
*
|
||
|
* <p>This reason also indicates a transition caused by another player (e.g. multiple controllers
|
||
|
* can control the same playback on a remote device).
|
||
|
*/
|
||
|
int MEDIA_ITEM_TRANSITION_REASON_AUTO = 1;
|
||
|
/** A seek to another media item has occurred. */
|
||
|
int MEDIA_ITEM_TRANSITION_REASON_SEEK = 2;
|
||
|
/**
|
||
|
* The current media item has changed because of a change in the playlist. This can either be if
|
||
|
* the media item previously being played has been removed, or when the playlist becomes non-empty
|
||
|
* after being empty.
|
||
|
*/
|
||
|
int MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED = 3;
|
||
|
|
||
|
/**
|
||
|
* Events that can be reported via {@link Listener#onEvents(Player, Events)}.
|
||
|
*
|
||
|
* <p>One of the {@link Player}{@code .EVENT_*} values.
|
||
|
*/
|
||
|
@Documented
|
||
|
@Retention(RetentionPolicy.SOURCE)
|
||
|
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE, TYPE_USE})
|
||
|
@IntDef({
|
||
|
EVENT_TIMELINE_CHANGED,
|
||
|
EVENT_MEDIA_ITEM_TRANSITION,
|
||
|
EVENT_TRACKS_CHANGED,
|
||
|
EVENT_IS_LOADING_CHANGED,
|
||
|
EVENT_PLAYBACK_STATE_CHANGED,
|
||
|
EVENT_PLAY_WHEN_READY_CHANGED,
|
||
|
EVENT_PLAYBACK_SUPPRESSION_REASON_CHANGED,
|
||
|
EVENT_IS_PLAYING_CHANGED,
|
||
|
EVENT_REPEAT_MODE_CHANGED,
|
||
|
EVENT_SHUFFLE_MODE_ENABLED_CHANGED,
|
||
|
EVENT_PLAYER_ERROR,
|
||
|
EVENT_POSITION_DISCONTINUITY,
|
||
|
EVENT_PLAYBACK_PARAMETERS_CHANGED,
|
||
|
EVENT_AVAILABLE_COMMANDS_CHANGED,
|
||
|
EVENT_MEDIA_METADATA_CHANGED,
|
||
|
EVENT_PLAYLIST_METADATA_CHANGED,
|
||
|
EVENT_SEEK_BACK_INCREMENT_CHANGED,
|
||
|
EVENT_SEEK_FORWARD_INCREMENT_CHANGED,
|
||
|
EVENT_MAX_SEEK_TO_PREVIOUS_POSITION_CHANGED,
|
||
|
EVENT_TRACK_SELECTION_PARAMETERS_CHANGED,
|
||
|
})
|
||
|
@interface Event {}
|
||
|
/** {@link #getCurrentTimeline()} changed. */
|
||
|
int EVENT_TIMELINE_CHANGED = 0;
|
||
|
/** {@link #getCurrentMediaItem()} changed or the player started repeating the current item. */
|
||
|
int EVENT_MEDIA_ITEM_TRANSITION = 1;
|
||
|
/** {@link #getCurrentTracksInfo()} changed. */
|
||
|
int EVENT_TRACKS_CHANGED = 2;
|
||
|
/** {@link #isLoading()} ()} changed. */
|
||
|
int EVENT_IS_LOADING_CHANGED = 3;
|
||
|
/** {@link #getPlaybackState()} changed. */
|
||
|
int EVENT_PLAYBACK_STATE_CHANGED = 4;
|
||
|
/** {@link #getPlayWhenReady()} changed. */
|
||
|
int EVENT_PLAY_WHEN_READY_CHANGED = 5;
|
||
|
/** {@link #getPlaybackSuppressionReason()} changed. */
|
||
|
int EVENT_PLAYBACK_SUPPRESSION_REASON_CHANGED = 6;
|
||
|
/** {@link #isPlaying()} changed. */
|
||
|
int EVENT_IS_PLAYING_CHANGED = 7;
|
||
|
/** {@link #getRepeatMode()} changed. */
|
||
|
int EVENT_REPEAT_MODE_CHANGED = 8;
|
||
|
/** {@link #getShuffleModeEnabled()} changed. */
|
||
|
int EVENT_SHUFFLE_MODE_ENABLED_CHANGED = 9;
|
||
|
/** {@link #getPlayerError()} changed. */
|
||
|
int EVENT_PLAYER_ERROR = 10;
|
||
|
/**
|
||
|
* A position discontinuity occurred. See {@link Listener#onPositionDiscontinuity(PositionInfo,
|
||
|
* PositionInfo, int)}.
|
||
|
*/
|
||
|
int EVENT_POSITION_DISCONTINUITY = 11;
|
||
|
/** {@link #getPlaybackParameters()} changed. */
|
||
|
int EVENT_PLAYBACK_PARAMETERS_CHANGED = 12;
|
||
|
/** {@link #isCommandAvailable(int)} changed for at least one {@link Command}. */
|
||
|
int EVENT_AVAILABLE_COMMANDS_CHANGED = 13;
|
||
|
/** {@link #getMediaMetadata()} changed. */
|
||
|
int EVENT_MEDIA_METADATA_CHANGED = 14;
|
||
|
/** {@link #getPlaylistMetadata()} changed. */
|
||
|
int EVENT_PLAYLIST_METADATA_CHANGED = 15;
|
||
|
/** {@link #getSeekBackIncrement()} changed. */
|
||
|
int EVENT_SEEK_BACK_INCREMENT_CHANGED = 16;
|
||
|
/** {@link #getSeekForwardIncrement()} changed. */
|
||
|
int EVENT_SEEK_FORWARD_INCREMENT_CHANGED = 17;
|
||
|
/** {@link #getMaxSeekToPreviousPosition()} changed. */
|
||
|
int EVENT_MAX_SEEK_TO_PREVIOUS_POSITION_CHANGED = 18;
|
||
|
/** {@link #getTrackSelectionParameters()} changed. */
|
||
|
int EVENT_TRACK_SELECTION_PARAMETERS_CHANGED = 19;
|
||
|
|
||
|
/**
|
||
|
* Commands that can be executed on a {@code Player}. One of {@link #COMMAND_PLAY_PAUSE}, {@link
|
||
|
* #COMMAND_PREPARE}, {@link #COMMAND_STOP}, {@link #COMMAND_SEEK_TO_DEFAULT_POSITION}, {@link
|
||
|
* #COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM}, {@link #COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM}, {@link
|
||
|
* #COMMAND_SEEK_TO_PREVIOUS}, {@link #COMMAND_SEEK_TO_NEXT_MEDIA_ITEM}, {@link
|
||
|
* #COMMAND_SEEK_TO_NEXT}, {@link #COMMAND_SEEK_TO_MEDIA_ITEM}, {@link #COMMAND_SEEK_BACK}, {@link
|
||
|
* #COMMAND_SEEK_FORWARD}, {@link #COMMAND_SET_SPEED_AND_PITCH}, {@link
|
||
|
* #COMMAND_SET_SHUFFLE_MODE}, {@link #COMMAND_SET_REPEAT_MODE}, {@link
|
||
|
* #COMMAND_GET_CURRENT_MEDIA_ITEM}, {@link #COMMAND_GET_TIMELINE}, {@link
|
||
|
* #COMMAND_GET_MEDIA_ITEMS_METADATA}, {@link #COMMAND_SET_MEDIA_ITEMS_METADATA}, {@link
|
||
|
* #COMMAND_CHANGE_MEDIA_ITEMS}, {@link #COMMAND_GET_AUDIO_ATTRIBUTES}, {@link
|
||
|
* #COMMAND_GET_VOLUME}, {@link #COMMAND_GET_DEVICE_VOLUME}, {@link #COMMAND_SET_VOLUME}, {@link
|
||
|
* #COMMAND_SET_DEVICE_VOLUME}, {@link #COMMAND_ADJUST_DEVICE_VOLUME}, {@link
|
||
|
* #COMMAND_SET_VIDEO_SURFACE}, {@link #COMMAND_GET_TEXT}, {@link
|
||
|
* #COMMAND_SET_TRACK_SELECTION_PARAMETERS} or {@link #COMMAND_GET_TRACK_INFOS}.
|
||
|
*/
|
||
|
@Documented
|
||
|
@Retention(RetentionPolicy.SOURCE)
|
||
|
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE, TYPE_USE})
|
||
|
@IntDef({
|
||
|
COMMAND_INVALID,
|
||
|
COMMAND_PLAY_PAUSE,
|
||
|
COMMAND_PREPARE,
|
||
|
COMMAND_STOP,
|
||
|
COMMAND_SEEK_TO_DEFAULT_POSITION,
|
||
|
COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM,
|
||
|
COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM,
|
||
|
COMMAND_SEEK_TO_PREVIOUS,
|
||
|
COMMAND_SEEK_TO_NEXT_MEDIA_ITEM,
|
||
|
COMMAND_SEEK_TO_NEXT,
|
||
|
COMMAND_SEEK_TO_MEDIA_ITEM,
|
||
|
COMMAND_SEEK_BACK,
|
||
|
COMMAND_SEEK_FORWARD,
|
||
|
COMMAND_SET_SPEED_AND_PITCH,
|
||
|
COMMAND_SET_SHUFFLE_MODE,
|
||
|
COMMAND_SET_REPEAT_MODE,
|
||
|
COMMAND_GET_CURRENT_MEDIA_ITEM,
|
||
|
COMMAND_GET_TIMELINE,
|
||
|
COMMAND_GET_MEDIA_ITEMS_METADATA,
|
||
|
COMMAND_SET_MEDIA_ITEMS_METADATA,
|
||
|
COMMAND_CHANGE_MEDIA_ITEMS,
|
||
|
COMMAND_GET_AUDIO_ATTRIBUTES,
|
||
|
COMMAND_GET_VOLUME,
|
||
|
COMMAND_GET_DEVICE_VOLUME,
|
||
|
COMMAND_SET_VOLUME,
|
||
|
COMMAND_SET_DEVICE_VOLUME,
|
||
|
COMMAND_ADJUST_DEVICE_VOLUME,
|
||
|
COMMAND_SET_VIDEO_SURFACE,
|
||
|
COMMAND_GET_TEXT,
|
||
|
COMMAND_SET_TRACK_SELECTION_PARAMETERS,
|
||
|
COMMAND_GET_TRACK_INFOS,
|
||
|
})
|
||
|
@interface Command {}
|
||
|
/** Command to start, pause or resume playback. */
|
||
|
int COMMAND_PLAY_PAUSE = 1;
|
||
|
/** Command to prepare the player. */
|
||
|
int COMMAND_PREPARE = 2;
|
||
|
/** Command to stop playback or release the player. */
|
||
|
int COMMAND_STOP = 3;
|
||
|
/** Command to seek to the default position of the current {@link MediaItem}. */
|
||
|
int COMMAND_SEEK_TO_DEFAULT_POSITION = 4;
|
||
|
/** Command to seek anywhere into the current {@link MediaItem}. */
|
||
|
int COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM = 5;
|
||
|
/** @deprecated Use {@link #COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM} instead. */
|
||
|
@Deprecated int COMMAND_SEEK_IN_CURRENT_WINDOW = COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM;
|
||
|
/** Command to seek to the default position of the previous {@link MediaItem}. */
|
||
|
int COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM = 6;
|
||
|
/** @deprecated Use {@link #COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM} instead. */
|
||
|
@Deprecated int COMMAND_SEEK_TO_PREVIOUS_WINDOW = COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM;
|
||
|
/** Command to seek to an earlier position in the current or previous {@link MediaItem}. */
|
||
|
int COMMAND_SEEK_TO_PREVIOUS = 7;
|
||
|
/** Command to seek to the default position of the next {@link MediaItem}. */
|
||
|
int COMMAND_SEEK_TO_NEXT_MEDIA_ITEM = 8;
|
||
|
/** @deprecated Use {@link #COMMAND_SEEK_TO_NEXT_MEDIA_ITEM} instead. */
|
||
|
@Deprecated int COMMAND_SEEK_TO_NEXT_WINDOW = COMMAND_SEEK_TO_NEXT_MEDIA_ITEM;
|
||
|
/** Command to seek to a later position in the current or next {@link MediaItem}. */
|
||
|
int COMMAND_SEEK_TO_NEXT = 9;
|
||
|
/** Command to seek anywhere in any {@link MediaItem}. */
|
||
|
int COMMAND_SEEK_TO_MEDIA_ITEM = 10;
|
||
|
/** @deprecated Use {@link #COMMAND_SEEK_TO_MEDIA_ITEM} instead. */
|
||
|
@Deprecated int COMMAND_SEEK_TO_WINDOW = COMMAND_SEEK_TO_MEDIA_ITEM;
|
||
|
/** Command to seek back by a fixed increment into the current {@link MediaItem}. */
|
||
|
int COMMAND_SEEK_BACK = 11;
|
||
|
/** Command to seek forward by a fixed increment into the current {@link MediaItem}. */
|
||
|
int COMMAND_SEEK_FORWARD = 12;
|
||
|
/** Command to set the playback speed and pitch. */
|
||
|
int COMMAND_SET_SPEED_AND_PITCH = 13;
|
||
|
/** Command to enable shuffling. */
|
||
|
int COMMAND_SET_SHUFFLE_MODE = 14;
|
||
|
/** Command to set the repeat mode. */
|
||
|
int COMMAND_SET_REPEAT_MODE = 15;
|
||
|
/** Command to get the currently playing {@link MediaItem}. */
|
||
|
int COMMAND_GET_CURRENT_MEDIA_ITEM = 16;
|
||
|
/** Command to get the information about the current timeline. */
|
||
|
int COMMAND_GET_TIMELINE = 17;
|
||
|
/** Command to get the {@link MediaItem MediaItems} metadata. */
|
||
|
int COMMAND_GET_MEDIA_ITEMS_METADATA = 18;
|
||
|
/** Command to set the {@link MediaItem MediaItems} metadata. */
|
||
|
int COMMAND_SET_MEDIA_ITEMS_METADATA = 19;
|
||
|
/** Command to change the {@link MediaItem MediaItems} in the playlist. */
|
||
|
int COMMAND_CHANGE_MEDIA_ITEMS = 20;
|
||
|
/** Command to get the player current {@link AudioAttributes}. */
|
||
|
int COMMAND_GET_AUDIO_ATTRIBUTES = 21;
|
||
|
/** Command to get the player volume. */
|
||
|
int COMMAND_GET_VOLUME = 22;
|
||
|
/** Command to get the device volume and whether it is muted. */
|
||
|
int COMMAND_GET_DEVICE_VOLUME = 23;
|
||
|
/** Command to set the player volume. */
|
||
|
int COMMAND_SET_VOLUME = 24;
|
||
|
/** Command to set the device volume and mute it. */
|
||
|
int COMMAND_SET_DEVICE_VOLUME = 25;
|
||
|
/** Command to increase and decrease the device volume and mute it. */
|
||
|
int COMMAND_ADJUST_DEVICE_VOLUME = 26;
|
||
|
/** Command to set and clear the surface on which to render the video. */
|
||
|
int COMMAND_SET_VIDEO_SURFACE = 27;
|
||
|
/** Command to get the text that should currently be displayed by the player. */
|
||
|
int COMMAND_GET_TEXT = 28;
|
||
|
/** Command to set the player's track selection parameters. */
|
||
|
int COMMAND_SET_TRACK_SELECTION_PARAMETERS = 29;
|
||
|
/** Command to get track infos. */
|
||
|
int COMMAND_GET_TRACK_INFOS = 30;
|
||
|
|
||
|
/** Represents an invalid {@link Command}. */
|
||
|
int COMMAND_INVALID = -1;
|
||
|
|
||
|
/**
|
||
|
* Returns the {@link Looper} associated with the application thread that's used to access the
|
||
|
* player and on which player events are received.
|
||
|
*/
|
||
|
Looper getApplicationLooper();
|
||
|
|
||
|
/**
|
||
|
* Registers a listener to receive all events from the player.
|
||
|
*
|
||
|
* <p>The listener's methods will be called on the thread associated with {@link
|
||
|
* #getApplicationLooper()}.
|
||
|
*
|
||
|
* @param listener The listener to register.
|
||
|
*/
|
||
|
void addListener(Listener listener);
|
||
|
|
||
|
/**
|
||
|
* Unregister a listener registered through {@link #addListener(Listener)}. The listener will no
|
||
|
* longer receive events.
|
||
|
*
|
||
|
* @param listener The listener to unregister.
|
||
|
*/
|
||
|
void removeListener(Listener listener);
|
||
|
|
||
|
/**
|
||
|
* Clears the playlist, adds the specified {@link MediaItem MediaItems} and resets the position to
|
||
|
* the default position.
|
||
|
*
|
||
|
* @param mediaItems The new {@link MediaItem MediaItems}.
|
||
|
*/
|
||
|
void setMediaItems(List<MediaItem> mediaItems);
|
||
|
|
||
|
/**
|
||
|
* Clears the playlist and adds the specified {@link MediaItem MediaItems}.
|
||
|
*
|
||
|
* @param mediaItems The new {@link MediaItem MediaItems}.
|
||
|
* @param resetPosition Whether the playback position should be reset to the default position in
|
||
|
* the first {@link Timeline.Window}. If false, playback will start from the position defined
|
||
|
* by {@link #getCurrentMediaItemIndex()} and {@link #getCurrentPosition()}.
|
||
|
*/
|
||
|
void setMediaItems(List<MediaItem> mediaItems, boolean resetPosition);
|
||
|
|
||
|
/**
|
||
|
* Clears the playlist and adds the specified {@link MediaItem MediaItems}.
|
||
|
*
|
||
|
* @param mediaItems The new {@link MediaItem MediaItems}.
|
||
|
* @param startIndex The {@link MediaItem} index to start playback from. If {@link C#INDEX_UNSET}
|
||
|
* is passed, the current position is not reset.
|
||
|
* @param startPositionMs The position in milliseconds to start playback from. If {@link
|
||
|
* C#TIME_UNSET} is passed, the default position of the given {@link MediaItem} is used. In
|
||
|
* any case, if {@code startIndex} is set to {@link C#INDEX_UNSET}, this parameter is ignored
|
||
|
* and the position is not reset at all.
|
||
|
* @throws IllegalSeekPositionException If the provided {@code startIndex} is not within the
|
||
|
* bounds of the list of media items.
|
||
|
*/
|
||
|
void setMediaItems(List<MediaItem> mediaItems, int startIndex, long startPositionMs);
|
||
|
|
||
|
/**
|
||
|
* Clears the playlist, adds the specified {@link MediaItem} and resets the position to the
|
||
|
* default position.
|
||
|
*
|
||
|
* @param mediaItem The new {@link MediaItem}.
|
||
|
*/
|
||
|
void setMediaItem(MediaItem mediaItem);
|
||
|
|
||
|
/**
|
||
|
* Clears the playlist and adds the specified {@link MediaItem}.
|
||
|
*
|
||
|
* @param mediaItem The new {@link MediaItem}.
|
||
|
* @param startPositionMs The position in milliseconds to start playback from.
|
||
|
*/
|
||
|
void setMediaItem(MediaItem mediaItem, long startPositionMs);
|
||
|
|
||
|
/**
|
||
|
* Clears the playlist and adds the specified {@link MediaItem}.
|
||
|
*
|
||
|
* @param mediaItem The new {@link MediaItem}.
|
||
|
* @param resetPosition Whether the playback position should be reset to the default position. If
|
||
|
* false, playback will start from the position defined by {@link #getCurrentMediaItemIndex()}
|
||
|
* and {@link #getCurrentPosition()}.
|
||
|
*/
|
||
|
void setMediaItem(MediaItem mediaItem, boolean resetPosition);
|
||
|
|
||
|
/**
|
||
|
* Adds a media item to the end of the playlist.
|
||
|
*
|
||
|
* @param mediaItem The {@link MediaItem} to add.
|
||
|
*/
|
||
|
void addMediaItem(MediaItem mediaItem);
|
||
|
|
||
|
/**
|
||
|
* Adds a media item at the given index of the playlist.
|
||
|
*
|
||
|
* @param index The index at which to add the media item. If the index is larger than the size of
|
||
|
* the playlist, the media item is added to the end of the playlist.
|
||
|
* @param mediaItem The {@link MediaItem} to add.
|
||
|
*/
|
||
|
void addMediaItem(int index, MediaItem mediaItem);
|
||
|
|
||
|
/**
|
||
|
* Adds a list of media items to the end of the playlist.
|
||
|
*
|
||
|
* @param mediaItems The {@link MediaItem MediaItems} to add.
|
||
|
*/
|
||
|
void addMediaItems(List<MediaItem> mediaItems);
|
||
|
|
||
|
/**
|
||
|
* Adds a list of media items at the given index of the playlist.
|
||
|
*
|
||
|
* @param index The index at which to add the media items. If the index is larger than the size of
|
||
|
* the playlist, the media items are added to the end of the playlist.
|
||
|
* @param mediaItems The {@link MediaItem MediaItems} to add.
|
||
|
*/
|
||
|
void addMediaItems(int index, List<MediaItem> mediaItems);
|
||
|
|
||
|
/**
|
||
|
* Moves the media item at the current index to the new index.
|
||
|
*
|
||
|
* @param currentIndex The current index of the media item to move.
|
||
|
* @param newIndex The new index of the media item. If the new index is larger than the size of
|
||
|
* the playlist the item is moved to the end of the playlist.
|
||
|
*/
|
||
|
void moveMediaItem(int currentIndex, int newIndex);
|
||
|
|
||
|
/**
|
||
|
* Moves the media item range to the new index.
|
||
|
*
|
||
|
* @param fromIndex The start of the range to move.
|
||
|
* @param toIndex The first item not to be included in the range (exclusive).
|
||
|
* @param newIndex The new index of the first media item of the range. If the new index is larger
|
||
|
* than the size of the remaining playlist after removing the range, the range is moved to the
|
||
|
* end of the playlist.
|
||
|
*/
|
||
|
void moveMediaItems(int fromIndex, int toIndex, int newIndex);
|
||
|
|
||
|
/**
|
||
|
* Removes the media item at the given index of the playlist.
|
||
|
*
|
||
|
* @param index The index at which to remove the media item.
|
||
|
*/
|
||
|
void removeMediaItem(int index);
|
||
|
|
||
|
/**
|
||
|
* Removes a range of media items from the playlist.
|
||
|
*
|
||
|
* @param fromIndex The index at which to start removing media items.
|
||
|
* @param toIndex The index of the first item to be kept (exclusive). If the index is larger than
|
||
|
* the size of the playlist, media items to the end of the playlist are removed.
|
||
|
*/
|
||
|
void removeMediaItems(int fromIndex, int toIndex);
|
||
|
|
||
|
/** Clears the playlist. */
|
||
|
void clearMediaItems();
|
||
|
|
||
|
/**
|
||
|
* Returns whether the provided {@link Command} is available.
|
||
|
*
|
||
|
* <p>This method does not execute the command.
|
||
|
*
|
||
|
* <p>Executing a command that is not available (for example, calling {@link
|
||
|
* #seekToNextMediaItem()} if {@link #COMMAND_SEEK_TO_NEXT_MEDIA_ITEM} is unavailable) will
|
||
|
* neither throw an exception nor generate a {@link #getPlayerError()} player error}.
|
||
|
*
|
||
|
* <p>{@link #COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM} and {@link #COMMAND_SEEK_TO_NEXT_MEDIA_ITEM}
|
||
|
* are unavailable if there is no such {@link MediaItem}.
|
||
|
*
|
||
|
* @param command A {@link Command}.
|
||
|
* @return Whether the {@link Command} is available.
|
||
|
* @see Listener#onAvailableCommandsChanged(Commands)
|
||
|
*/
|
||
|
boolean isCommandAvailable(@Command int command);
|
||
|
|
||
|
/** Returns whether the player can be used to advertise a media session. */
|
||
|
boolean canAdvertiseSession();
|
||
|
|
||
|
/**
|
||
|
* Returns the player's currently available {@link Commands}.
|
||
|
*
|
||
|
* <p>The returned {@link Commands} are not updated when available commands change. Use {@link
|
||
|
* Listener#onAvailableCommandsChanged(Commands)} to get an update when the available commands
|
||
|
* change.
|
||
|
*
|
||
|
* <p>Executing a command that is not available (for example, calling {@link
|
||
|
* #seekToNextMediaItem()} if {@link #COMMAND_SEEK_TO_NEXT_MEDIA_ITEM} is unavailable) will
|
||
|
* neither throw an exception nor generate a {@link #getPlayerError()} player error}.
|
||
|
*
|
||
|
* <p>{@link #COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM} and {@link #COMMAND_SEEK_TO_NEXT_MEDIA_ITEM}
|
||
|
* are unavailable if there is no such {@link MediaItem}.
|
||
|
*
|
||
|
* @return The currently available {@link Commands}.
|
||
|
* @see Listener#onAvailableCommandsChanged
|
||
|
*/
|
||
|
Commands getAvailableCommands();
|
||
|
|
||
|
/**
|
||
|
* Prepares the player.
|
||
|
*
|
||
|
* <p>This will move the player out of {@link #STATE_IDLE idle state} and the player will start
|
||
|
* loading media and acquire resources needed for playback.
|
||
|
*/
|
||
|
void prepare();
|
||
|
|
||
|
/**
|
||
|
* Returns the current {@link State playback state} of the player.
|
||
|
*
|
||
|
* @return The current {@link State playback state}.
|
||
|
* @see Listener#onPlaybackStateChanged(int)
|
||
|
*/
|
||
|
@State
|
||
|
int getPlaybackState();
|
||
|
|
||
|
/**
|
||
|
* Returns the reason why playback is suppressed even though {@link #getPlayWhenReady()} is {@code
|
||
|
* true}, or {@link #PLAYBACK_SUPPRESSION_REASON_NONE} if playback is not suppressed.
|
||
|
*
|
||
|
* @return The current {@link PlaybackSuppressionReason playback suppression reason}.
|
||
|
* @see Listener#onPlaybackSuppressionReasonChanged(int)
|
||
|
*/
|
||
|
@PlaybackSuppressionReason
|
||
|
int getPlaybackSuppressionReason();
|
||
|
|
||
|
/**
|
||
|
* Returns whether the player is playing, i.e. {@link #getCurrentPosition()} is advancing.
|
||
|
*
|
||
|
* <p>If {@code false}, then at least one of the following is true:
|
||
|
*
|
||
|
* <ul>
|
||
|
* <li>The {@link #getPlaybackState() playback state} is not {@link #STATE_READY ready}.
|
||
|
* <li>There is no {@link #getPlayWhenReady() intention to play}.
|
||
|
* <li>Playback is {@link #getPlaybackSuppressionReason() suppressed for other reasons}.
|
||
|
* </ul>
|
||
|
*
|
||
|
* @return Whether the player is playing.
|
||
|
* @see Listener#onIsPlayingChanged(boolean)
|
||
|
*/
|
||
|
boolean isPlaying();
|
||
|
|
||
|
/**
|
||
|
* Returns the error that caused playback to fail. This is the same error that will have been
|
||
|
* reported via {@link Listener#onPlayerError(PlaybackException)} at the time of failure. It can
|
||
|
* be queried using this method until the player is re-prepared.
|
||
|
*
|
||
|
* <p>Note that this method will always return {@code null} if {@link #getPlaybackState()} is not
|
||
|
* {@link #STATE_IDLE}.
|
||
|
*
|
||
|
* @return The error, or {@code null}.
|
||
|
* @see Listener#onPlayerError(PlaybackException)
|
||
|
*/
|
||
|
@Nullable
|
||
|
PlaybackException getPlayerError();
|
||
|
|
||
|
/**
|
||
|
* Resumes playback as soon as {@link #getPlaybackState()} == {@link #STATE_READY}. Equivalent to
|
||
|
* {@code setPlayWhenReady(true)}.
|
||
|
*/
|
||
|
void play();
|
||
|
|
||
|
/** Pauses playback. Equivalent to {@code setPlayWhenReady(false)}. */
|
||
|
void pause();
|
||
|
|
||
|
/**
|
||
|
* Sets whether playback should proceed when {@link #getPlaybackState()} == {@link #STATE_READY}.
|
||
|
*
|
||
|
* <p>If the player is already in the ready state then this method pauses and resumes playback.
|
||
|
*
|
||
|
* @param playWhenReady Whether playback should proceed when ready.
|
||
|
*/
|
||
|
void setPlayWhenReady(boolean playWhenReady);
|
||
|
|
||
|
/**
|
||
|
* Whether playback will proceed when {@link #getPlaybackState()} == {@link #STATE_READY}.
|
||
|
*
|
||
|
* @return Whether playback will proceed when ready.
|
||
|
* @see Listener#onPlayWhenReadyChanged(boolean, int)
|
||
|
*/
|
||
|
boolean getPlayWhenReady();
|
||
|
|
||
|
/**
|
||
|
* Sets the {@link RepeatMode} to be used for playback.
|
||
|
*
|
||
|
* @param repeatMode The repeat mode.
|
||
|
*/
|
||
|
void setRepeatMode(@RepeatMode int repeatMode);
|
||
|
|
||
|
/**
|
||
|
* Returns the current {@link RepeatMode} used for playback.
|
||
|
*
|
||
|
* @return The current repeat mode.
|
||
|
* @see Listener#onRepeatModeChanged(int)
|
||
|
*/
|
||
|
@RepeatMode
|
||
|
int getRepeatMode();
|
||
|
|
||
|
/**
|
||
|
* Sets whether shuffling of media items is enabled.
|
||
|
*
|
||
|
* @param shuffleModeEnabled Whether shuffling is enabled.
|
||
|
*/
|
||
|
void setShuffleModeEnabled(boolean shuffleModeEnabled);
|
||
|
|
||
|
/**
|
||
|
* Returns whether shuffling of media items is enabled.
|
||
|
*
|
||
|
* @see Listener#onShuffleModeEnabledChanged(boolean)
|
||
|
*/
|
||
|
boolean getShuffleModeEnabled();
|
||
|
|
||
|
/**
|
||
|
* Whether the player is currently loading the source.
|
||
|
*
|
||
|
* @return Whether the player is currently loading the source.
|
||
|
* @see Listener#onIsLoadingChanged(boolean)
|
||
|
*/
|
||
|
boolean isLoading();
|
||
|
|
||
|
/**
|
||
|
* Seeks to the default position associated with the current {@link MediaItem}. The position can
|
||
|
* depend on the type of media being played. For live streams it will typically be the live edge.
|
||
|
* For other streams it will typically be the start.
|
||
|
*/
|
||
|
void seekToDefaultPosition();
|
||
|
|
||
|
/**
|
||
|
* Seeks to the default position associated with the specified {@link MediaItem}. The position can
|
||
|
* depend on the type of media being played. For live streams it will typically be the live edge.
|
||
|
* For other streams it will typically be the start.
|
||
|
*
|
||
|
* @param mediaItemIndex The index of the {@link MediaItem} whose associated default position
|
||
|
* should be seeked to.
|
||
|
* @throws IllegalSeekPositionException If the player has a non-empty timeline and the provided
|
||
|
* {@code mediaItemIndex} is not within the bounds of the current timeline.
|
||
|
*/
|
||
|
void seekToDefaultPosition(int mediaItemIndex);
|
||
|
|
||
|
/**
|
||
|
* Seeks to a position specified in milliseconds in the current {@link MediaItem}.
|
||
|
*
|
||
|
* @param positionMs The seek position in the current {@link MediaItem}, or {@link C#TIME_UNSET}
|
||
|
* to seek to the media item's default position.
|
||
|
*/
|
||
|
void seekTo(long positionMs);
|
||
|
|
||
|
/**
|
||
|
* Seeks to a position specified in milliseconds in the specified {@link MediaItem}.
|
||
|
*
|
||
|
* @param mediaItemIndex The index of the {@link MediaItem}.
|
||
|
* @param positionMs The seek position in the specified {@link MediaItem}, or {@link C#TIME_UNSET}
|
||
|
* to seek to the media item's default position.
|
||
|
* @throws IllegalSeekPositionException If the player has a non-empty timeline and the provided
|
||
|
* {@code mediaItemIndex} is not within the bounds of the current timeline.
|
||
|
*/
|
||
|
void seekTo(int mediaItemIndex, long positionMs);
|
||
|
|
||
|
/**
|
||
|
* Returns the {@link #seekBack()} increment.
|
||
|
*
|
||
|
* @return The seek back increment, in milliseconds.
|
||
|
* @see Listener#onSeekBackIncrementChanged(long)
|
||
|
*/
|
||
|
long getSeekBackIncrement();
|
||
|
|
||
|
/**
|
||
|
* Seeks back in the current {@link MediaItem} by {@link #getSeekBackIncrement()} milliseconds.
|
||
|
*/
|
||
|
void seekBack();
|
||
|
|
||
|
/**
|
||
|
* Returns the {@link #seekForward()} increment.
|
||
|
*
|
||
|
* @return The seek forward increment, in milliseconds.
|
||
|
* @see Listener#onSeekForwardIncrementChanged(long)
|
||
|
*/
|
||
|
long getSeekForwardIncrement();
|
||
|
|
||
|
/**
|
||
|
* Seeks forward in the current {@link MediaItem} by {@link #getSeekForwardIncrement()}
|
||
|
* milliseconds.
|
||
|
*/
|
||
|
void seekForward();
|
||
|
|
||
|
/** @deprecated Use {@link #hasPreviousMediaItem()} instead. */
|
||
|
@Deprecated
|
||
|
boolean hasPrevious();
|
||
|
|
||
|
/** @deprecated Use {@link #hasPreviousMediaItem()} instead. */
|
||
|
@Deprecated
|
||
|
boolean hasPreviousWindow();
|
||
|
|
||
|
/**
|
||
|
* Returns whether a previous media item exists, which may depend on the current repeat mode and
|
||
|
* whether shuffle mode is enabled.
|
||
|
*
|
||
|
* <p>Note: When the repeat mode is {@link #REPEAT_MODE_ONE}, this method behaves the same as when
|
||
|
* the current repeat mode is {@link #REPEAT_MODE_OFF}. See {@link #REPEAT_MODE_ONE} for more
|
||
|
* details.
|
||
|
*/
|
||
|
boolean hasPreviousMediaItem();
|
||
|
|
||
|
/** @deprecated Use {@link #seekToPreviousMediaItem()} instead. */
|
||
|
@Deprecated
|
||
|
void previous();
|
||
|
|
||
|
/** @deprecated Use {@link #seekToPreviousMediaItem()} instead. */
|
||
|
@Deprecated
|
||
|
void seekToPreviousWindow();
|
||
|
|
||
|
/**
|
||
|
* Seeks to the default position of the previous {@link MediaItem}, which may depend on the
|
||
|
* current repeat mode and whether shuffle mode is enabled. Does nothing if {@link
|
||
|
* #hasPreviousMediaItem()} is {@code false}.
|
||
|
*
|
||
|
* <p>Note: When the repeat mode is {@link #REPEAT_MODE_ONE}, this method behaves the same as when
|
||
|
* the current repeat mode is {@link #REPEAT_MODE_OFF}. See {@link #REPEAT_MODE_ONE} for more
|
||
|
* details.
|
||
|
*/
|
||
|
void seekToPreviousMediaItem();
|
||
|
|
||
|
/**
|
||
|
* Returns the maximum position for which {@link #seekToPrevious()} seeks to the previous {@link
|
||
|
* MediaItem}, in milliseconds.
|
||
|
*
|
||
|
* @return The maximum seek to previous position, in milliseconds.
|
||
|
* @see Listener#onMaxSeekToPreviousPositionChanged(long)
|
||
|
*/
|
||
|
long getMaxSeekToPreviousPosition();
|
||
|
|
||
|
/**
|
||
|
* Seeks to an earlier position in the current or previous {@link MediaItem} (if available). More
|
||
|
* precisely:
|
||
|
*
|
||
|
* <ul>
|
||
|
* <li>If the timeline is empty or seeking is not possible, does nothing.
|
||
|
* <li>Otherwise, if the current {@link MediaItem} is {@link #isCurrentMediaItemLive()} live}
|
||
|
* and {@link #isCurrentMediaItemSeekable() unseekable}, then:
|
||
|
* <ul>
|
||
|
* <li>If {@link #hasPreviousMediaItem() a previous media item exists}, seeks to the
|
||
|
* default position of the previous media item.
|
||
|
* <li>Otherwise, does nothing.
|
||
|
* </ul>
|
||
|
* <li>Otherwise, if {@link #hasPreviousMediaItem() a previous media item exists} and the {@link
|
||
|
* #getCurrentPosition() current position} is less than {@link
|
||
|
* #getMaxSeekToPreviousPosition()}, seeks to the default position of the previous {@link
|
||
|
* MediaItem}.
|
||
|
* <li>Otherwise, seeks to 0 in the current {@link MediaItem}.
|
||
|
* </ul>
|
||
|
*/
|
||
|
void seekToPrevious();
|
||
|
|
||
|
/** @deprecated Use {@link #hasNextMediaItem()} instead. */
|
||
|
@Deprecated
|
||
|
boolean hasNext();
|
||
|
|
||
|
/** @deprecated Use {@link #hasNextMediaItem()} instead. */
|
||
|
@Deprecated
|
||
|
boolean hasNextWindow();
|
||
|
|
||
|
/**
|
||
|
* Returns whether a next {@link MediaItem} exists, which may depend on the current repeat mode
|
||
|
* and whether shuffle mode is enabled.
|
||
|
*
|
||
|
* <p>Note: When the repeat mode is {@link #REPEAT_MODE_ONE}, this method behaves the same as when
|
||
|
* the current repeat mode is {@link #REPEAT_MODE_OFF}. See {@link #REPEAT_MODE_ONE} for more
|
||
|
* details.
|
||
|
*/
|
||
|
boolean hasNextMediaItem();
|
||
|
|
||
|
/** @deprecated Use {@link #seekToNextMediaItem()} instead. */
|
||
|
@Deprecated
|
||
|
void next();
|
||
|
|
||
|
/** @deprecated Use {@link #seekToNextMediaItem()} instead. */
|
||
|
@Deprecated
|
||
|
void seekToNextWindow();
|
||
|
|
||
|
/**
|
||
|
* Seeks to the default position of the next {@link MediaItem}, which may depend on the current
|
||
|
* repeat mode and whether shuffle mode is enabled. Does nothing if {@link #hasNextMediaItem()} is
|
||
|
* {@code false}.
|
||
|
*
|
||
|
* <p>Note: When the repeat mode is {@link #REPEAT_MODE_ONE}, this method behaves the same as when
|
||
|
* the current repeat mode is {@link #REPEAT_MODE_OFF}. See {@link #REPEAT_MODE_ONE} for more
|
||
|
* details.
|
||
|
*/
|
||
|
void seekToNextMediaItem();
|
||
|
|
||
|
/**
|
||
|
* Seeks to a later position in the current or next {@link MediaItem} (if available). More
|
||
|
* precisely:
|
||
|
*
|
||
|
* <ul>
|
||
|
* <li>If the timeline is empty or seeking is not possible, does nothing.
|
||
|
* <li>Otherwise, if {@link #hasNextMediaItem() a next media item exists}, seeks to the default
|
||
|
* position of the next {@link MediaItem}.
|
||
|
* <li>Otherwise, if the current {@link MediaItem} is {@link #isCurrentMediaItemLive() live} and
|
||
|
* has not ended, seeks to the live edge of the current {@link MediaItem}.
|
||
|
* <li>Otherwise, does nothing.
|
||
|
* </ul>
|
||
|
*/
|
||
|
void seekToNext();
|
||
|
|
||
|
/**
|
||
|
* Attempts to set the playback parameters. Passing {@link PlaybackParameters#DEFAULT} resets the
|
||
|
* player to the default, which means there is no speed or pitch adjustment.
|
||
|
*
|
||
|
* <p>Playback parameters changes may cause the player to buffer. {@link
|
||
|
* Listener#onPlaybackParametersChanged(PlaybackParameters)} will be called whenever the currently
|
||
|
* active playback parameters change.
|
||
|
*
|
||
|
* @param playbackParameters The playback parameters.
|
||
|
*/
|
||
|
void setPlaybackParameters(PlaybackParameters playbackParameters);
|
||
|
|
||
|
/**
|
||
|
* Changes the rate at which playback occurs. The pitch is not changed.
|
||
|
*
|
||
|
* <p>This is equivalent to {@code
|
||
|
* setPlaybackParameters(getPlaybackParameters().withSpeed(speed))}.
|
||
|
*
|
||
|
* @param speed The linear factor by which playback will be sped up. Must be higher than 0. 1 is
|
||
|
* normal speed, 2 is twice as fast, 0.5 is half normal speed...
|
||
|
*/
|
||
|
void setPlaybackSpeed(@FloatRange(from = 0, fromInclusive = false) float speed);
|
||
|
|
||
|
/**
|
||
|
* Returns the currently active playback parameters.
|
||
|
*
|
||
|
* @see Listener#onPlaybackParametersChanged(PlaybackParameters)
|
||
|
*/
|
||
|
PlaybackParameters getPlaybackParameters();
|
||
|
|
||
|
/**
|
||
|
* Stops playback without resetting the playlist. Use {@link #pause()} rather than this method if
|
||
|
* the intention is to pause playback.
|
||
|
*
|
||
|
* <p>Calling this method will cause the playback state to transition to {@link #STATE_IDLE} and
|
||
|
* the player will release the loaded media and resources required for playback. The player
|
||
|
* instance can still be used by calling {@link #prepare()} again, and {@link #release()} must
|
||
|
* still be called on the player if it's no longer required.
|
||
|
*
|
||
|
* <p>Calling this method does not clear the playlist, reset the playback position or the playback
|
||
|
* error.
|
||
|
*/
|
||
|
void stop();
|
||
|
|
||
|
/**
|
||
|
* @deprecated Use {@link #stop()} and {@link #clearMediaItems()} (if {@code reset} is true) or
|
||
|
* just {@link #stop()} (if {@code reset} is false). Any player error will be cleared when
|
||
|
* {@link #prepare() re-preparing} the player.
|
||
|
*/
|
||
|
@Deprecated
|
||
|
void stop(boolean reset);
|
||
|
|
||
|
/**
|
||
|
* Releases the player. This method must be called when the player is no longer required. The
|
||
|
* player must not be used after calling this method.
|
||
|
*/
|
||
|
void release();
|
||
|
|
||
|
/**
|
||
|
* Returns the available track groups.
|
||
|
*
|
||
|
* @see Listener#onTracksChanged(TrackGroupArray, TrackSelectionArray)
|
||
|
* @deprecated Use {@link #getCurrentTracksInfo()}.
|
||
|
*/
|
||
|
@Deprecated
|
||
|
TrackGroupArray getCurrentTrackGroups();
|
||
|
|
||
|
/**
|
||
|
* Returns the current track selections.
|
||
|
*
|
||
|
* <p>A concrete implementation may include null elements if it has a fixed number of renderer
|
||
|
* components, wishes to report a TrackSelection for each of them, and has one or more renderer
|
||
|
* components that is not assigned any selected tracks.
|
||
|
*
|
||
|
* @see Listener#onTracksChanged(TrackGroupArray, TrackSelectionArray)
|
||
|
* @deprecated Use {@link #getCurrentTracksInfo()}.
|
||
|
*/
|
||
|
@Deprecated
|
||
|
TrackSelectionArray getCurrentTrackSelections();
|
||
|
|
||
|
/**
|
||
|
* Returns the available tracks, as well as the tracks' support, type, and selection status.
|
||
|
*
|
||
|
* @see Listener#onTracksChanged(TrackGroupArray, TrackSelectionArray)
|
||
|
*/
|
||
|
TracksInfo getCurrentTracksInfo();
|
||
|
|
||
|
/**
|
||
|
* Returns the parameters constraining the track selection.
|
||
|
*
|
||
|
* @see Listener#onTrackSelectionParametersChanged}
|
||
|
*/
|
||
|
TrackSelectionParameters getTrackSelectionParameters();
|
||
|
|
||
|
/**
|
||
|
* Sets the parameters constraining the track selection.
|
||
|
*
|
||
|
* <p>Unsupported parameters will be silently ignored.
|
||
|
*
|
||
|
* <p>Use {@link #getTrackSelectionParameters()} to retrieve the current parameters. For example,
|
||
|
* the following snippet restricts video to SD whilst keep other track selection parameters
|
||
|
* unchanged:
|
||
|
*
|
||
|
* <pre>{@code
|
||
|
* player.setTrackSelectionParameters(
|
||
|
* player.getTrackSelectionParameters()
|
||
|
* .buildUpon()
|
||
|
* .setMaxVideoSizeSd()
|
||
|
* .build())
|
||
|
* }</pre>
|
||
|
*/
|
||
|
void setTrackSelectionParameters(TrackSelectionParameters parameters);
|
||
|
|
||
|
/**
|
||
|
* Returns the current combined {@link MediaMetadata}, or {@link MediaMetadata#EMPTY} if not
|
||
|
* supported.
|
||
|
*
|
||
|
* <p>This {@link MediaMetadata} is a combination of the {@link MediaItem#mediaMetadata} and the
|
||
|
* static and dynamic metadata from the {@link TrackSelection#getFormat(int) track selections'
|
||
|
* formats} and {@link Listener#onMetadata(Metadata)}. If a field is populated in the {@link
|
||
|
* MediaItem#mediaMetadata}, it will be prioritised above the same field coming from static or
|
||
|
* dynamic metadata.
|
||
|
*/
|
||
|
MediaMetadata getMediaMetadata();
|
||
|
|
||
|
/**
|
||
|
* Returns the playlist {@link MediaMetadata}, as set by {@link
|
||
|
* #setPlaylistMetadata(MediaMetadata)}, or {@link MediaMetadata#EMPTY} if not supported.
|
||
|
*/
|
||
|
MediaMetadata getPlaylistMetadata();
|
||
|
|
||
|
/** Sets the playlist {@link MediaMetadata}. */
|
||
|
void setPlaylistMetadata(MediaMetadata mediaMetadata);
|
||
|
|
||
|
/**
|
||
|
* Returns the current manifest. The type depends on the type of media being played. May be null.
|
||
|
*/
|
||
|
@Nullable
|
||
|
Object getCurrentManifest();
|
||
|
|
||
|
/**
|
||
|
* Returns the current {@link Timeline}. Never null, but may be empty.
|
||
|
*
|
||
|
* @see Listener#onTimelineChanged(Timeline, int)
|
||
|
*/
|
||
|
Timeline getCurrentTimeline();
|
||
|
|
||
|
/** Returns the index of the period currently being played. */
|
||
|
int getCurrentPeriodIndex();
|
||
|
|
||
|
/** @deprecated Use {@link #getCurrentMediaItemIndex()} instead. */
|
||
|
@Deprecated
|
||
|
int getCurrentWindowIndex();
|
||
|
|
||
|
/**
|
||
|
* Returns the index of the current {@link MediaItem} in the {@link #getCurrentTimeline()
|
||
|
* timeline}, or the prospective index if the {@link #getCurrentTimeline() current timeline} is
|
||
|
* empty.
|
||
|
*/
|
||
|
int getCurrentMediaItemIndex();
|
||
|
|
||
|
/** @deprecated Use {@link #getNextMediaItemIndex()} instead. */
|
||
|
@Deprecated
|
||
|
int getNextWindowIndex();
|
||
|
|
||
|
/**
|
||
|
* Returns the index of the {@link MediaItem} that will be played if {@link
|
||
|
* #seekToNextMediaItem()} is called, which may depend on the current repeat mode and whether
|
||
|
* shuffle mode is enabled. Returns {@link C#INDEX_UNSET} if {@link #hasNextMediaItem()} is {@code
|
||
|
* false}.
|
||
|
*
|
||
|
* <p>Note: When the repeat mode is {@link #REPEAT_MODE_ONE}, this method behaves the same as when
|
||
|
* the current repeat mode is {@link #REPEAT_MODE_OFF}. See {@link #REPEAT_MODE_ONE} for more
|
||
|
* details.
|
||
|
*/
|
||
|
int getNextMediaItemIndex();
|
||
|
|
||
|
/** @deprecated Use {@link #getPreviousMediaItemIndex()} instead. */
|
||
|
@Deprecated
|
||
|
int getPreviousWindowIndex();
|
||
|
|
||
|
/**
|
||
|
* Returns the index of the {@link MediaItem} that will be played if {@link
|
||
|
* #seekToPreviousMediaItem()} is called, which may depend on the current repeat mode and whether
|
||
|
* shuffle mode is enabled. Returns {@link C#INDEX_UNSET} if {@link #hasPreviousMediaItem()} is
|
||
|
* {@code false}.
|
||
|
*
|
||
|
* <p>Note: When the repeat mode is {@link #REPEAT_MODE_ONE}, this method behaves the same as when
|
||
|
* the current repeat mode is {@link #REPEAT_MODE_OFF}. See {@link #REPEAT_MODE_ONE} for more
|
||
|
* details.
|
||
|
*/
|
||
|
int getPreviousMediaItemIndex();
|
||
|
|
||
|
/**
|
||
|
* Returns the currently playing {@link MediaItem}. May be null if the timeline is empty.
|
||
|
*
|
||
|
* @see Listener#onMediaItemTransition(MediaItem, int)
|
||
|
*/
|
||
|
@Nullable
|
||
|
MediaItem getCurrentMediaItem();
|
||
|
|
||
|
/** Returns the number of {@link MediaItem media items} in the playlist. */
|
||
|
int getMediaItemCount();
|
||
|
|
||
|
/** Returns the {@link MediaItem} at the given index. */
|
||
|
MediaItem getMediaItemAt(int index);
|
||
|
|
||
|
/**
|
||
|
* Returns the duration of the current content or ad in milliseconds, or {@link C#TIME_UNSET} if
|
||
|
* the duration is not known.
|
||
|
*/
|
||
|
long getDuration();
|
||
|
|
||
|
/**
|
||
|
* Returns the playback position in the current content or ad, in milliseconds, or the prospective
|
||
|
* position in milliseconds if the {@link #getCurrentTimeline() current timeline} is empty.
|
||
|
*/
|
||
|
long getCurrentPosition();
|
||
|
|
||
|
/**
|
||
|
* Returns an estimate of the position in the current content or ad up to which data is buffered,
|
||
|
* in milliseconds.
|
||
|
*/
|
||
|
long getBufferedPosition();
|
||
|
|
||
|
/**
|
||
|
* Returns an estimate of the percentage in the current content or ad up to which data is
|
||
|
* buffered, or 0 if no estimate is available.
|
||
|
*/
|
||
|
@IntRange(from = 0, to = 100)
|
||
|
int getBufferedPercentage();
|
||
|
|
||
|
/**
|
||
|
* Returns an estimate of the total buffered duration from the current position, in milliseconds.
|
||
|
* This includes pre-buffered data for subsequent ads and {@link MediaItem media items}.
|
||
|
*/
|
||
|
long getTotalBufferedDuration();
|
||
|
|
||
|
/** @deprecated Use {@link #isCurrentMediaItemDynamic()} instead. */
|
||
|
@Deprecated
|
||
|
boolean isCurrentWindowDynamic();
|
||
|
|
||
|
/**
|
||
|
* Returns whether the current {@link MediaItem} is dynamic (may change when the {@link Timeline}
|
||
|
* is updated), or {@code false} if the {@link Timeline} is empty.
|
||
|
*
|
||
|
* @see Timeline.Window#isDynamic
|
||
|
*/
|
||
|
boolean isCurrentMediaItemDynamic();
|
||
|
|
||
|
/** @deprecated Use {@link #isCurrentMediaItemLive()} instead. */
|
||
|
@Deprecated
|
||
|
boolean isCurrentWindowLive();
|
||
|
|
||
|
/**
|
||
|
* Returns whether the current {@link MediaItem} is live, or {@code false} if the {@link Timeline}
|
||
|
* is empty.
|
||
|
*
|
||
|
* @see Timeline.Window#isLive()
|
||
|
*/
|
||
|
boolean isCurrentMediaItemLive();
|
||
|
|
||
|
/**
|
||
|
* Returns the offset of the current playback position from the live edge in milliseconds, or
|
||
|
* {@link C#TIME_UNSET} if the current {@link MediaItem} {@link #isCurrentMediaItemLive()} isn't
|
||
|
* live} or the offset is unknown.
|
||
|
*
|
||
|
* <p>The offset is calculated as {@code currentTime - playbackPosition}, so should usually be
|
||
|
* positive.
|
||
|
*
|
||
|
* <p>Note that this offset may rely on an accurate local time, so this method may return an
|
||
|
* incorrect value if the difference between system clock and server clock is unknown.
|
||
|
*/
|
||
|
long getCurrentLiveOffset();
|
||
|
|
||
|
/** @deprecated Use {@link #isCurrentMediaItemSeekable()} instead. */
|
||
|
@Deprecated
|
||
|
boolean isCurrentWindowSeekable();
|
||
|
|
||
|
/**
|
||
|
* Returns whether the current {@link MediaItem} is seekable, or {@code false} if the {@link
|
||
|
* Timeline} is empty.
|
||
|
*
|
||
|
* @see Timeline.Window#isSeekable
|
||
|
*/
|
||
|
boolean isCurrentMediaItemSeekable();
|
||
|
|
||
|
/** Returns whether the player is currently playing an ad. */
|
||
|
boolean isPlayingAd();
|
||
|
|
||
|
/**
|
||
|
* If {@link #isPlayingAd()} returns true, returns the index of the ad group in the period
|
||
|
* currently being played. Returns {@link C#INDEX_UNSET} otherwise.
|
||
|
*/
|
||
|
int getCurrentAdGroupIndex();
|
||
|
|
||
|
/**
|
||
|
* If {@link #isPlayingAd()} returns true, returns the index of the ad in its ad group. Returns
|
||
|
* {@link C#INDEX_UNSET} otherwise.
|
||
|
*/
|
||
|
int getCurrentAdIndexInAdGroup();
|
||
|
|
||
|
/**
|
||
|
* If {@link #isPlayingAd()} returns {@code true}, returns the duration of the current content in
|
||
|
* milliseconds, or {@link C#TIME_UNSET} if the duration is not known. If there is no ad playing,
|
||
|
* the returned duration is the same as that returned by {@link #getDuration()}.
|
||
|
*/
|
||
|
long getContentDuration();
|
||
|
|
||
|
/**
|
||
|
* If {@link #isPlayingAd()} returns {@code true}, returns the content position that will be
|
||
|
* played once all ads in the ad group have finished playing, in milliseconds. If there is no ad
|
||
|
* playing, the returned position is the same as that returned by {@link #getCurrentPosition()}.
|
||
|
*/
|
||
|
long getContentPosition();
|
||
|
|
||
|
/**
|
||
|
* If {@link #isPlayingAd()} returns {@code true}, returns an estimate of the content position in
|
||
|
* the current content up to which data is buffered, in milliseconds. If there is no ad playing,
|
||
|
* the returned position is the same as that returned by {@link #getBufferedPosition()}.
|
||
|
*/
|
||
|
long getContentBufferedPosition();
|
||
|
|
||
|
/** Returns the attributes for audio playback. */
|
||
|
AudioAttributes getAudioAttributes();
|
||
|
|
||
|
/**
|
||
|
* Sets the audio volume, valid values are between 0 (silence) and 1 (unity gain, signal
|
||
|
* unchanged), inclusive.
|
||
|
*
|
||
|
* @param volume Linear output gain to apply to all audio channels.
|
||
|
*/
|
||
|
void setVolume(@FloatRange(from = 0, to = 1.0) float volume);
|
||
|
|
||
|
/**
|
||
|
* Returns the audio volume, with 0 being silence and 1 being unity gain (signal unchanged).
|
||
|
*
|
||
|
* @return The linear gain applied to all audio channels.
|
||
|
*/
|
||
|
@FloatRange(from = 0, to = 1.0)
|
||
|
float getVolume();
|
||
|
|
||
|
/**
|
||
|
* Clears any {@link Surface}, {@link SurfaceHolder}, {@link SurfaceView} or {@link TextureView}
|
||
|
* currently set on the player.
|
||
|
*/
|
||
|
void clearVideoSurface();
|
||
|
|
||
|
/**
|
||
|
* Clears the {@link Surface} onto which video is being rendered if it matches the one passed.
|
||
|
* Else does nothing.
|
||
|
*
|
||
|
* @param surface The surface to clear.
|
||
|
*/
|
||
|
void clearVideoSurface(@Nullable Surface surface);
|
||
|
|
||
|
/**
|
||
|
* Sets the {@link Surface} onto which video will be rendered. The caller is responsible for
|
||
|
* tracking the lifecycle of the surface, and must clear the surface by calling {@code
|
||
|
* setVideoSurface(null)} if the surface is destroyed.
|
||
|
*
|
||
|
* <p>If the surface is held by a {@link SurfaceView}, {@link TextureView} or {@link
|
||
|
* SurfaceHolder} then it's recommended to use {@link #setVideoSurfaceView(SurfaceView)}, {@link
|
||
|
* #setVideoTextureView(TextureView)} or {@link #setVideoSurfaceHolder(SurfaceHolder)} rather than
|
||
|
* this method, since passing the holder allows the player to track the lifecycle of the surface
|
||
|
* automatically.
|
||
|
*
|
||
|
* @param surface The {@link Surface}.
|
||
|
*/
|
||
|
void setVideoSurface(@Nullable Surface surface);
|
||
|
|
||
|
/**
|
||
|
* Sets the {@link SurfaceHolder} that holds the {@link Surface} onto which video will be
|
||
|
* rendered. The player will track the lifecycle of the surface automatically.
|
||
|
*
|
||
|
* <p>The thread that calls the {@link SurfaceHolder.Callback} methods must be the thread
|
||
|
* associated with {@link #getApplicationLooper()}.
|
||
|
*
|
||
|
* @param surfaceHolder The surface holder.
|
||
|
*/
|
||
|
void setVideoSurfaceHolder(@Nullable SurfaceHolder surfaceHolder);
|
||
|
|
||
|
/**
|
||
|
* Clears the {@link SurfaceHolder} that holds the {@link Surface} onto which video is being
|
||
|
* rendered if it matches the one passed. Else does nothing.
|
||
|
*
|
||
|
* @param surfaceHolder The surface holder to clear.
|
||
|
*/
|
||
|
void clearVideoSurfaceHolder(@Nullable SurfaceHolder surfaceHolder);
|
||
|
|
||
|
/**
|
||
|
* Sets the {@link SurfaceView} onto which video will be rendered. The player will track the
|
||
|
* lifecycle of the surface automatically.
|
||
|
*
|
||
|
* <p>The thread that calls the {@link SurfaceHolder.Callback} methods must be the thread
|
||
|
* associated with {@link #getApplicationLooper()}.
|
||
|
*
|
||
|
* @param surfaceView The surface view.
|
||
|
*/
|
||
|
void setVideoSurfaceView(@Nullable SurfaceView surfaceView);
|
||
|
|
||
|
/**
|
||
|
* Clears the {@link SurfaceView} onto which video is being rendered if it matches the one passed.
|
||
|
* Else does nothing.
|
||
|
*
|
||
|
* @param surfaceView The texture view to clear.
|
||
|
*/
|
||
|
void clearVideoSurfaceView(@Nullable SurfaceView surfaceView);
|
||
|
|
||
|
/**
|
||
|
* Sets the {@link TextureView} onto which video will be rendered. The player will track the
|
||
|
* lifecycle of the surface automatically.
|
||
|
*
|
||
|
* <p>The thread that calls the {@link TextureView.SurfaceTextureListener} methods must be the
|
||
|
* thread associated with {@link #getApplicationLooper()}.
|
||
|
*
|
||
|
* @param textureView The texture view.
|
||
|
*/
|
||
|
void setVideoTextureView(@Nullable TextureView textureView);
|
||
|
|
||
|
/**
|
||
|
* Clears the {@link TextureView} onto which video is being rendered if it matches the one passed.
|
||
|
* Else does nothing.
|
||
|
*
|
||
|
* @param textureView The texture view to clear.
|
||
|
*/
|
||
|
void clearVideoTextureView(@Nullable TextureView textureView);
|
||
|
|
||
|
/**
|
||
|
* Gets the size of the video.
|
||
|
*
|
||
|
* <p>The video's width and height are {@code 0} if there is no video or its size has not been
|
||
|
* determined yet.
|
||
|
*
|
||
|
* @see Listener#onVideoSizeChanged(VideoSize)
|
||
|
*/
|
||
|
VideoSize getVideoSize();
|
||
|
|
||
|
/** Returns the current {@link Cue Cues}. This list may be empty. */
|
||
|
List<Cue> getCurrentCues();
|
||
|
|
||
|
/** Gets the device information. */
|
||
|
DeviceInfo getDeviceInfo();
|
||
|
|
||
|
/**
|
||
|
* Gets the current volume of the device.
|
||
|
*
|
||
|
* <p>For devices with {@link DeviceInfo#PLAYBACK_TYPE_LOCAL local playback}, the volume returned
|
||
|
* by this method varies according to the current {@link C.StreamType stream type}. The stream
|
||
|
* type is determined by {@link AudioAttributes#usage} which can be converted to stream type with
|
||
|
* {@link Util#getStreamTypeForAudioUsage(int)}.
|
||
|
*
|
||
|
* <p>For devices with {@link DeviceInfo#PLAYBACK_TYPE_REMOTE remote playback}, the volume of the
|
||
|
* remote device is returned.
|
||
|
*/
|
||
|
@IntRange(from = 0)
|
||
|
int getDeviceVolume();
|
||
|
|
||
|
/** Gets whether the device is muted or not. */
|
||
|
boolean isDeviceMuted();
|
||
|
|
||
|
/**
|
||
|
* Sets the volume of the device.
|
||
|
*
|
||
|
* @param volume The volume to set.
|
||
|
*/
|
||
|
void setDeviceVolume(@IntRange(from = 0) int volume);
|
||
|
|
||
|
/** Increases the volume of the device. */
|
||
|
void increaseDeviceVolume();
|
||
|
|
||
|
/** Decreases the volume of the device. */
|
||
|
void decreaseDeviceVolume();
|
||
|
|
||
|
/** Sets the mute state of the device. */
|
||
|
void setDeviceMuted(boolean muted);
|
||
|
}
|