Skip to content

Commit f444a1e

Browse files
authored
[video_player_android] Fix incorrect dimensions swap (#9199)
Fixes flutter/flutter#166097 *List which issues are fixed by this PR. You must list at least one issue.* ## Manual Testing Overview | API | Device | Video requires rotation | Works w/o fix| Works w/ fix | Ref | |---|---|---|---|---|---| | 35 | Emulator | yes | no | yes | #9199 (comment) by @marvin-kolja | | 34 | Pixel Tablet | no | no | yes | #9199 (comment) by @camsim99 | | 34 | Pixel Tablet | yes | no | yes | @camsim99 | | 33 | Samsung A71 | ? | ? | yes | #9199 (comment) by @PaulineMoovency | | 32 | Pixel 3A | yes | no | yes | @camsim99 | | 27 | Samsung Galaxy J7 | yes | yes | yes | @camsim99 | ## Pre-Review Checklist [^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
1 parent af0b9a9 commit f444a1e

File tree

5 files changed

+31
-38
lines changed

5 files changed

+31
-38
lines changed

packages/video_player/video_player_android/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 2.8.4
2+
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.
4+
* Fixes example app layout issue caused by `Transform.rotate` not affecting space calculation (following [#8685](https://github.com/flutter/packages/pull/8685)).
5+
16
## 2.8.3
27

38
* Changes plugin to use `TextureRegistry.SurfaceProducer.handlesCropAndRotation` to detect

packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/texture/TextureExoPlayerEventListener.java

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -38,67 +38,55 @@ public TextureExoPlayerEventListener(
3838
@Override
3939
protected void sendInitialized() {
4040
VideoSize videoSize = exoPlayer.getVideoSize();
41-
int rotationCorrection = 0;
41+
RotationDegrees rotationCorrection = RotationDegrees.ROTATE_0;
4242
int width = videoSize.width;
4343
int height = videoSize.height;
4444
if (width != 0 && height != 0) {
45-
RotationDegrees reportedRotationCorrection = RotationDegrees.ROTATE_0;
46-
4745
if (Build.VERSION.SDK_INT <= 21) {
4846
// On API 21 and below, Exoplayer may not internally handle rotation correction
4947
// and reports it through VideoSize.unappliedRotationDegrees. We may apply it to
5048
// fix the case of upside-down playback.
5149
try {
52-
reportedRotationCorrection =
50+
RotationDegrees unappliedRotation =
5351
RotationDegrees.fromDegrees(videoSize.unappliedRotationDegrees);
54-
rotationCorrection =
55-
getRotationCorrectionFromUnappliedRotation(reportedRotationCorrection);
52+
rotationCorrection = getRotationCorrectionFromUnappliedRotation(unappliedRotation);
5653
} catch (IllegalArgumentException e) {
5754
// Unapplied rotation other than 0, 90, 180, 270 reported by VideoSize. Because this is
5855
// unexpected, we apply no rotation correction.
59-
reportedRotationCorrection = RotationDegrees.ROTATE_0;
60-
rotationCorrection = 0;
56+
rotationCorrection = RotationDegrees.ROTATE_0;
6157
}
6258
} else if (surfaceProducerHandlesCropAndRotation) {
6359
// When the SurfaceTexture backend for Impeller is used, the preview should already
6460
// be correctly rotated.
65-
rotationCorrection = 0;
61+
rotationCorrection = RotationDegrees.ROTATE_0;
6662
} else {
6763
// The video's Format also provides a rotation correction that may be used to
6864
// correct the rotation, so we try to use that to correct the video rotation
6965
// when the ImageReader backend for Impeller is used.
70-
rotationCorrection = getRotationCorrectionFromFormat(exoPlayer);
66+
int rawVideoFormatRotation = getRotationCorrectionFromFormat(exoPlayer);
7167

7268
try {
73-
reportedRotationCorrection = RotationDegrees.fromDegrees(rotationCorrection);
69+
rotationCorrection = RotationDegrees.fromDegrees(rawVideoFormatRotation);
7470
} catch (IllegalArgumentException e) {
7571
// Rotation correction other than 0, 90, 180, 270 reported by Format. Because this is
7672
// unexpected we apply no rotation correction.
77-
reportedRotationCorrection = RotationDegrees.ROTATE_0;
78-
rotationCorrection = 0;
73+
rotationCorrection = RotationDegrees.ROTATE_0;
7974
}
8075
}
81-
82-
// Switch the width/height if video was taken in portrait mode and a rotation
83-
// correction was detected.
84-
if (reportedRotationCorrection == RotationDegrees.ROTATE_90
85-
|| reportedRotationCorrection == RotationDegrees.ROTATE_270) {
86-
width = videoSize.height;
87-
height = videoSize.width;
88-
}
8976
}
90-
events.onInitialized(width, height, exoPlayer.getDuration(), rotationCorrection);
77+
events.onInitialized(width, height, exoPlayer.getDuration(), rotationCorrection.getDegrees());
9178
}
9279

93-
private int getRotationCorrectionFromUnappliedRotation(RotationDegrees unappliedRotationDegrees) {
94-
int rotationCorrection = 0;
80+
private RotationDegrees getRotationCorrectionFromUnappliedRotation(
81+
RotationDegrees unappliedRotationDegrees) {
82+
RotationDegrees rotationCorrection = RotationDegrees.ROTATE_0;
9583

9684
// Rotating the video with ExoPlayer does not seem to be possible with a Surface,
9785
// so inform the Flutter code that the widget needs to be rotated to prevent
9886
// upside-down playback for videos with unappliedRotationDegrees of 180 (other orientations
9987
// work correctly without correction).
10088
if (unappliedRotationDegrees == RotationDegrees.ROTATE_180) {
101-
rotationCorrection = unappliedRotationDegrees.getDegrees();
89+
rotationCorrection = unappliedRotationDegrees;
10290
}
10391

10492
return rotationCorrection;

packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/TextureExoPlayerEventListenerTest.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public void onPlaybackStateChangedReadySendInitialized_belowAndroid21() {
7777
when(mockExoPlayer.getVideoFormat()).thenReturn(videoFormat);
7878

7979
eventListener.onPlaybackStateChanged(Player.STATE_READY);
80-
verify(mockCallbacks).onInitialized(400, 800, 10L, rotationCorrection);
80+
verify(mockCallbacks).onInitialized(800, 400, 10L, rotationCorrection);
8181
}
8282

8383
@Test
@@ -91,7 +91,7 @@ public void onPlaybackStateChangedReadySendInitialized_belowAndroid21() {
9191
when(mockExoPlayer.getDuration()).thenReturn(10L);
9292

9393
eventListener.onPlaybackStateChanged(Player.STATE_READY);
94-
verify(mockCallbacks).onInitialized(400, 800, 10L, 0);
94+
verify(mockCallbacks).onInitialized(800, 400, 10L, 0);
9595
}
9696

9797
@Test
@@ -124,7 +124,7 @@ public void onPlaybackStateChangedReadySendInitialized_belowAndroid21() {
124124
when(mockExoPlayer.getVideoFormat()).thenReturn(videoFormat);
125125

126126
eventListener.onPlaybackStateChanged(Player.STATE_READY);
127-
verify(mockCallbacks).onInitialized(400, 800, 10L, 90);
127+
verify(mockCallbacks).onInitialized(800, 400, 10L, 90);
128128
}
129129

130130
@Test
@@ -138,7 +138,7 @@ public void onPlaybackStateChangedReadySendInitialized_belowAndroid21() {
138138
when(mockExoPlayer.getDuration()).thenReturn(10L);
139139

140140
eventListener.onPlaybackStateChanged(Player.STATE_READY);
141-
verify(mockCallbacks).onInitialized(400, 800, 10L, 0);
141+
verify(mockCallbacks).onInitialized(800, 400, 10L, 0);
142142
}
143143

144144
@Test
@@ -170,7 +170,7 @@ public void onPlaybackStateChangedReadySendInitialized_belowAndroid21() {
170170
when(mockExoPlayer.getVideoFormat()).thenReturn(videoFormat);
171171

172172
eventListener.onPlaybackStateChanged(Player.STATE_READY);
173-
verify(mockCallbacks).onInitialized(400, 800, 10L, 270);
173+
verify(mockCallbacks).onInitialized(800, 400, 10L, 270);
174174
}
175175

176176
@Test

packages/video_player/video_player_android/example/lib/mini_controller.dart

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
import 'dart:async';
99
import 'dart:io';
10-
import 'dart:math';
1110

1211
import 'package:flutter/foundation.dart';
1312
import 'package:flutter/material.dart';
@@ -467,12 +466,13 @@ class _VideoPlayerWithRotation extends StatelessWidget {
467466

468467
@override
469468
Widget build(BuildContext context) {
470-
return rotation == 0
471-
? child
472-
: Transform.rotate(
473-
angle: rotation * pi / 180,
474-
child: child,
475-
);
469+
if (rotation == 0) {
470+
return child;
471+
}
472+
return RotatedBox(
473+
quarterTurns: rotation ~/ 90,
474+
child: child,
475+
);
476476
}
477477
}
478478

packages/video_player/video_player_android/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: video_player_android
22
description: Android implementation of the video_player plugin.
33
repository: https://github.com/flutter/packages/tree/main/packages/video_player/video_player_android
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22
5-
version: 2.8.3
5+
version: 2.8.4
66

77
environment:
88
sdk: ^3.6.0

0 commit comments

Comments
 (0)