Skip to content

Commit

Permalink
[video_player] Android: Rotate videos recorded in landscapeRight (flu…
Browse files Browse the repository at this point in the history
  • Loading branch information
KyleFin authored Jun 6, 2022
1 parent 087d037 commit 62132e8
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 6 deletions.
3 changes: 2 additions & 1 deletion packages/video_player/video_player/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## NEXT
## 2.4.3

* Fixes Android to correctly display videos recorded in landscapeRight (https://github.com/flutter/flutter/issues/60327).
* Fixes order-dependent unit tests.

## 2.4.2
Expand Down
31 changes: 29 additions & 2 deletions packages/video_player/video_player/lib/video_player.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'dart:async';
import 'dart:io';
import 'dart:math' as math;

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
Expand Down Expand Up @@ -48,6 +49,7 @@ class VideoPlayerValue {
this.isBuffering = false,
this.volume = 1.0,
this.playbackSpeed = 1.0,
this.rotationCorrection = 0,
this.errorDescription,
});

Expand Down Expand Up @@ -111,6 +113,9 @@ class VideoPlayerValue {
/// The [size] of the currently loaded video.
final Size size;

/// Degrees to rotate the video (clockwise) so it is displayed correctly.
final int rotationCorrection;

/// Indicates whether or not the video has been loaded and is ready to play.
final bool isInitialized;

Expand All @@ -136,7 +141,7 @@ class VideoPlayerValue {
}

/// Returns a new instance that has the same values as this current instance,
/// except for any overrides passed in as arguments to [copyWidth].
/// except for any overrides passed in as arguments to [copyWith].
VideoPlayerValue copyWith({
Duration? duration,
Size? size,
Expand All @@ -150,6 +155,7 @@ class VideoPlayerValue {
bool? isBuffering,
double? volume,
double? playbackSpeed,
int? rotationCorrection,
String? errorDescription = _defaultErrorDescription,
}) {
return VideoPlayerValue(
Expand All @@ -165,6 +171,7 @@ class VideoPlayerValue {
isBuffering: isBuffering ?? this.isBuffering,
volume: volume ?? this.volume,
playbackSpeed: playbackSpeed ?? this.playbackSpeed,
rotationCorrection: rotationCorrection ?? this.rotationCorrection,
errorDescription: errorDescription != _defaultErrorDescription
? errorDescription
: this.errorDescription,
Expand Down Expand Up @@ -368,6 +375,7 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
value = value.copyWith(
duration: event.duration,
size: event.size,
rotationCorrection: event.rotationCorrection,
isInitialized: event.duration != null,
errorDescription: null,
);
Expand Down Expand Up @@ -761,10 +769,29 @@ class _VideoPlayerState extends State<VideoPlayer> {
Widget build(BuildContext context) {
return _textureId == VideoPlayerController.kUninitializedTextureId
? Container()
: _videoPlayerPlatform.buildView(_textureId);
: _VideoPlayerWithRotation(
rotation: widget.controller.value.rotationCorrection,
child: _videoPlayerPlatform.buildView(_textureId),
);
}
}

class _VideoPlayerWithRotation extends StatelessWidget {
const _VideoPlayerWithRotation(
{Key? key, required this.rotation, required this.child})
: super(key: key);
final int rotation;
final Widget child;

@override
Widget build(BuildContext context) => rotation == 0
? child
: Transform.rotate(
angle: rotation * math.pi / 180,
child: child,
);
}

/// Used to configure the [VideoProgressIndicator] widget's colors for how it
/// describes the video's status.
///
Expand Down
6 changes: 3 additions & 3 deletions packages/video_player/video_player/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description: Flutter plugin for displaying inline video with other Flutter
widgets on Android, iOS, and web.
repository: https://github.com/flutter/plugins/tree/main/packages/video_player/video_player
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22
version: 2.4.2
version: 2.4.3

environment:
sdk: ">=2.14.0 <3.0.0"
Expand All @@ -23,9 +23,9 @@ dependencies:
flutter:
sdk: flutter
html: ^0.15.0
video_player_android: ^2.2.17
video_player_android: ^2.3.5
video_player_avfoundation: ^2.2.17
video_player_platform_interface: ^5.1.0
video_player_platform_interface: ^5.1.1
video_player_web: ^2.0.0

dev_dependencies:
Expand Down
24 changes: 24 additions & 0 deletions packages/video_player/video_player/test/video_player_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'dart:async';
import 'dart:io';
import 'dart:math' as math;

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
Expand All @@ -15,6 +16,8 @@ class FakeController extends ValueNotifier<VideoPlayerValue>
implements VideoPlayerController {
FakeController() : super(VideoPlayerValue(duration: Duration.zero));

FakeController.value(VideoPlayerValue value) : super(value);

@override
Future<void> dispose() async {
super.dispose();
Expand Down Expand Up @@ -149,6 +152,27 @@ void main() {
findsOneWidget);
});

testWidgets('non-zero rotationCorrection value is used',
(WidgetTester tester) async {
final FakeController controller = FakeController.value(
VideoPlayerValue(duration: Duration.zero, rotationCorrection: 180));
controller.textureId = 1;
await tester.pumpWidget(VideoPlayer(controller));
final Transform actualRotationCorrection =
find.byType(Transform).evaluate().single.widget as Transform;
expect(
actualRotationCorrection.transform, equals(Matrix4.rotationZ(math.pi)));
});

testWidgets('no transform when rotationCorrection is zero',
(WidgetTester tester) async {
final FakeController controller = FakeController.value(
VideoPlayerValue(duration: Duration.zero, rotationCorrection: 0));
controller.textureId = 1;
await tester.pumpWidget(VideoPlayer(controller));
expect(find.byType(Transform), findsNothing);
});

group('ClosedCaption widget', () {
testWidgets('uses a default text style', (WidgetTester tester) async {
const String text = 'foo';
Expand Down

0 comments on commit 62132e8

Please sign in to comment.