add imageview into simpleexoplayerview to display subtitles that are image based

This commit is contained in:
Drew Hill 2016-12-17 13:39:47 -05:00
parent fda2d143e4
commit 8277999b16
3 changed files with 109 additions and 6 deletions

View file

@ -0,0 +1,15 @@
package com.google.android.exoplayer2.text;
import android.graphics.Bitmap;
public class ImageCue extends Cue {
public ImageCue() { super(""); }
public Bitmap getBitmap() { return null; }
public int getX() { return 0; }
public int getY() { return 0; }
public int getWidth() { return 0; }
public int getHeight() { return 0; }
public boolean isForcedSubtitle() { return false; }
}

View file

@ -40,6 +40,7 @@ import com.google.android.exoplayer2.metadata.Metadata;
import com.google.android.exoplayer2.metadata.id3.ApicFrame;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.text.ImageCue;
import com.google.android.exoplayer2.text.TextRenderer;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
@ -171,6 +172,7 @@ public final class SimpleExoPlayerView extends FrameLayout {
private final View surfaceView;
private final ImageView artworkView;
private final SubtitleView subtitleView;
private final ImageView subtitleImageView;
private final PlaybackControlView controller;
private final ComponentListener componentListener;
private final FrameLayout overlayFrameLayout;
@ -178,6 +180,7 @@ public final class SimpleExoPlayerView extends FrameLayout {
private SimpleExoPlayer player;
private boolean useController;
private boolean useArtwork;
private boolean subtitlesEnabled = false;
private int controllerShowTimeoutMs;
public SimpleExoPlayerView(Context context) {
@ -253,6 +256,8 @@ public final class SimpleExoPlayerView extends FrameLayout {
subtitleView.setUserDefaultTextSize();
}
subtitleImageView = (ImageView) findViewById(R.id.exo_subtitles_image);
// Playback control view.
View controllerPlaceholder = findViewById(R.id.exo_controller_placeholder);
if (controllerPlaceholder != null) {
@ -523,14 +528,26 @@ public final class SimpleExoPlayerView extends FrameLayout {
return;
}
TrackSelectionArray selections = player.getCurrentTrackSelections();
boolean quickExit = false;
for (int i = 0; i < selections.length; i++) {
if (player.getRendererType(i) == C.TRACK_TYPE_VIDEO && selections.get(i) != null) {
// Video enabled so artwork must be hidden. If the shutter is closed, it will be opened in
// onRenderedFirstFrame().
hideArtwork();
return;
switch(player.getRendererType(i)) {
case C.TRACK_TYPE_VIDEO:
if (selections.get(i) != null) {
// Video enabled so artwork must be hidden. If the shutter is closed, it will be opened in
// onRenderedFirstFrame().
hideArtwork();
quickExit = true;
}
break;
case C.TRACK_TYPE_TEXT:
if (selections.get(i) != null)
subtitlesEnabled = true;
break;
}
}
if (quickExit)
return;
// Video disabled so the shutter must be closed.
if (shutterView != null) {
shutterView.setVisibility(VISIBLE);
@ -597,20 +614,85 @@ public final class SimpleExoPlayerView extends FrameLayout {
private final class ComponentListener implements SimpleExoPlayer.VideoListener,
TextRenderer.Output, ExoPlayer.EventListener {
private int sourceWidth = 0;
private int sourceHeight = 0;
// TextRenderer.Output implementation
@Override
public void onCues(List<Cue> cues) {
if (subtitleView != null) {
boolean skipNormalCues = false;
if (subtitleImageView != null) {
final ImageCue cue = (cues != null && !cues.isEmpty() && cues.get(0) instanceof ImageCue) ? (ImageCue) cues.get(0) : null;
skipNormalCues = (cue != null);
if (cue == null || (!subtitlesEnabled && !cue.isForcedSubtitle())) {
subtitleImageView.setImageBitmap(null);
subtitleImageView.setVisibility(View.INVISIBLE);
}
else {
handleImageCue(cue);
}
}
if (!skipNormalCues && subtitleView != null) {
subtitleView.onCues(cues);
}
}
private void handleImageCue(ImageCue cue) {
Bitmap bitmap = cue.getBitmap();
if (bitmap != null && surfaceView != null) {
int surfaceAnchorX = (int) surfaceView.getX();
int surfaceAnchorY = (int) surfaceView.getY();
int surfaceWidth = surfaceView.getWidth();
int surfaceHeight = surfaceView.getHeight();
int subAnchorX = cue.getX();
int subAnchorY = cue.getY();
int subScaleWidth = cue.getWidth();
int subScaleHeight = cue.getHeight();
// they should change together as we keep the aspect ratio
if ((surfaceHeight != sourceHeight || surfaceWidth != sourceWidth)
&& sourceHeight > 0 && sourceWidth > 0) {
double scale;
if (surfaceWidth != sourceWidth)
scale = (double) surfaceWidth / (double) sourceWidth;
else
scale = (double) surfaceHeight / (double) sourceHeight;
subScaleHeight = (int) (scale * subScaleHeight);
subScaleWidth = (int) (scale * subScaleWidth);
}
if (surfaceAnchorX != 0)
subAnchorX += surfaceAnchorX;
if (subAnchorY != 0)
subAnchorY += surfaceAnchorY;
ViewGroup.LayoutParams params = subtitleImageView.getLayoutParams();
params.width = subScaleWidth;
params.height = subScaleHeight;
subtitleImageView.setX(subAnchorX);
subtitleImageView.setY(subAnchorY);
subtitleImageView.setLayoutParams(params);
subtitleImageView.setImageBitmap(bitmap);
subtitleImageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
subtitleImageView.setVisibility(View.VISIBLE);
}
else {
subtitleImageView.setImageBitmap(null);
subtitleImageView.setVisibility(View.INVISIBLE);
}
}
// SimpleExoPlayer.VideoListener implementation
@Override
public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees,
float pixelWidthHeightRatio) {
sourceWidth = width;
sourceHeight = height;
if (contentFrame != null) {
float aspectRatio = height == 0 ? 1 : (width * pixelWidthHeightRatio) / height;
contentFrame.setAspectRatio(aspectRatio);

View file

@ -36,6 +36,12 @@
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<ImageView
android:id="@+id/exo_subtitles_image"
android:visibility="invisible"
android:layout_height="0dp"
android:layout_width="0dp" />
</com.google.android.exoplayer2.ui.AspectRatioFrameLayout>
<View android:id="@id/exo_controller_placeholder"