*** Original commit ***

Move VideoComponent in ExoPlayer

VideoFrameMetadataListener and CameraMotionListener are still part
of the Player interface as a good way to break the UI dependency
on them has not yet been finalised.

***

PiperOrigin-RevId: 369194309
This commit is contained in:
ibaker 2021-04-19 12:33:04 +01:00 committed by Oliver Woodman
parent f438955285
commit 6550ea88ea
12 changed files with 217 additions and 501 deletions

View File

@ -3,11 +3,6 @@
### dev-v2 (not yet released) ### dev-v2 (not yet released)
* Core Library: * Core Library:
* Move `Player` components to `ExoPlayer`. For example
`Player.VideoComponent` is now `ExoPlayer.VideoComponent`.
* The most used methods of `Player`'s audio/video/text/metadata components
have been added to `Player`. Support can be queried using
`Player.isCommandAvailable` instead of testing for component nullness.
* Add position info of the old and the new position as arguments to * Add position info of the old and the new position as arguments to
`EventListener.onPositionDiscontinuity`. Add the new reasons `EventListener.onPositionDiscontinuity`. Add the new reasons
`DISCONTINUITY_REASON_SKIP` and `DISCONTINUITY_REASON_REMOVE` and rename `DISCONTINUITY_REASON_SKIP` and `DISCONTINUITY_REASON_REMOVE` and rename

View File

@ -25,8 +25,8 @@ import android.os.Handler;
import android.view.Surface; import android.view.Surface;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.GlUtil; import com.google.android.exoplayer2.util.GlUtil;
import com.google.android.exoplayer2.util.TimedValueQueue; import com.google.android.exoplayer2.util.TimedValueQueue;
@ -72,7 +72,7 @@ public final class VideoProcessingGLSurfaceView extends GLSurfaceView {
@Nullable private SurfaceTexture surfaceTexture; @Nullable private SurfaceTexture surfaceTexture;
@Nullable private Surface surface; @Nullable private Surface surface;
@Nullable private ExoPlayer.VideoComponent videoComponent; @Nullable private Player.VideoComponent videoComponent;
/** /**
* Creates a new instance. Pass {@code true} for {@code requireSecureContext} if the {@link * Creates a new instance. Pass {@code true} for {@code requireSecureContext} if the {@link
@ -151,7 +151,7 @@ public final class VideoProcessingGLSurfaceView extends GLSurfaceView {
* *
* @param newVideoComponent The new video component, or {@code null} to detach this view. * @param newVideoComponent The new video component, or {@code null} to detach this view.
*/ */
public void setVideoComponent(@Nullable ExoPlayer.VideoComponent newVideoComponent) { public void setVideoComponent(@Nullable Player.VideoComponent newVideoComponent) {
if (newVideoComponent == videoComponent) { if (newVideoComponent == videoComponent) {
return; return;
} }

View File

@ -19,10 +19,6 @@ import static com.google.android.exoplayer2.util.Util.castNonNull;
import static java.lang.Math.min; import static java.lang.Math.min;
import android.os.Looper; import android.os.Looper;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.TextureView;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import com.google.android.exoplayer2.BasePlayer; import com.google.android.exoplayer2.BasePlayer;
@ -48,8 +44,6 @@ import com.google.android.exoplayer2.util.ListenerSet;
import com.google.android.exoplayer2.util.Log; import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
import com.google.android.exoplayer2.video.spherical.CameraMotionListener;
import com.google.android.gms.cast.CastStatusCodes; import com.google.android.gms.cast.CastStatusCodes;
import com.google.android.gms.cast.MediaInfo; import com.google.android.gms.cast.MediaInfo;
import com.google.android.gms.cast.MediaQueueItem; import com.google.android.gms.cast.MediaQueueItem;
@ -282,6 +276,12 @@ public final class CastPlayer extends BasePlayer {
// Player implementation. // Player implementation.
@Override
@Nullable
public VideoComponent getVideoComponent() {
return null;
}
@Override @Override
public Looper getApplicationLooper() { public Looper getApplicationLooper() {
return Looper.getMainLooper(); return Looper.getMainLooper();
@ -653,57 +653,6 @@ public final class CastPlayer extends BasePlayer {
return 1; return 1;
} }
/** This method is not supported and does nothing. */
@Override
public void setVideoFrameMetadataListener(VideoFrameMetadataListener listener) {}
/** This method is not supported and does nothing. */
@Override
public void clearVideoFrameMetadataListener(VideoFrameMetadataListener listener) {}
/** This method is not supported and does nothing. */
@Override
public void setCameraMotionListener(CameraMotionListener listener) {}
/** This method is not supported and does nothing. */
@Override
public void clearCameraMotionListener(CameraMotionListener listener) {}
/** This method is not supported and does nothing. */
@Override
public void clearVideoSurface() {}
/** This method is not supported and does nothing. */
@Override
public void clearVideoSurface(@Nullable Surface surface) {}
/** This method is not supported and does nothing. */
@Override
public void setVideoSurface(@Nullable Surface surface) {}
/** This method is not supported and does nothing. */
@Override
public void setVideoSurfaceHolder(@Nullable SurfaceHolder surfaceHolder) {}
/** This method is not supported and does nothing. */
@Override
public void clearVideoSurfaceHolder(@Nullable SurfaceHolder surfaceHolder) {}
/** This method is not supported and does nothing. */
@Override
public void setVideoSurfaceView(@Nullable SurfaceView surfaceView) {}
/** This method is not supported and does nothing. */
@Override
public void clearVideoSurfaceView(@Nullable SurfaceView surfaceView) {}
/** This method is not supported and does nothing. */
@Override
public void setVideoTextureView(@Nullable TextureView textureView) {}
/** This method is not supported and does nothing. */
@Override
public void clearVideoTextureView(@Nullable TextureView textureView) {}
/** This method is not supported and returns an empty list. */ /** This method is not supported and returns an empty list. */
@Override @Override
public ImmutableList<Cue> getCurrentCues() { public ImmutableList<Cue> getCurrentCues() {

View File

@ -37,6 +37,7 @@ import com.google.android.exoplayer2.Player.TimelineChangeReason;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.util.ErrorMessageProvider; import com.google.android.exoplayer2.util.ErrorMessageProvider;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.VideoListener;
/** Leanback {@code PlayerAdapter} implementation for {@link Player}. */ /** Leanback {@code PlayerAdapter} implementation for {@link Player}. */
public final class LeanbackPlayerAdapter extends PlayerAdapter implements Runnable { public final class LeanbackPlayerAdapter extends PlayerAdapter implements Runnable {
@ -48,7 +49,7 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter implements Runnab
private final Context context; private final Context context;
private final Player player; private final Player player;
private final Handler handler; private final Handler handler;
private final PlayerListener playerListener; private final ComponentListener componentListener;
private final int updatePeriodMs; private final int updatePeriodMs;
@Nullable private PlaybackPreparer playbackPreparer; @Nullable private PlaybackPreparer playbackPreparer;
@ -72,7 +73,7 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter implements Runnab
this.player = player; this.player = player;
this.updatePeriodMs = updatePeriodMs; this.updatePeriodMs = updatePeriodMs;
handler = Util.createHandlerForCurrentOrMainLooper(); handler = Util.createHandlerForCurrentOrMainLooper();
playerListener = new PlayerListener(); componentListener = new ComponentListener();
controlDispatcher = new DefaultControlDispatcher(); controlDispatcher = new DefaultControlDispatcher();
} }
@ -117,15 +118,23 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter implements Runnab
public void onAttachedToHost(PlaybackGlueHost host) { public void onAttachedToHost(PlaybackGlueHost host) {
if (host instanceof SurfaceHolderGlueHost) { if (host instanceof SurfaceHolderGlueHost) {
surfaceHolderGlueHost = ((SurfaceHolderGlueHost) host); surfaceHolderGlueHost = ((SurfaceHolderGlueHost) host);
surfaceHolderGlueHost.setSurfaceHolderCallback(playerListener); surfaceHolderGlueHost.setSurfaceHolderCallback(componentListener);
} }
notifyStateChanged(); notifyStateChanged();
player.addListener(playerListener); player.addListener(componentListener);
Player.VideoComponent videoComponent = player.getVideoComponent();
if (videoComponent != null) {
videoComponent.addVideoListener(componentListener);
}
} }
@Override @Override
public void onDetachedFromHost() { public void onDetachedFromHost() {
player.removeListener(playerListener); player.removeListener(componentListener);
Player.VideoComponent videoComponent = player.getVideoComponent();
if (videoComponent != null) {
videoComponent.removeVideoListener(componentListener);
}
if (surfaceHolderGlueHost != null) { if (surfaceHolderGlueHost != null) {
removeSurfaceHolderCallback(surfaceHolderGlueHost); removeSurfaceHolderCallback(surfaceHolderGlueHost);
surfaceHolderGlueHost = null; surfaceHolderGlueHost = null;
@ -218,7 +227,10 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter implements Runnab
/* package */ void setVideoSurface(@Nullable Surface surface) { /* package */ void setVideoSurface(@Nullable Surface surface) {
hasSurface = surface != null; hasSurface = surface != null;
player.setVideoSurface(surface); Player.VideoComponent videoComponent = player.getVideoComponent();
if (videoComponent != null) {
videoComponent.setVideoSurface(surface);
}
maybeNotifyPreparedStateChanged(getCallback()); maybeNotifyPreparedStateChanged(getCallback());
} }
@ -246,7 +258,8 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter implements Runnab
surfaceHolderGlueHost.setSurfaceHolderCallback(null); surfaceHolderGlueHost.setSurfaceHolderCallback(null);
} }
private final class PlayerListener implements Player.Listener, SurfaceHolder.Callback { private final class ComponentListener
implements Player.EventListener, SurfaceHolder.Callback, VideoListener {
// SurfaceHolder.Callback implementation. // SurfaceHolder.Callback implementation.

View File

@ -67,6 +67,146 @@ import java.util.List;
*/ */
public interface Player { public interface Player {
/** The video component of a {@link Player}. */
interface VideoComponent {
/**
* Sets the {@link C.VideoScalingMode}.
*
* @param videoScalingMode The {@link C.VideoScalingMode}.
*/
void setVideoScalingMode(@C.VideoScalingMode int videoScalingMode);
/** Returns the {@link C.VideoScalingMode}. */
@C.VideoScalingMode
int getVideoScalingMode();
/**
* Adds a listener to receive video events.
*
* @param listener The listener to register.
*/
void addVideoListener(VideoListener listener);
/**
* Removes a listener of video events.
*
* @param listener The listener to unregister.
*/
void removeVideoListener(VideoListener listener);
/**
* Sets a listener to receive video frame metadata events.
*
* <p>This method is intended to be called by the same component that sets the {@link Surface}
* onto which video will be rendered. If using ExoPlayer's standard UI components, this method
* should not be called directly from application code.
*
* @param listener The listener.
*/
void setVideoFrameMetadataListener(VideoFrameMetadataListener listener);
/**
* Clears the listener which receives video frame metadata events if it matches the one passed.
* Else does nothing.
*
* @param listener The listener to clear.
*/
void clearVideoFrameMetadataListener(VideoFrameMetadataListener listener);
/**
* Sets a listener of camera motion events.
*
* @param listener The listener.
*/
void setCameraMotionListener(CameraMotionListener listener);
/**
* Clears the listener which receives camera motion events if it matches the one passed. Else
* does nothing.
*
* @param listener The listener to clear.
*/
void clearCameraMotionListener(CameraMotionListener listener);
/**
* 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.
*
* @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.
*
* @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.
*
* @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);
}
/** /**
* Listener of changes in player state. * Listener of changes in player state.
* *
@ -1012,6 +1152,10 @@ public interface Player {
/** Command to get the text that should currently be displayed by the player. */ /** Command to get the text that should currently be displayed by the player. */
int COMMAND_GET_TEXT = 22; int COMMAND_GET_TEXT = 22;
/** Returns the component of this player for video output, or null if video is not supported. */
@Nullable
VideoComponent getVideoComponent();
/** /**
* Returns the {@link Looper} associated with the application thread that's used to access the * Returns the {@link Looper} associated with the application thread that's used to access the
* player and on which player events are received. * player and on which player events are received.
@ -1686,117 +1830,6 @@ public interface Player {
*/ */
float getVolume(); float getVolume();
/**
* Sets a listener to receive video frame metadata events.
*
* <p>This method is intended to be called by the same component that sets the {@link Surface}
* onto which video will be rendered. If using ExoPlayer's standard UI components, this method
* should not be called directly from application code.
*
* @param listener The listener.
*/
void setVideoFrameMetadataListener(VideoFrameMetadataListener listener);
/**
* Clears the listener which receives video frame metadata events if it matches the one passed.
* Else does nothing.
*
* @param listener The listener to clear.
*/
void clearVideoFrameMetadataListener(VideoFrameMetadataListener listener);
/**
* Sets a listener of camera motion events.
*
* @param listener The listener.
*/
void setCameraMotionListener(CameraMotionListener listener);
/**
* Clears the listener which receives camera motion events if it matches the one passed. Else does
* nothing.
*
* @param listener The listener to clear.
*/
void clearCameraMotionListener(CameraMotionListener listener);
/**
* 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.
*
* @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.
*
* @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.
*
* @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);
/** Returns the current {@link Cue Cues}. This list may be empty. */ /** Returns the current {@link Cue Cues}. This list may be empty. */
List<Cue> getCurrentCues(); List<Cue> getCurrentCues();

View File

@ -18,10 +18,6 @@ package com.google.android.exoplayer2;
import android.content.Context; import android.content.Context;
import android.media.AudioTrack; import android.media.AudioTrack;
import android.os.Looper; import android.os.Looper;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.TextureView;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import com.google.android.exoplayer2.analytics.AnalyticsCollector; import com.google.android.exoplayer2.analytics.AnalyticsCollector;
@ -52,9 +48,6 @@ import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Clock; import com.google.android.exoplayer2.util.Clock;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.MediaCodecVideoRenderer; import com.google.android.exoplayer2.video.MediaCodecVideoRenderer;
import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
import com.google.android.exoplayer2.video.VideoListener;
import com.google.android.exoplayer2.video.spherical.CameraMotionListener;
import java.util.List; import java.util.List;
/** /**
@ -230,146 +223,6 @@ public interface ExoPlayer extends Player {
boolean getSkipSilenceEnabled(); boolean getSkipSilenceEnabled();
} }
/** The video component of an {@link ExoPlayer}. */
interface VideoComponent {
/**
* Sets the {@link C.VideoScalingMode}.
*
* @param videoScalingMode The {@link C.VideoScalingMode}.
*/
void setVideoScalingMode(@C.VideoScalingMode int videoScalingMode);
/** Returns the {@link C.VideoScalingMode}. */
@C.VideoScalingMode
int getVideoScalingMode();
/**
* Adds a listener to receive video events.
*
* @param listener The listener to register.
*/
void addVideoListener(VideoListener listener);
/**
* Removes a listener of video events.
*
* @param listener The listener to unregister.
*/
void removeVideoListener(VideoListener listener);
/**
* Sets a listener to receive video frame metadata events.
*
* <p>This method is intended to be called by the same component that sets the {@link Surface}
* onto which video will be rendered. If using ExoPlayer's standard UI components, this method
* should not be called directly from application code.
*
* @param listener The listener.
*/
void setVideoFrameMetadataListener(VideoFrameMetadataListener listener);
/**
* Clears the listener which receives video frame metadata events if it matches the one passed.
* Else does nothing.
*
* @param listener The listener to clear.
*/
void clearVideoFrameMetadataListener(VideoFrameMetadataListener listener);
/**
* Sets a listener of camera motion events.
*
* @param listener The listener.
*/
void setCameraMotionListener(CameraMotionListener listener);
/**
* Clears the listener which receives camera motion events if it matches the one passed. Else
* does nothing.
*
* @param listener The listener to clear.
*/
void clearCameraMotionListener(CameraMotionListener listener);
/**
* 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.
*
* @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.
*
* @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.
*
* @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);
}
/** The text component of an {@link ExoPlayer}. */ /** The text component of an {@link ExoPlayer}. */
interface TextComponent { interface TextComponent {
@ -798,10 +651,6 @@ public interface ExoPlayer extends Player {
@Nullable @Nullable
AudioComponent getAudioComponent(); AudioComponent getAudioComponent();
/** Returns the component of this player for video output, or null if video is not supported. */
@Nullable
VideoComponent getVideoComponent();
/** Returns the component of this player for text output, or null if text is not supported. */ /** Returns the component of this player for text output, or null if text is not supported. */
@Nullable @Nullable
TextComponent getTextComponent(); TextComponent getTextComponent();

View File

@ -25,10 +25,6 @@ import android.annotation.SuppressLint;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.util.Pair; import android.util.Pair;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.TextureView;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.PlayerMessage.Target; import com.google.android.exoplayer2.PlayerMessage.Target;
import com.google.android.exoplayer2.analytics.AnalyticsCollector; import com.google.android.exoplayer2.analytics.AnalyticsCollector;
@ -52,8 +48,6 @@ import com.google.android.exoplayer2.util.HandlerWrapper;
import com.google.android.exoplayer2.util.ListenerSet; import com.google.android.exoplayer2.util.ListenerSet;
import com.google.android.exoplayer2.util.Log; import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
import com.google.android.exoplayer2.video.spherical.CameraMotionListener;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -1010,58 +1004,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
return 1; return 1;
} }
/** This method is not supported and does nothing. */
@Override
public void setVideoFrameMetadataListener(VideoFrameMetadataListener listener) {}
/** This method is not supported and does nothing. */
@Override
public void clearVideoFrameMetadataListener(VideoFrameMetadataListener listener) {}
/** This method is not supported and does nothing. */
@Override
public void setCameraMotionListener(CameraMotionListener listener) {}
/** This method is not supported and does nothing. */
@Override
public void clearCameraMotionListener(CameraMotionListener listener) {}
/** This method is not supported and does nothing. */
@Override
public void clearVideoSurface() {}
/** This method is not supported and does nothing. */
@Override
public void clearVideoSurface(@Nullable Surface surface) {}
/** This method is not supported and does nothing. */
@Override
public void setVideoSurface(@Nullable Surface surface) {}
/** This method is not supported and does nothing. */
@Override
public void setVideoSurfaceHolder(@Nullable SurfaceHolder surfaceHolder) {}
/** This method is not supported and does nothing. */
@Override
public void clearVideoSurfaceHolder(@Nullable SurfaceHolder surfaceHolder) {}
/** This method is not supported and does nothing. */
@Override
public void setVideoSurfaceView(@Nullable SurfaceView surfaceView) {}
/** This method is not supported and does nothing. */
@Override
public void clearVideoSurfaceView(@Nullable SurfaceView surfaceView) {}
/** This method is not supported and does nothing. */
@Override
public void setVideoTextureView(@Nullable TextureView textureView) {}
/** This method is not supported and does nothing. */
@Override
public void clearVideoTextureView(@Nullable TextureView textureView) {}
/** This method is not supported and returns an empty list. */ /** This method is not supported and returns an empty list. */
@Override @Override
public ImmutableList<Cue> getCurrentCues() { public ImmutableList<Cue> getCurrentCues() {

View File

@ -79,7 +79,7 @@ import java.util.concurrent.TimeoutException;
public class SimpleExoPlayer extends BasePlayer public class SimpleExoPlayer extends BasePlayer
implements ExoPlayer, implements ExoPlayer,
ExoPlayer.AudioComponent, ExoPlayer.AudioComponent,
ExoPlayer.VideoComponent, Player.VideoComponent,
ExoPlayer.TextComponent, ExoPlayer.TextComponent,
ExoPlayer.MetadataComponent, ExoPlayer.MetadataComponent,
ExoPlayer.DeviceComponent { ExoPlayer.DeviceComponent {

View File

@ -16,7 +16,6 @@
package com.google.android.exoplayer2.ui; package com.google.android.exoplayer2.ui;
import static com.google.android.exoplayer2.Player.COMMAND_GET_TEXT; import static com.google.android.exoplayer2.Player.COMMAND_GET_TEXT;
import static com.google.android.exoplayer2.Player.COMMAND_SET_VIDEO_SURFACE;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
@ -564,13 +563,14 @@ public class PlayerView extends FrameLayout implements AdViewProvider {
@Nullable Player oldPlayer = this.player; @Nullable Player oldPlayer = this.player;
if (oldPlayer != null) { if (oldPlayer != null) {
oldPlayer.removeListener(componentListener); oldPlayer.removeListener(componentListener);
if (oldPlayer.isCommandAvailable(COMMAND_SET_VIDEO_SURFACE)) { @Nullable Player.VideoComponent oldVideoComponent = oldPlayer.getVideoComponent();
if (oldVideoComponent != null) {
if (surfaceView instanceof TextureView) { if (surfaceView instanceof TextureView) {
oldPlayer.clearVideoTextureView((TextureView) surfaceView); oldVideoComponent.clearVideoTextureView((TextureView) surfaceView);
} else if (surfaceView instanceof SphericalGLSurfaceView) { } else if (surfaceView instanceof SphericalGLSurfaceView) {
((SphericalGLSurfaceView) surfaceView).setPlayer(null); ((SphericalGLSurfaceView) surfaceView).setVideoComponent(null);
} else if (surfaceView instanceof SurfaceView) { } else if (surfaceView instanceof SurfaceView) {
oldPlayer.clearVideoSurfaceView((SurfaceView) surfaceView); oldVideoComponent.clearVideoSurfaceView((SurfaceView) surfaceView);
} }
} }
} }
@ -585,14 +585,16 @@ public class PlayerView extends FrameLayout implements AdViewProvider {
updateErrorMessage(); updateErrorMessage();
updateForCurrentTrackSelections(/* isNewPlayer= */ true); updateForCurrentTrackSelections(/* isNewPlayer= */ true);
if (player != null) { if (player != null) {
if (player.isCommandAvailable(COMMAND_SET_VIDEO_SURFACE)) { @Nullable Player.VideoComponent newVideoComponent = player.getVideoComponent();
if (newVideoComponent != null) {
if (surfaceView instanceof TextureView) { if (surfaceView instanceof TextureView) {
player.setVideoTextureView((TextureView) surfaceView); newVideoComponent.setVideoTextureView((TextureView) surfaceView);
} else if (surfaceView instanceof SphericalGLSurfaceView) { } else if (surfaceView instanceof SphericalGLSurfaceView) {
((SphericalGLSurfaceView) surfaceView).setPlayer(player); ((SphericalGLSurfaceView) surfaceView).setVideoComponent(newVideoComponent);
} else if (surfaceView instanceof SurfaceView) { } else if (surfaceView instanceof SurfaceView) {
player.setVideoSurfaceView((SurfaceView) surfaceView); newVideoComponent.setVideoSurfaceView((SurfaceView) surfaceView);
} }
newVideoComponent.addVideoListener(componentListener);
} }
if (subtitleView != null && player.isCommandAvailable(COMMAND_GET_TEXT)) { if (subtitleView != null && player.isCommandAvailable(COMMAND_GET_TEXT)) {
subtitleView.setCues(player.getCurrentCues()); subtitleView.setCues(player.getCurrentCues());

View File

@ -16,7 +16,6 @@
package com.google.android.exoplayer2.ui; package com.google.android.exoplayer2.ui;
import static com.google.android.exoplayer2.Player.COMMAND_GET_TEXT; import static com.google.android.exoplayer2.Player.COMMAND_GET_TEXT;
import static com.google.android.exoplayer2.Player.COMMAND_SET_VIDEO_SURFACE;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull; import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
@ -573,12 +572,15 @@ public class StyledPlayerView extends FrameLayout implements AdViewProvider {
@Nullable Player oldPlayer = this.player; @Nullable Player oldPlayer = this.player;
if (oldPlayer != null) { if (oldPlayer != null) {
oldPlayer.removeListener(componentListener); oldPlayer.removeListener(componentListener);
@Nullable Player.VideoComponent oldVideoComponent = oldPlayer.getVideoComponent();
if (oldVideoComponent != null) {
if (surfaceView instanceof TextureView) { if (surfaceView instanceof TextureView) {
oldPlayer.clearVideoTextureView((TextureView) surfaceView); oldVideoComponent.clearVideoTextureView((TextureView) surfaceView);
} else if (surfaceView instanceof SphericalGLSurfaceView) { } else if (surfaceView instanceof SphericalGLSurfaceView) {
((SphericalGLSurfaceView) surfaceView).setPlayer(null); ((SphericalGLSurfaceView) surfaceView).setVideoComponent(null);
} else if (surfaceView instanceof SurfaceView) { } else if (surfaceView instanceof SurfaceView) {
oldPlayer.clearVideoSurfaceView((SurfaceView) surfaceView); oldVideoComponent.clearVideoSurfaceView((SurfaceView) surfaceView);
}
} }
} }
if (subtitleView != null) { if (subtitleView != null) {
@ -592,14 +594,16 @@ public class StyledPlayerView extends FrameLayout implements AdViewProvider {
updateErrorMessage(); updateErrorMessage();
updateForCurrentTrackSelections(/* isNewPlayer= */ true); updateForCurrentTrackSelections(/* isNewPlayer= */ true);
if (player != null) { if (player != null) {
if (player.isCommandAvailable(COMMAND_SET_VIDEO_SURFACE)) { @Nullable Player.VideoComponent newVideoComponent = player.getVideoComponent();
if (newVideoComponent != null) {
if (surfaceView instanceof TextureView) { if (surfaceView instanceof TextureView) {
player.setVideoTextureView((TextureView) surfaceView); newVideoComponent.setVideoTextureView((TextureView) surfaceView);
} else if (surfaceView instanceof SphericalGLSurfaceView) { } else if (surfaceView instanceof SphericalGLSurfaceView) {
((SphericalGLSurfaceView) surfaceView).setPlayer(player); ((SphericalGLSurfaceView) surfaceView).setVideoComponent(newVideoComponent);
} else if (surfaceView instanceof SurfaceView) { } else if (surfaceView instanceof SurfaceView) {
player.setVideoSurfaceView((SurfaceView) surfaceView); newVideoComponent.setVideoSurfaceView((SurfaceView) surfaceView);
} }
newVideoComponent.addVideoListener(componentListener);
} }
if (subtitleView != null && player.isCommandAvailable(COMMAND_GET_TEXT)) { if (subtitleView != null && player.isCommandAvailable(COMMAND_GET_TEXT)) {
subtitleView.setCues(player.getCurrentCues()); subtitleView.setCues(player.getCurrentCues());

View File

@ -72,7 +72,7 @@ public final class SphericalGLSurfaceView extends GLSurfaceView {
private final SceneRenderer scene; private final SceneRenderer scene;
@Nullable private SurfaceTexture surfaceTexture; @Nullable private SurfaceTexture surfaceTexture;
@Nullable private Surface surface; @Nullable private Surface surface;
@Nullable private Player player; @Nullable private Player.VideoComponent videoComponent;
private boolean useSensorRotation; private boolean useSensorRotation;
private boolean isStarted; private boolean isStarted;
private boolean isOrientationListenerRegistered; private boolean isOrientationListenerRegistered;
@ -125,23 +125,23 @@ public final class SphericalGLSurfaceView extends GLSurfaceView {
scene.setDefaultStereoMode(stereoMode); scene.setDefaultStereoMode(stereoMode);
} }
/** Sets the {@link Player} to use. */ /** Sets the {@link Player.VideoComponent} to use. */
public void setPlayer(@Nullable Player newPlayer) { public void setVideoComponent(@Nullable Player.VideoComponent newVideoComponent) {
if (newPlayer == player) { if (newVideoComponent == videoComponent) {
return; return;
} }
if (player != null) { if (videoComponent != null) {
if (surface != null) { if (surface != null) {
player.clearVideoSurface(surface); videoComponent.clearVideoSurface(surface);
} }
player.clearVideoFrameMetadataListener(scene); videoComponent.clearVideoFrameMetadataListener(scene);
player.clearCameraMotionListener(scene); videoComponent.clearCameraMotionListener(scene);
} }
player = newPlayer; videoComponent = newVideoComponent;
if (this.player != null) { if (videoComponent != null) {
player.setVideoFrameMetadataListener(scene); videoComponent.setVideoFrameMetadataListener(scene);
player.setCameraMotionListener(scene); videoComponent.setCameraMotionListener(scene);
player.setVideoSurface(surface); videoComponent.setVideoSurface(surface);
} }
} }
@ -174,8 +174,8 @@ public final class SphericalGLSurfaceView extends GLSurfaceView {
mainHandler.post( mainHandler.post(
() -> { () -> {
if (surface != null) { if (surface != null) {
if (player != null) { if (videoComponent != null) {
player.clearVideoSurface(surface); videoComponent.clearVideoSurface(surface);
} }
releaseSurface(surfaceTexture, surface); releaseSurface(surfaceTexture, surface);
surfaceTexture = null; surfaceTexture = null;
@ -206,8 +206,8 @@ public final class SphericalGLSurfaceView extends GLSurfaceView {
Surface oldSurface = this.surface; Surface oldSurface = this.surface;
this.surfaceTexture = surfaceTexture; this.surfaceTexture = surfaceTexture;
this.surface = new Surface(surfaceTexture); this.surface = new Surface(surfaceTexture);
if (player != null) { if (videoComponent != null) {
player.setVideoSurface(surface); videoComponent.setVideoSurface(surface);
} }
releaseSurface(oldSurfaceTexture, oldSurface); releaseSurface(oldSurfaceTexture, oldSurface);
}); });

View File

@ -16,10 +16,6 @@
package com.google.android.exoplayer2.testutil; package com.google.android.exoplayer2.testutil;
import android.os.Looper; import android.os.Looper;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.TextureView;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.BasePlayer; import com.google.android.exoplayer2.BasePlayer;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
@ -41,8 +37,6 @@ import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray; import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelector; import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.util.Clock; import com.google.android.exoplayer2.util.Clock;
import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
import com.google.android.exoplayer2.video.spherical.CameraMotionListener;
import java.util.List; import java.util.List;
/** /**
@ -446,71 +440,6 @@ public class StubExoPlayer extends BasePlayer implements ExoPlayer {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
public void setVideoFrameMetadataListener(VideoFrameMetadataListener listener) {
throw new UnsupportedOperationException();
}
@Override
public void clearVideoFrameMetadataListener(VideoFrameMetadataListener listener) {
throw new UnsupportedOperationException();
}
@Override
public void setCameraMotionListener(CameraMotionListener listener) {
throw new UnsupportedOperationException();
}
@Override
public void clearCameraMotionListener(CameraMotionListener listener) {
throw new UnsupportedOperationException();
}
@Override
public void clearVideoSurface() {
throw new UnsupportedOperationException();
}
@Override
public void clearVideoSurface(@Nullable Surface surface) {
throw new UnsupportedOperationException();
}
@Override
public void setVideoSurface(@Nullable Surface surface) {
throw new UnsupportedOperationException();
}
@Override
public void setVideoSurfaceHolder(@Nullable SurfaceHolder surfaceHolder) {
throw new UnsupportedOperationException();
}
@Override
public void clearVideoSurfaceHolder(@Nullable SurfaceHolder surfaceHolder) {
throw new UnsupportedOperationException();
}
@Override
public void setVideoSurfaceView(@Nullable SurfaceView surfaceView) {
throw new UnsupportedOperationException();
}
@Override
public void clearVideoSurfaceView(@Nullable SurfaceView surfaceView) {
throw new UnsupportedOperationException();
}
@Override
public void setVideoTextureView(@Nullable TextureView textureView) {
throw new UnsupportedOperationException();
}
@Override
public void clearVideoTextureView(@Nullable TextureView textureView) {
throw new UnsupportedOperationException();
}
@Override @Override
public List<Cue> getCurrentCues() { public List<Cue> getCurrentCues() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();