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: 368863829
This commit is contained in:
parent
a6e9a9c6d2
commit
cdebf6c68b
@ -3,6 +3,11 @@
|
|||||||
### 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
|
||||||
|
@ -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 Player.VideoComponent videoComponent;
|
@Nullable private ExoPlayer.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 Player.VideoComponent newVideoComponent) {
|
public void setVideoComponent(@Nullable ExoPlayer.VideoComponent newVideoComponent) {
|
||||||
if (newVideoComponent == videoComponent) {
|
if (newVideoComponent == videoComponent) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,10 @@ 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;
|
||||||
@ -44,6 +48,8 @@ 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;
|
||||||
@ -276,12 +282,6 @@ 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,6 +653,57 @@ 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() {
|
||||||
|
@ -37,7 +37,6 @@ 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 {
|
||||||
@ -49,7 +48,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 ComponentListener componentListener;
|
private final PlayerListener playerListener;
|
||||||
private final int updatePeriodMs;
|
private final int updatePeriodMs;
|
||||||
|
|
||||||
@Nullable private PlaybackPreparer playbackPreparer;
|
@Nullable private PlaybackPreparer playbackPreparer;
|
||||||
@ -73,7 +72,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();
|
||||||
componentListener = new ComponentListener();
|
playerListener = new PlayerListener();
|
||||||
controlDispatcher = new DefaultControlDispatcher();
|
controlDispatcher = new DefaultControlDispatcher();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,23 +117,15 @@ 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(componentListener);
|
surfaceHolderGlueHost.setSurfaceHolderCallback(playerListener);
|
||||||
}
|
}
|
||||||
notifyStateChanged();
|
notifyStateChanged();
|
||||||
player.addListener(componentListener);
|
player.addListener(playerListener);
|
||||||
Player.VideoComponent videoComponent = player.getVideoComponent();
|
|
||||||
if (videoComponent != null) {
|
|
||||||
videoComponent.addVideoListener(componentListener);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDetachedFromHost() {
|
public void onDetachedFromHost() {
|
||||||
player.removeListener(componentListener);
|
player.removeListener(playerListener);
|
||||||
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;
|
||||||
@ -227,10 +218,7 @@ 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.VideoComponent videoComponent = player.getVideoComponent();
|
player.setVideoSurface(surface);
|
||||||
if (videoComponent != null) {
|
|
||||||
videoComponent.setVideoSurface(surface);
|
|
||||||
}
|
|
||||||
maybeNotifyPreparedStateChanged(getCallback());
|
maybeNotifyPreparedStateChanged(getCallback());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,8 +246,7 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter implements Runnab
|
|||||||
surfaceHolderGlueHost.setSurfaceHolderCallback(null);
|
surfaceHolderGlueHost.setSurfaceHolderCallback(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class ComponentListener
|
private final class PlayerListener implements Player.Listener, SurfaceHolder.Callback {
|
||||||
implements Player.EventListener, SurfaceHolder.Callback, VideoListener {
|
|
||||||
|
|
||||||
// SurfaceHolder.Callback implementation.
|
// SurfaceHolder.Callback implementation.
|
||||||
|
|
||||||
|
@ -67,146 +67,6 @@ 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.
|
||||||
*
|
*
|
||||||
@ -1152,10 +1012,6 @@ 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.
|
||||||
@ -1830,6 +1686,117 @@ 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();
|
||||||
|
|
||||||
|
@ -18,6 +18,10 @@ 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;
|
||||||
@ -48,6 +52,9 @@ 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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -223,6 +230,146 @@ 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 {
|
||||||
|
|
||||||
@ -651,6 +798,10 @@ 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();
|
||||||
|
@ -25,6 +25,10 @@ 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;
|
||||||
@ -48,6 +52,8 @@ 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;
|
||||||
@ -1004,6 +1010,58 @@ 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() {
|
||||||
|
@ -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,
|
||||||
Player.VideoComponent,
|
ExoPlayer.VideoComponent,
|
||||||
ExoPlayer.TextComponent,
|
ExoPlayer.TextComponent,
|
||||||
ExoPlayer.MetadataComponent,
|
ExoPlayer.MetadataComponent,
|
||||||
ExoPlayer.DeviceComponent {
|
ExoPlayer.DeviceComponent {
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
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;
|
||||||
@ -563,14 +564,13 @@ 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);
|
||||||
@Nullable Player.VideoComponent oldVideoComponent = oldPlayer.getVideoComponent();
|
if (oldPlayer.isCommandAvailable(COMMAND_SET_VIDEO_SURFACE)) {
|
||||||
if (oldVideoComponent != null) {
|
|
||||||
if (surfaceView instanceof TextureView) {
|
if (surfaceView instanceof TextureView) {
|
||||||
oldVideoComponent.clearVideoTextureView((TextureView) surfaceView);
|
oldPlayer.clearVideoTextureView((TextureView) surfaceView);
|
||||||
} else if (surfaceView instanceof SphericalGLSurfaceView) {
|
} else if (surfaceView instanceof SphericalGLSurfaceView) {
|
||||||
((SphericalGLSurfaceView) surfaceView).setVideoComponent(null);
|
((SphericalGLSurfaceView) surfaceView).setPlayer(null);
|
||||||
} else if (surfaceView instanceof SurfaceView) {
|
} else if (surfaceView instanceof SurfaceView) {
|
||||||
oldVideoComponent.clearVideoSurfaceView((SurfaceView) surfaceView);
|
oldPlayer.clearVideoSurfaceView((SurfaceView) surfaceView);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -585,16 +585,14 @@ public class PlayerView extends FrameLayout implements AdViewProvider {
|
|||||||
updateErrorMessage();
|
updateErrorMessage();
|
||||||
updateForCurrentTrackSelections(/* isNewPlayer= */ true);
|
updateForCurrentTrackSelections(/* isNewPlayer= */ true);
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
@Nullable Player.VideoComponent newVideoComponent = player.getVideoComponent();
|
if (player.isCommandAvailable(COMMAND_SET_VIDEO_SURFACE)) {
|
||||||
if (newVideoComponent != null) {
|
|
||||||
if (surfaceView instanceof TextureView) {
|
if (surfaceView instanceof TextureView) {
|
||||||
newVideoComponent.setVideoTextureView((TextureView) surfaceView);
|
player.setVideoTextureView((TextureView) surfaceView);
|
||||||
} else if (surfaceView instanceof SphericalGLSurfaceView) {
|
} else if (surfaceView instanceof SphericalGLSurfaceView) {
|
||||||
((SphericalGLSurfaceView) surfaceView).setVideoComponent(newVideoComponent);
|
((SphericalGLSurfaceView) surfaceView).setPlayer(player);
|
||||||
} else if (surfaceView instanceof SurfaceView) {
|
} else if (surfaceView instanceof SurfaceView) {
|
||||||
newVideoComponent.setVideoSurfaceView((SurfaceView) surfaceView);
|
player.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());
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
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;
|
||||||
@ -572,15 +573,12 @@ 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) {
|
||||||
oldVideoComponent.clearVideoTextureView((TextureView) surfaceView);
|
oldPlayer.clearVideoTextureView((TextureView) surfaceView);
|
||||||
} else if (surfaceView instanceof SphericalGLSurfaceView) {
|
} else if (surfaceView instanceof SphericalGLSurfaceView) {
|
||||||
((SphericalGLSurfaceView) surfaceView).setVideoComponent(null);
|
((SphericalGLSurfaceView) surfaceView).setPlayer(null);
|
||||||
} else if (surfaceView instanceof SurfaceView) {
|
} else if (surfaceView instanceof SurfaceView) {
|
||||||
oldVideoComponent.clearVideoSurfaceView((SurfaceView) surfaceView);
|
oldPlayer.clearVideoSurfaceView((SurfaceView) surfaceView);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (subtitleView != null) {
|
if (subtitleView != null) {
|
||||||
@ -594,16 +592,14 @@ public class StyledPlayerView extends FrameLayout implements AdViewProvider {
|
|||||||
updateErrorMessage();
|
updateErrorMessage();
|
||||||
updateForCurrentTrackSelections(/* isNewPlayer= */ true);
|
updateForCurrentTrackSelections(/* isNewPlayer= */ true);
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
@Nullable Player.VideoComponent newVideoComponent = player.getVideoComponent();
|
if (player.isCommandAvailable(COMMAND_SET_VIDEO_SURFACE)) {
|
||||||
if (newVideoComponent != null) {
|
|
||||||
if (surfaceView instanceof TextureView) {
|
if (surfaceView instanceof TextureView) {
|
||||||
newVideoComponent.setVideoTextureView((TextureView) surfaceView);
|
player.setVideoTextureView((TextureView) surfaceView);
|
||||||
} else if (surfaceView instanceof SphericalGLSurfaceView) {
|
} else if (surfaceView instanceof SphericalGLSurfaceView) {
|
||||||
((SphericalGLSurfaceView) surfaceView).setVideoComponent(newVideoComponent);
|
((SphericalGLSurfaceView) surfaceView).setPlayer(player);
|
||||||
} else if (surfaceView instanceof SurfaceView) {
|
} else if (surfaceView instanceof SurfaceView) {
|
||||||
newVideoComponent.setVideoSurfaceView((SurfaceView) surfaceView);
|
player.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());
|
||||||
|
@ -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.VideoComponent videoComponent;
|
@Nullable private Player player;
|
||||||
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.VideoComponent} to use. */
|
/** Sets the {@link Player} to use. */
|
||||||
public void setVideoComponent(@Nullable Player.VideoComponent newVideoComponent) {
|
public void setPlayer(@Nullable Player newPlayer) {
|
||||||
if (newVideoComponent == videoComponent) {
|
if (newPlayer == player) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (videoComponent != null) {
|
if (player != null) {
|
||||||
if (surface != null) {
|
if (surface != null) {
|
||||||
videoComponent.clearVideoSurface(surface);
|
player.clearVideoSurface(surface);
|
||||||
}
|
}
|
||||||
videoComponent.clearVideoFrameMetadataListener(scene);
|
player.clearVideoFrameMetadataListener(scene);
|
||||||
videoComponent.clearCameraMotionListener(scene);
|
player.clearCameraMotionListener(scene);
|
||||||
}
|
}
|
||||||
videoComponent = newVideoComponent;
|
player = newPlayer;
|
||||||
if (videoComponent != null) {
|
if (this.player != null) {
|
||||||
videoComponent.setVideoFrameMetadataListener(scene);
|
player.setVideoFrameMetadataListener(scene);
|
||||||
videoComponent.setCameraMotionListener(scene);
|
player.setCameraMotionListener(scene);
|
||||||
videoComponent.setVideoSurface(surface);
|
player.setVideoSurface(surface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,8 +174,8 @@ public final class SphericalGLSurfaceView extends GLSurfaceView {
|
|||||||
mainHandler.post(
|
mainHandler.post(
|
||||||
() -> {
|
() -> {
|
||||||
if (surface != null) {
|
if (surface != null) {
|
||||||
if (videoComponent != null) {
|
if (player != null) {
|
||||||
videoComponent.clearVideoSurface(surface);
|
player.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 (videoComponent != null) {
|
if (player != null) {
|
||||||
videoComponent.setVideoSurface(surface);
|
player.setVideoSurface(surface);
|
||||||
}
|
}
|
||||||
releaseSurface(oldSurfaceTexture, oldSurface);
|
releaseSurface(oldSurfaceTexture, oldSurface);
|
||||||
});
|
});
|
||||||
|
@ -16,6 +16,10 @@
|
|||||||
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;
|
||||||
@ -37,6 +41,8 @@ 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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -440,6 +446,71 @@ 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();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user