remove imagecue and add bitmap to cue with size_height, change to painter for displaying

This commit is contained in:
Drew Hill 2016-12-20 22:49:18 -05:00
parent 47d8b7ff16
commit 44b21f2e3b
5 changed files with 125 additions and 136 deletions

View file

@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.text;
import android.graphics.Bitmap;
import android.support.annotation.IntDef;
import android.text.Layout.Alignment;
import java.lang.annotation.Retention;
@ -78,6 +79,10 @@ public class Cue {
* The alignment of the cue text within the cue box, or null if the alignment is undefined.
*/
public final Alignment textAlignment;
/**
* The cue image.
*/
public final Bitmap bitmap;
/**
* The position of the {@link #lineAnchor} of the cue box within the viewport in the direction
* orthogonal to the writing direction, or {@link #DIMEN_UNSET}. When set, the interpretation of
@ -85,6 +90,8 @@ public class Cue {
* <p>
* For horizontal text and {@link #lineType} equal to {@link #LINE_TYPE_FRACTION}, this is the
* fractional vertical position relative to the top of the viewport.
* <p>
* If {@link #bitmap} is not null then this value is used to indicate the top position
*/
public final float line;
/**
@ -119,6 +126,8 @@ public class Cue {
* For horizontal text, this is the horizontal position relative to the left of the viewport. Note
* that positioning is relative to the left of the viewport even in the case of right-to-left
* text.
* <p>
* If {@link #bitmap} is not null then this value is used to indicate the left position
*/
public final float position;
/**
@ -134,9 +143,25 @@ public class Cue {
/**
* The size of the cue box in the writing direction specified as a fraction of the viewport size
* in that direction, or {@link #DIMEN_UNSET}.
* <p>
* If {@link #bitmap} is not null then this value is used to indicate the width
*/
public final float size;
/**
* The height size of the cue box when a {@link #bitmap} is set specified as a fraction of the
* viewport size in that direction, or {@link #DIMEN_UNSET}.
*/
public final float size_height;
/**
*
*/
public Cue(Bitmap bitmap, float left, float top, float size, float size_height) {
this(null, null, top, LINE_TYPE_FRACTION, TYPE_UNSET, left, TYPE_UNSET, size, size_height,
bitmap);
}
/**
* Constructs a cue whose {@link #textAlignment} is null, whose type parameters are set to
* {@link #TYPE_UNSET} and whose dimension parameters are set to {@link #DIMEN_UNSET}.
@ -159,6 +184,24 @@ public class Cue {
*/
public Cue(CharSequence text, Alignment textAlignment, float line, @LineType int lineType,
@AnchorType int lineAnchor, float position, @AnchorType int positionAnchor, float size) {
this(text, textAlignment, line, lineType, lineAnchor, position, positionAnchor, size,
DIMEN_UNSET, null);
}
/**
* @param text See {@link #text}.
* @param textAlignment See {@link #textAlignment}.
* @param line See {@link #line}.
* @param lineType See {@link #lineType}.
* @param lineAnchor See {@link #lineAnchor}.
* @param position See {@link #position}.
* @param positionAnchor See {@link #positionAnchor}.
* @param size See {@link #size}.
* @param size_height See {@link #size_height}.
* @param bitmap See {@link #bitmap}.
*/
private Cue(CharSequence text, Alignment textAlignment, float line, @LineType int lineType,
@AnchorType int lineAnchor, float position, @AnchorType int positionAnchor, float size,
float size_height, Bitmap bitmap) {
this.text = text;
this.textAlignment = textAlignment;
this.line = line;
@ -167,6 +210,8 @@ public class Cue {
this.position = position;
this.positionAnchor = positionAnchor;
this.size = size;
this.size_height = size_height;
this.bitmap = bitmap;
}
}

View file

@ -1,41 +0,0 @@
package com.google.android.exoplayer2.text;
import android.graphics.Bitmap;
public class ImageCue extends Cue {
final private long start_display_time;
final private int x;
final private int y;
final private int bitmap_height;
final private int bitmap_width;
final private int plane_height;
final private int plane_width;
final private Bitmap bitmap;
final private boolean isForced;
public ImageCue(Bitmap bitmap, long start_display_time,
int x, int y, int bitmap_width, int bitmap_height, boolean isForced,
int plane_width, int plane_height) {
super("");
this.bitmap = bitmap;
this.start_display_time = start_display_time;
this.x = x;
this.y = y;
this.bitmap_width = bitmap_width;
this.bitmap_height = bitmap_height;
this.plane_width = plane_width;
this.plane_height = plane_height;
this.isForced = isForced;
}
public long getStartDisplayTime() { return start_display_time; }
public Bitmap getBitmap() { return bitmap; }
public int getX() { return x; }
public int getY() { return y; }
public int getBitmapWidth() { return bitmap_width; }
public int getBitmapHeight() { return bitmap_height; }
public int getPlaneWidth() { return plane_width; }
public int getPlaneHeight() { return plane_height; }
public boolean isForcedSubtitle() { return isForced; }
}

View file

@ -40,7 +40,6 @@ 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;
@ -172,7 +171,6 @@ 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;
@ -256,8 +254,6 @@ 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) {
@ -619,70 +615,11 @@ public final class SimpleExoPlayerView extends FrameLayout {
@Override
public void onCues(List<Cue> cues) {
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) {
if (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 sourceWidth = cue.getPlaneWidth();
int sourceHeight = cue.getPlaneHeight();
int subAnchorX = cue.getX();
int subAnchorY = cue.getY();
int subScaleWidth = cue.getBitmapWidth();
int subScaleHeight = cue.getBitmapHeight();
// 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

View file

@ -18,11 +18,13 @@ package com.google.android.exoplayer2.ui;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Join;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.RectF;
import android.text.Layout.Alignment;
import android.text.StaticLayout;
@ -63,6 +65,7 @@ import com.google.android.exoplayer2.util.Util;
private final Paint paint;
// Previous input variables.
private Bitmap cueBitmap;
private CharSequence cueText;
private Alignment cueTextAlignment;
private float cueLine;
@ -74,6 +77,7 @@ import com.google.android.exoplayer2.util.Util;
@Cue.AnchorType
private int cuePositionAnchor;
private float cueSize;
private float cueSizeHeight;
private boolean applyEmbeddedStyles;
private int foregroundColor;
private int backgroundColor;
@ -93,6 +97,7 @@ import com.google.android.exoplayer2.util.Util;
private int textLeft;
private int textTop;
private int textPaddingX;
private Rect bitmapRect;
@SuppressWarnings("ResourceType")
public SubtitlePainter(Context context) {
@ -142,40 +147,43 @@ import com.google.android.exoplayer2.util.Util;
float bottomPaddingFraction, Canvas canvas, int cueBoxLeft, int cueBoxTop, int cueBoxRight,
int cueBoxBottom) {
CharSequence cueText = cue.text;
if (TextUtils.isEmpty(cueText)) {
boolean textIsEmpty = TextUtils.isEmpty(cueText);
if (textIsEmpty && cue.bitmap == null) {
// Nothing to draw.
return;
}
if (!applyEmbeddedStyles) {
if (!applyEmbeddedStyles && !textIsEmpty) {
// Strip out any embedded styling.
cueText = cueText.toString();
}
if (areCharSequencesEqual(this.cueText, cueText)
&& Util.areEqual(this.cueTextAlignment, cue.textAlignment)
&& this.cueLine == cue.line
&& this.cueLineType == cue.lineType
&& Util.areEqual(this.cueLineAnchor, cue.lineAnchor)
&& this.cuePosition == cue.position
&& Util.areEqual(this.cuePositionAnchor, cue.positionAnchor)
&& this.cueSize == cue.size
&& this.applyEmbeddedStyles == applyEmbeddedStyles
&& this.foregroundColor == style.foregroundColor
&& this.backgroundColor == style.backgroundColor
&& this.windowColor == style.windowColor
&& this.edgeType == style.edgeType
&& this.edgeColor == style.edgeColor
&& Util.areEqual(this.textPaint.getTypeface(), style.typeface)
&& this.textSizePx == textSizePx
&& this.bottomPaddingFraction == bottomPaddingFraction
&& this.parentLeft == cueBoxLeft
&& this.parentTop == cueBoxTop
&& this.parentRight == cueBoxRight
&& this.parentBottom == cueBoxBottom) {
if (((cue.bitmap != null && cue.bitmap == cueBitmap) ||
(!textIsEmpty && areCharSequencesEqual(this.cueText, cueText)))
&& Util.areEqual(this.cueTextAlignment, cue.textAlignment)
&& this.cueLine == cue.line
&& this.cueLineType == cue.lineType
&& Util.areEqual(this.cueLineAnchor, cue.lineAnchor)
&& this.cuePosition == cue.position
&& Util.areEqual(this.cuePositionAnchor, cue.positionAnchor)
&& this.cueSize == cue.size
&& this.applyEmbeddedStyles == applyEmbeddedStyles
&& this.foregroundColor == style.foregroundColor
&& this.backgroundColor == style.backgroundColor
&& this.windowColor == style.windowColor
&& this.edgeType == style.edgeType
&& this.edgeColor == style.edgeColor
&& Util.areEqual(this.textPaint.getTypeface(), style.typeface)
&& this.textSizePx == textSizePx
&& this.bottomPaddingFraction == bottomPaddingFraction
&& this.parentLeft == cueBoxLeft
&& this.parentTop == cueBoxTop
&& this.parentRight == cueBoxRight
&& this.parentBottom == cueBoxBottom) {
// We can use the cached layout.
drawLayout(canvas);
return;
}
this.cueBitmap = cue.bitmap;
this.cueText = cueText;
this.cueTextAlignment = cue.textAlignment;
this.cueLine = cue.line;
@ -184,6 +192,7 @@ import com.google.android.exoplayer2.util.Util;
this.cuePosition = cue.position;
this.cuePositionAnchor = cue.positionAnchor;
this.cueSize = cue.size;
this.cueSizeHeight = cue.size_height;
this.applyEmbeddedStyles = applyEmbeddedStyles;
this.foregroundColor = style.foregroundColor;
this.backgroundColor = style.backgroundColor;
@ -198,6 +207,32 @@ import com.google.android.exoplayer2.util.Util;
this.parentRight = cueBoxRight;
this.parentBottom = cueBoxBottom;
if (this.cueBitmap != null)
setupBitmapLayout();
else
setupTextLayout();
drawLayout(canvas);
}
/**
* Setup {@link #textLayout} for later drawing.
*/
private void setupBitmapLayout() {
int parentWidth = parentRight - parentLeft;
int parentHeight = parentBottom - parentTop;
int x = parentLeft + (int) ((float) parentWidth * cuePosition);
int y = parentTop + (int) ((float) parentHeight * cueLine);
bitmapRect = new Rect(x,y,
x + (int)((float) parentWidth * cueSize),y + (int)((float) parentHeight * cueSizeHeight));
}
/**
* Setup {@link #textLayout} for later drawing.
*/
private void setupTextLayout() {
int parentWidth = parentRight - parentLeft;
int parentHeight = parentBottom - parentTop;
@ -275,8 +310,27 @@ import com.google.android.exoplayer2.util.Util;
this.textLeft = textLeft;
this.textTop = textTop;
this.textPaddingX = textPaddingX;
}
drawLayout(canvas);
/**
* Draws {@link #textLayout} or {@link #cueBitmap} into the provided canvas.
*
* @param canvas The canvas into which to draw.
*/
private void drawLayout(Canvas canvas) {
if (cueBitmap != null)
drawBitmapLayout(canvas);
else
drawTextLayout(canvas);
}
/**
* Draws {@link #cueBitmap} into the provided canvas.
*
* @param canvas The canvas into which to draw.
*/
private void drawBitmapLayout(Canvas canvas) {
canvas.drawBitmap(cueBitmap, null, bitmapRect, null);
}
/**
@ -284,7 +338,7 @@ import com.google.android.exoplayer2.util.Util;
*
* @param canvas The canvas into which to draw.
*/
private void drawLayout(Canvas canvas) {
private void drawTextLayout(Canvas canvas) {
final StaticLayout layout = textLayout;
if (layout == null) {
// Nothing to draw.

View file

@ -36,12 +36,6 @@
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"