Commit d0a3468b by bachinger Committed by Tofunmi Adigun-Hameed

Add artwork display mode to PlayerView

This change deprecates `PlayerView.setUseArtwork(boolean)` and
introduces `setArtworkDisplayMode(mode)` and
`artworkDisplayMode="off|fit|fill"` instead.

- off: no artwork is displayed (like deprecated useArtwork=false)
- fit: letterbox like media (like deprecated useArtwork=true)
- fill: scales the artwork to fill the entire width/weight of the player view

#minor-release

PiperOrigin-RevId: 534167226
(cherry picked from commit 7f3f2fe0758e083cc5baf8781b1f1be20d32f052)
parent 85a9d563
...@@ -90,10 +90,11 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; ...@@ -90,10 +90,11 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
* The following attributes can be set on a StyledPlayerView when used in a layout XML file: * The following attributes can be set on a StyledPlayerView when used in a layout XML file:
* *
* <ul> * <ul>
* <li><b>{@code use_artwork}</b> - Whether artwork is used if available in audio streams. * <li><b>{@code artwork_display_mode}</b> - Whether artwork is used if available in audio streams
* and {@link ArtworkDisplayMode how it is displayed}.
* <ul> * <ul>
* <li>Corresponding method: {@link #setUseArtwork(boolean)} * <li>Corresponding method: {@link #setArtworkDisplayMode(int)}
* <li>Default: {@code true} * <li>Default: {@link #ARTWORK_DISPLAY_MODE_FIT}
* </ul> * </ul>
* <li><b>{@code default_artwork}</b> - Default artwork to use if no artwork available in audio * <li><b>{@code default_artwork}</b> - Default artwork to use if no artwork available in audio
* streams. * streams.
...@@ -199,6 +200,26 @@ public class StyledPlayerView extends FrameLayout implements AdViewProvider { ...@@ -199,6 +200,26 @@ public class StyledPlayerView extends FrameLayout implements AdViewProvider {
} }
/** /**
* Determines the artwork display mode. One of {@link #ARTWORK_DISPLAY_MODE_OFF}, {@link
* #ARTWORK_DISPLAY_MODE_FIT} or {@link #ARTWORK_DISPLAY_MODE_FILL}.
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
@Target(TYPE_USE)
@IntDef({ARTWORK_DISPLAY_MODE_OFF, ARTWORK_DISPLAY_MODE_FIT, ARTWORK_DISPLAY_MODE_FILL})
public @interface ArtworkDisplayMode {}
/** No artwork is shown. */
public static final int ARTWORK_DISPLAY_MODE_OFF = 0;
/** The artwork is fit into the player view and centered creating a letterbox style. */
public static final int ARTWORK_DISPLAY_MODE_FIT = 1;
/**
* The artwork covers the entire space of the player view. If the aspect ratio of the image is
* different than the player view some areas of the image are cropped.
*/
public static final int ARTWORK_DISPLAY_MODE_FILL = 2;
/**
* Determines when the buffering view is shown. One of {@link #SHOW_BUFFERING_NEVER}, {@link * Determines when the buffering view is shown. One of {@link #SHOW_BUFFERING_NEVER}, {@link
* #SHOW_BUFFERING_WHEN_PLAYING} or {@link #SHOW_BUFFERING_ALWAYS}. * #SHOW_BUFFERING_WHEN_PLAYING} or {@link #SHOW_BUFFERING_ALWAYS}.
*/ */
...@@ -251,7 +272,8 @@ public class StyledPlayerView extends FrameLayout implements AdViewProvider { ...@@ -251,7 +272,8 @@ public class StyledPlayerView extends FrameLayout implements AdViewProvider {
@Nullable private FullscreenButtonClickListener fullscreenButtonClickListener; @Nullable private FullscreenButtonClickListener fullscreenButtonClickListener;
private boolean useArtwork; private @ArtworkDisplayMode int artworkDisplayMode;
@Nullable private Drawable defaultArtwork; @Nullable private Drawable defaultArtwork;
private @ShowBuffering int showBuffering; private @ShowBuffering int showBuffering;
private boolean keepContentOnPlayerReset; private boolean keepContentOnPlayerReset;
...@@ -304,6 +326,7 @@ public class StyledPlayerView extends FrameLayout implements AdViewProvider { ...@@ -304,6 +326,7 @@ public class StyledPlayerView extends FrameLayout implements AdViewProvider {
int shutterColor = 0; int shutterColor = 0;
int playerLayoutId = R.layout.exo_styled_player_view; int playerLayoutId = R.layout.exo_styled_player_view;
boolean useArtwork = true; boolean useArtwork = true;
int artworkDisplayMode = ARTWORK_DISPLAY_MODE_FIT;
int defaultArtworkId = 0; int defaultArtworkId = 0;
boolean useController = true; boolean useController = true;
int surfaceType = SURFACE_TYPE_SURFACE_VIEW; int surfaceType = SURFACE_TYPE_SURFACE_VIEW;
...@@ -326,6 +349,8 @@ public class StyledPlayerView extends FrameLayout implements AdViewProvider { ...@@ -326,6 +349,8 @@ public class StyledPlayerView extends FrameLayout implements AdViewProvider {
playerLayoutId = playerLayoutId =
a.getResourceId(R.styleable.StyledPlayerView_player_layout_id, playerLayoutId); a.getResourceId(R.styleable.StyledPlayerView_player_layout_id, playerLayoutId);
useArtwork = a.getBoolean(R.styleable.StyledPlayerView_use_artwork, useArtwork); useArtwork = a.getBoolean(R.styleable.StyledPlayerView_use_artwork, useArtwork);
artworkDisplayMode =
a.getInt(R.styleable.StyledPlayerView_artwork_display_mode, artworkDisplayMode);
defaultArtworkId = defaultArtworkId =
a.getResourceId(R.styleable.StyledPlayerView_default_artwork, defaultArtworkId); a.getResourceId(R.styleable.StyledPlayerView_default_artwork, defaultArtworkId);
useController = a.getBoolean(R.styleable.StyledPlayerView_use_controller, useController); useController = a.getBoolean(R.styleable.StyledPlayerView_use_controller, useController);
...@@ -420,7 +445,9 @@ public class StyledPlayerView extends FrameLayout implements AdViewProvider { ...@@ -420,7 +445,9 @@ public class StyledPlayerView extends FrameLayout implements AdViewProvider {
// Artwork view. // Artwork view.
artworkView = findViewById(R.id.exo_artwork); artworkView = findViewById(R.id.exo_artwork);
this.useArtwork = useArtwork && artworkView != null; boolean isArtworkEnabled =
useArtwork && artworkDisplayMode != ARTWORK_DISPLAY_MODE_OFF && artworkView != null;
this.artworkDisplayMode = isArtworkEnabled ? artworkDisplayMode : ARTWORK_DISPLAY_MODE_OFF;
if (defaultArtworkId != 0) { if (defaultArtworkId != 0) {
defaultArtwork = ContextCompat.getDrawable(getContext(), defaultArtworkId); defaultArtwork = ContextCompat.getDrawable(getContext(), defaultArtworkId);
} }
...@@ -558,7 +585,10 @@ public class StyledPlayerView extends FrameLayout implements AdViewProvider { ...@@ -558,7 +585,10 @@ public class StyledPlayerView extends FrameLayout implements AdViewProvider {
} else if (surfaceView instanceof SurfaceView) { } else if (surfaceView instanceof SurfaceView) {
player.setVideoSurfaceView((SurfaceView) surfaceView); player.setVideoSurfaceView((SurfaceView) surfaceView);
} }
updateAspectRatio(); if (player.getCurrentTracks().isTypeSupported(C.TRACK_TYPE_VIDEO)) {
// If the player already is or was playing a video, onVideoSizeChanged isn't called.
updateAspectRatio();
}
} }
if (subtitleView != null && player.isCommandAvailable(COMMAND_GET_TEXT)) { if (subtitleView != null && player.isCommandAvailable(COMMAND_GET_TEXT)) {
subtitleView.setCues(player.getCurrentCues().cues); subtitleView.setCues(player.getCurrentCues().cues);
...@@ -595,24 +625,36 @@ public class StyledPlayerView extends FrameLayout implements AdViewProvider { ...@@ -595,24 +625,36 @@ public class StyledPlayerView extends FrameLayout implements AdViewProvider {
return contentFrame.getResizeMode(); return contentFrame.getResizeMode();
} }
/** Returns whether artwork is displayed if present in the media. */ /**
* @deprecated Use {@link #getArtworkDisplayMode()} instead.
*/
@Deprecated
public boolean getUseArtwork() { public boolean getUseArtwork() {
return useArtwork; return this.artworkDisplayMode != ARTWORK_DISPLAY_MODE_OFF;
} }
/** /**
* Sets whether artwork is displayed if present in the media. * @deprecated Use {@link #setArtworkDisplayMode(int)} instead.
*
* @param useArtwork Whether artwork is displayed.
*/ */
@Deprecated
public void setUseArtwork(boolean useArtwork) { public void setUseArtwork(boolean useArtwork) {
Assertions.checkState(!useArtwork || artworkView != null); setArtworkDisplayMode(useArtwork ? ARTWORK_DISPLAY_MODE_OFF : ARTWORK_DISPLAY_MODE_FIT);
if (this.useArtwork != useArtwork) { }
this.useArtwork = useArtwork;
/** Sets whether and how artwork is displayed if present in the media. */
public void setArtworkDisplayMode(@ArtworkDisplayMode int artworkDisplayMode) {
Assertions.checkState(artworkDisplayMode == ARTWORK_DISPLAY_MODE_OFF || artworkView != null);
if (this.artworkDisplayMode != artworkDisplayMode) {
this.artworkDisplayMode = artworkDisplayMode;
updateForCurrentTrackSelections(/* isNewPlayer= */ false); updateForCurrentTrackSelections(/* isNewPlayer= */ false);
} }
} }
/** Returns the {@link ArtworkDisplayMode artwork display mode}. */
public @ArtworkDisplayMode int getArtworkDisplayMode() {
return artworkDisplayMode;
}
/** Returns the default artwork to display. */ /** Returns the default artwork to display. */
@Nullable @Nullable
public Drawable getDefaultArtwork() { public Drawable getDefaultArtwork() {
...@@ -1208,7 +1250,7 @@ public class StyledPlayerView extends FrameLayout implements AdViewProvider { ...@@ -1208,7 +1250,7 @@ public class StyledPlayerView extends FrameLayout implements AdViewProvider {
@EnsuresNonNullIf(expression = "artworkView", result = true) @EnsuresNonNullIf(expression = "artworkView", result = true)
private boolean useArtwork() { private boolean useArtwork() {
if (useArtwork) { if (artworkDisplayMode != ARTWORK_DISPLAY_MODE_OFF) {
Assertions.checkStateNotNull(artworkView); Assertions.checkStateNotNull(artworkView);
return true; return true;
} }
...@@ -1329,8 +1371,14 @@ public class StyledPlayerView extends FrameLayout implements AdViewProvider { ...@@ -1329,8 +1371,14 @@ public class StyledPlayerView extends FrameLayout implements AdViewProvider {
int drawableWidth = drawable.getIntrinsicWidth(); int drawableWidth = drawable.getIntrinsicWidth();
int drawableHeight = drawable.getIntrinsicHeight(); int drawableHeight = drawable.getIntrinsicHeight();
if (drawableWidth > 0 && drawableHeight > 0) { if (drawableWidth > 0 && drawableHeight > 0) {
float artworkAspectRatio = (float) drawableWidth / drawableHeight; float artworkLayoutAspectRatio = (float) drawableWidth / drawableHeight;
onContentAspectRatioChanged(contentFrame, artworkAspectRatio); ImageView.ScaleType scaleStyle = ImageView.ScaleType.FIT_XY;
if (artworkDisplayMode == ARTWORK_DISPLAY_MODE_FILL) {
artworkLayoutAspectRatio = (float) getWidth() / getHeight();
scaleStyle = ImageView.ScaleType.CENTER_CROP;
}
onContentAspectRatioChanged(contentFrame, artworkLayoutAspectRatio);
artworkView.setScaleType(scaleStyle);
artworkView.setImageDrawable(drawable); artworkView.setImageDrawable(drawable);
artworkView.setVisibility(VISIBLE); artworkView.setVisibility(VISIBLE);
return true; return true;
......
...@@ -42,6 +42,11 @@ ...@@ -42,6 +42,11 @@
<!-- PlayerView and StyledPlayerView attributes --> <!-- PlayerView and StyledPlayerView attributes -->
<attr name="use_artwork" format="boolean"/> <attr name="use_artwork" format="boolean"/>
<attr name="artwork_display_mode" format="enum">
<enum name="off" value="0"/>
<enum name="fit" value="1"/>
<enum name="fill" value="2"/>
</attr>
<attr name="shutter_background_color" format="color"/> <attr name="shutter_background_color" format="color"/>
<attr name="default_artwork" format="reference"/> <attr name="default_artwork" format="reference"/>
<attr name="use_controller" format="boolean"/> <attr name="use_controller" format="boolean"/>
...@@ -93,6 +98,7 @@ ...@@ -93,6 +98,7 @@
<declare-styleable name="StyledPlayerView"> <declare-styleable name="StyledPlayerView">
<attr name="use_artwork"/> <attr name="use_artwork"/>
<attr name="artwork_display_mode"/>
<attr name="shutter_background_color"/> <attr name="shutter_background_color"/>
<attr name="default_artwork"/> <attr name="default_artwork"/>
<attr name="use_controller"/> <attr name="use_controller"/>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment