Commit 5364962d by hoangtc Committed by Oliver Woodman

Automatically apply rotation for TextureView in SimpleExoPlayer.

If SimpleExoPlayer is using TextView as output, we can handle video rotation by
automatically applying a matrix transformation to the TextureView when we have
this information available from the video (from video's metadata).

GitHub: #91

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=180925571
parent 373935ae
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
### dev-v2 (not yet released) ### ### dev-v2 (not yet released) ###
* SimpleExoPlayerView: Automatically apply video rotation if
`SimpleExoPlayerView` is configured to use `TextureView`
([#91](https://github.com/google/ExoPlayer/issues/91)).
* Player interface: * Player interface:
* Add optional parameter to `stop` to reset the player when stopping. * Add optional parameter to `stop` to reset the player when stopping.
* Add a reason to `EventListener.onTimelineChanged` to distinguish between * Add a reason to `EventListener.onTimelineChanged` to distinguish between
......
...@@ -22,6 +22,8 @@ import android.content.res.Resources; ...@@ -22,6 +22,8 @@ import android.content.res.Resources;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.util.AttributeSet; import android.util.AttributeSet;
...@@ -224,6 +226,7 @@ public final class SimpleExoPlayerView extends FrameLayout { ...@@ -224,6 +226,7 @@ public final class SimpleExoPlayerView extends FrameLayout {
private boolean controllerAutoShow; private boolean controllerAutoShow;
private boolean controllerHideDuringAds; private boolean controllerHideDuringAds;
private boolean controllerHideOnTouch; private boolean controllerHideOnTouch;
private int textureViewRotation;
public SimpleExoPlayerView(Context context) { public SimpleExoPlayerView(Context context) {
this(context, null); this(context, null);
...@@ -920,6 +923,31 @@ public final class SimpleExoPlayerView extends FrameLayout { ...@@ -920,6 +923,31 @@ public final class SimpleExoPlayerView extends FrameLayout {
aspectRatioFrame.setResizeMode(resizeMode); aspectRatioFrame.setResizeMode(resizeMode);
} }
/** Applies a texture rotation to a {@link TextureView}. */
private static void applyTextureViewRotation(TextureView textureView, int textureViewRotation) {
float textureViewWidth = textureView.getWidth();
float textureViewHeight = textureView.getHeight();
if (textureViewWidth == 0 || textureViewHeight == 0 || textureViewRotation == 0) {
textureView.setTransform(null);
} else {
Matrix transformMatrix = new Matrix();
float pivotX = textureViewWidth / 2;
float pivotY = textureViewHeight / 2;
transformMatrix.postRotate(textureViewRotation, pivotX, pivotY);
// After rotation, scale the rotated texture to fit the TextureView size.
RectF originalTextureRect = new RectF(0, 0, textureViewWidth, textureViewHeight);
RectF rotatedTextureRect = new RectF();
transformMatrix.mapRect(rotatedTextureRect, originalTextureRect);
transformMatrix.postScale(
textureViewWidth / rotatedTextureRect.width(),
textureViewHeight / rotatedTextureRect.height(),
pivotX,
pivotY);
textureView.setTransform(transformMatrix);
}
}
@SuppressLint("InlinedApi") @SuppressLint("InlinedApi")
private boolean isDpadKey(int keyCode) { private boolean isDpadKey(int keyCode) {
return keyCode == KeyEvent.KEYCODE_DPAD_UP return keyCode == KeyEvent.KEYCODE_DPAD_UP
...@@ -934,7 +962,7 @@ public final class SimpleExoPlayerView extends FrameLayout { ...@@ -934,7 +962,7 @@ public final class SimpleExoPlayerView extends FrameLayout {
} }
private final class ComponentListener extends Player.DefaultEventListener private final class ComponentListener extends Player.DefaultEventListener
implements TextOutput, SimpleExoPlayer.VideoListener { implements TextOutput, SimpleExoPlayer.VideoListener, OnLayoutChangeListener {
// TextOutput implementation // TextOutput implementation
...@@ -950,10 +978,32 @@ public final class SimpleExoPlayerView extends FrameLayout { ...@@ -950,10 +978,32 @@ public final class SimpleExoPlayerView extends FrameLayout {
@Override @Override
public void onVideoSizeChanged( public void onVideoSizeChanged(
int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) { int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
if (contentFrame != null) { if (contentFrame == null) {
float aspectRatio = height == 0 ? 1 : (width * pixelWidthHeightRatio) / height; return;
contentFrame.setAspectRatio(aspectRatio); }
float videoAspectRatio =
(height == 0 || width == 0) ? 1 : (width * pixelWidthHeightRatio) / height;
if (surfaceView instanceof TextureView) {
// Try to apply rotation transformation when our surface is a TextureView.
if (unappliedRotationDegrees == 90 || unappliedRotationDegrees == 270) {
// We will apply a rotation 90/270 degree to the output texture of the TextureView.
// In this case, the output video's width and height will be swapped.
videoAspectRatio = 1 / videoAspectRatio;
}
if (textureViewRotation != 0) {
surfaceView.removeOnLayoutChangeListener(this);
}
textureViewRotation = unappliedRotationDegrees;
if (textureViewRotation != 0) {
// The texture view's dimensions might be changed after layout step.
// So add an OnLayoutChangeListener to apply rotation after layout step.
surfaceView.addOnLayoutChangeListener(this);
}
applyTextureViewRotation((TextureView) surfaceView, textureViewRotation);
} }
contentFrame.setAspectRatio(videoAspectRatio);
} }
@Override @Override
...@@ -985,5 +1035,21 @@ public final class SimpleExoPlayerView extends FrameLayout { ...@@ -985,5 +1035,21 @@ public final class SimpleExoPlayerView extends FrameLayout {
hideController(); hideController();
} }
} }
// OnLayoutChangeListener implementation
@Override
public void onLayoutChange(
View view,
int left,
int top,
int right,
int bottom,
int oldLeft,
int oldTop,
int oldRight,
int oldBottom) {
applyTextureViewRotation((TextureView) view, textureViewRotation);
}
} }
} }
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