From a633acaeee84d6eb8cc86020310a122bc61ea18f Mon Sep 17 00:00:00 2001 From: Marvin Willms <54174311+marvin-kolja@users.noreply.github.com> Date: Sun, 4 May 2025 13:50:42 +0200 Subject: [PATCH 1/6] fix(video_player_android): remove incorrect width/height swap for 90/270 rotation Since https://github.com/flutter/packages/pull/6535 `VideoSize` is used to get width and height instead of getting them from the video `Format`. My testing concluded that `VideoSize` dimension values are post rotation and do not need to be swapped when there is a 90 or 270 degree rotation present. --- .../TextureExoPlayerEventListener.java | 38 +++++++------------ .../TextureExoPlayerEventListenerTest.java | 10 ++--- 2 files changed, 18 insertions(+), 30 deletions(-) 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 From f579d5efcf709b4d27f87994014dbf860350d90f Mon Sep 17 00:00:00 2001 From: Marvin Willms <54174311+marvin-kolja@users.noreply.github.com> Date: Sun, 4 May 2025 14:24:43 +0200 Subject: [PATCH 2/6] fix(video_player_android): rotation layout issue (following #8685) --- .../example/lib/mini_controller.dart | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) 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..a36de80e5a0e 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 @@ -467,12 +467,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, + ); } } From 12a98ada07a6ff1cccc21a85beb2abb0ba7395cd Mon Sep 17 00:00:00 2001 From: Marvin Willms <54174311+marvin-kolja@users.noreply.github.com> Date: Sun, 4 May 2025 15:16:29 +0200 Subject: [PATCH 3/6] feat(video_player_android): remove unused import --- .../video_player_android/example/lib/mini_controller.dart | 1 - 1 file changed, 1 deletion(-) 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 a36de80e5a0e..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'; From 242040e5e737edaf47f293befcb97a2b3c87a173 Mon Sep 17 00:00:00 2001 From: Marvin Willms <54174311+marvin-kolja@users.noreply.github.com> Date: Sun, 4 May 2025 15:40:41 +0200 Subject: [PATCH 4/6] chore(video_player_android): version bump + changelog entry --- packages/video_player/video_player_android/CHANGELOG.md | 4 ++++ packages/video_player/video_player_android/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) 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/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 From 4cd6ad758182af85a33258efbfe292fb1adbfb25 Mon Sep 17 00:00:00 2001 From: Marvin Willms <54174311+marvin-kolja@users.noreply.github.com> Date: Tue, 13 May 2025 10:05:03 +0200 Subject: [PATCH 5/6] chore(video_player_android): add example app fix to changelog --- packages/video_player/video_player_android/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/video_player/video_player_android/CHANGELOG.md b/packages/video_player/video_player_android/CHANGELOG.md index 4c76313a2c6b..698314c28016 100644 --- a/packages/video_player/video_player_android/CHANGELOG.md +++ b/packages/video_player/video_player_android/CHANGELOG.md @@ -1,6 +1,7 @@ ## 2.8.4 * 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. +* Fixes example app layout issue caused by `Transform.rotate` not affecting space calculation (following #8685). ## 2.8.3 From 9a033771b17bde58da71514938aff2f6694a8268 Mon Sep 17 00:00:00 2001 From: Marvin Willms <54174311+marvin-kolja@users.noreply.github.com> Date: Tue, 13 May 2025 10:42:46 +0200 Subject: [PATCH 6/6] chore(video_player_android): add a proper link to PR ref --- packages/video_player/video_player_android/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/video_player/video_player_android/CHANGELOG.md b/packages/video_player/video_player_android/CHANGELOG.md index 698314c28016..d7e79f16cdba 100644 --- a/packages/video_player/video_player_android/CHANGELOG.md +++ b/packages/video_player/video_player_android/CHANGELOG.md @@ -1,7 +1,7 @@ ## 2.8.4 * 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. -* Fixes example app layout issue caused by `Transform.rotate` not affecting space calculation (following #8685). +* Fixes example app layout issue caused by `Transform.rotate` not affecting space calculation (following [#8685](https://github.com/flutter/packages/pull/8685)). ## 2.8.3