diff --git a/packages/video_player/video_player_android/CHANGELOG.md b/packages/video_player/video_player_android/CHANGELOG.md index f9a2064447e4..fdd1cd0096dc 100644 --- a/packages/video_player/video_player_android/CHANGELOG.md +++ b/packages/video_player/video_player_android/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.8.3 + +* Fixes incorrect width/height swap ([bug](https://github.com/flutter/flutter/issues/166097)). The swap was originally required for the uncorrected width/height of `Format` but was mistakenly retained after [switching to `VideoSize`](https://github.com/flutter/packages/pull/6535), which already accounts for rotation. + ## 2.8.2 * Fixes a [bug](https://github.com/flutter/flutter/issues/164689) that can cause video to diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/texture/TextureExoPlayerEventListener.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/texture/TextureExoPlayerEventListener.java index 3722ddebeece..1a88f7b42145 100644 --- a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/texture/TextureExoPlayerEventListener.java +++ b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/texture/TextureExoPlayerEventListener.java @@ -30,26 +30,22 @@ public TextureExoPlayerEventListener( @Override protected void sendInitialized() { VideoSize videoSize = exoPlayer.getVideoSize(); - int rotationCorrection = 0; + RotationDegrees rotationCorrection = RotationDegrees.ROTATE_0; int width = videoSize.width; int height = videoSize.height; if (width != 0 && height != 0) { - RotationDegrees reportedRotationCorrection = RotationDegrees.ROTATE_0; - if (Build.VERSION.SDK_INT <= 21) { // On API 21 and below, Exoplayer may not internally handle rotation correction // and reports it through VideoSize.unappliedRotationDegrees. We may apply it to // fix the case of upside-down playback. try { - reportedRotationCorrection = + RotationDegrees unappliedRotation = RotationDegrees.fromDegrees(videoSize.unappliedRotationDegrees); - rotationCorrection = - getRotationCorrectionFromUnappliedRotation(reportedRotationCorrection); + rotationCorrection = getRotationCorrectionFromUnappliedRotation(unappliedRotation); } catch (IllegalArgumentException e) { // Unapplied rotation other than 0, 90, 180, 270 reported by VideoSize. Because this is // unexpected, we apply no rotation correction. - reportedRotationCorrection = RotationDegrees.ROTATE_0; - rotationCorrection = 0; + rotationCorrection = RotationDegrees.ROTATE_0; } } // TODO(camsim99): Replace this with a call to `handlesCropAndRotation` when it is @@ -57,43 +53,35 @@ protected void sendInitialized() { else if (Build.VERSION.SDK_INT < 29) { // When the SurfaceTexture backend for Impeller is used, the preview should already // be correctly rotated. - rotationCorrection = 0; + rotationCorrection = RotationDegrees.ROTATE_0; } else { // The video's Format also provides a rotation correction that may be used to // correct the rotation, so we try to use that to correct the video rotation // when the ImageReader backend for Impeller is used. - rotationCorrection = getRotationCorrectionFromFormat(exoPlayer); + int rawVideoFormatRotation = getRotationCorrectionFromFormat(exoPlayer); try { - reportedRotationCorrection = RotationDegrees.fromDegrees(rotationCorrection); + rotationCorrection = RotationDegrees.fromDegrees(rawVideoFormatRotation); } catch (IllegalArgumentException e) { // Rotation correction other than 0, 90, 180, 270 reported by Format. Because this is // unexpected we apply no rotation correction. - reportedRotationCorrection = RotationDegrees.ROTATE_0; - rotationCorrection = 0; + rotationCorrection = RotationDegrees.ROTATE_0; } } - - // Switch the width/height if video was taken in portrait mode and a rotation - // correction was detected. - if (reportedRotationCorrection == RotationDegrees.ROTATE_90 - || reportedRotationCorrection == RotationDegrees.ROTATE_270) { - width = videoSize.height; - height = videoSize.width; - } } - events.onInitialized(width, height, exoPlayer.getDuration(), rotationCorrection); + events.onInitialized(width, height, exoPlayer.getDuration(), rotationCorrection.getDegrees()); } - private int getRotationCorrectionFromUnappliedRotation(RotationDegrees unappliedRotationDegrees) { - int rotationCorrection = 0; + private RotationDegrees getRotationCorrectionFromUnappliedRotation( + RotationDegrees unappliedRotationDegrees) { + RotationDegrees rotationCorrection = RotationDegrees.ROTATE_0; // Rotating the video with ExoPlayer does not seem to be possible with a Surface, // so inform the Flutter code that the widget needs to be rotated to prevent // upside-down playback for videos with unappliedRotationDegrees of 180 (other orientations // work correctly without correction). if (unappliedRotationDegrees == RotationDegrees.ROTATE_180) { - rotationCorrection = unappliedRotationDegrees.getDegrees(); + rotationCorrection = unappliedRotationDegrees; } return rotationCorrection; diff --git a/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/TextureExoPlayerEventListenerTest.java b/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/TextureExoPlayerEventListenerTest.java index 931023b7a7b7..1fbecb4f5e54 100644 --- a/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/TextureExoPlayerEventListenerTest.java +++ b/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/TextureExoPlayerEventListenerTest.java @@ -66,7 +66,7 @@ public void onPlaybackStateChangedReadySendInitialized_belowAndroid29() { when(mockExoPlayer.getVideoFormat()).thenReturn(videoFormat); eventListener.onPlaybackStateChanged(Player.STATE_READY); - verify(mockCallbacks).onInitialized(400, 800, 10L, rotationCorrection); + verify(mockCallbacks).onInitialized(800, 400, 10L, rotationCorrection); } @Test @@ -78,7 +78,7 @@ public void onPlaybackStateChangedReadySendInitialized_belowAndroid29() { when(mockExoPlayer.getDuration()).thenReturn(10L); eventListener.onPlaybackStateChanged(Player.STATE_READY); - verify(mockCallbacks).onInitialized(400, 800, 10L, 0); + verify(mockCallbacks).onInitialized(800, 400, 10L, 0); } @Test @@ -107,7 +107,7 @@ public void onPlaybackStateChangedReadySendInitialized_belowAndroid29() { when(mockExoPlayer.getVideoFormat()).thenReturn(videoFormat); eventListener.onPlaybackStateChanged(Player.STATE_READY); - verify(mockCallbacks).onInitialized(400, 800, 10L, 90); + verify(mockCallbacks).onInitialized(800, 400, 10L, 90); } @Test @@ -119,7 +119,7 @@ public void onPlaybackStateChangedReadySendInitialized_belowAndroid29() { when(mockExoPlayer.getDuration()).thenReturn(10L); eventListener.onPlaybackStateChanged(Player.STATE_READY); - verify(mockCallbacks).onInitialized(400, 800, 10L, 0); + verify(mockCallbacks).onInitialized(800, 400, 10L, 0); } @Test @@ -147,7 +147,7 @@ public void onPlaybackStateChangedReadySendInitialized_belowAndroid29() { when(mockExoPlayer.getVideoFormat()).thenReturn(videoFormat); eventListener.onPlaybackStateChanged(Player.STATE_READY); - verify(mockCallbacks).onInitialized(400, 800, 10L, 270); + verify(mockCallbacks).onInitialized(800, 400, 10L, 270); } @Test diff --git a/packages/video_player/video_player_android/example/lib/mini_controller.dart b/packages/video_player/video_player_android/example/lib/mini_controller.dart index db8692a4a913..4350927542c7 100644 --- a/packages/video_player/video_player_android/example/lib/mini_controller.dart +++ b/packages/video_player/video_player_android/example/lib/mini_controller.dart @@ -7,7 +7,6 @@ import 'dart:async'; import 'dart:io'; -import 'dart:math'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; @@ -467,12 +466,13 @@ class _VideoPlayerWithRotation extends StatelessWidget { @override Widget build(BuildContext context) { - return rotation == 0 - ? child - : Transform.rotate( - angle: rotation * pi / 180, - child: child, - ); + if (rotation == 0) { + return child; + } + return RotatedBox( + quarterTurns: rotation ~/ 90, + child: child, + ); } } diff --git a/packages/video_player/video_player_android/pubspec.yaml b/packages/video_player/video_player_android/pubspec.yaml index 40b0c33388c3..4c4293e130f9 100644 --- a/packages/video_player/video_player_android/pubspec.yaml +++ b/packages/video_player/video_player_android/pubspec.yaml @@ -2,7 +2,7 @@ name: video_player_android description: Android implementation of the video_player plugin. repository: https://github.com/flutter/packages/tree/main/packages/video_player/video_player_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22 -version: 2.8.2 +version: 2.8.3 environment: sdk: ^3.6.0