Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

Commit

Permalink
Simplify testing constructor for VideoPlayer.java.
Browse files Browse the repository at this point in the history
Use `rotationCorrection` instead of `rotation`.
  • Loading branch information
KyleFin committed Sep 24, 2021
1 parent fd20737 commit 5f95287
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,35 +67,11 @@ final class VideoPlayer {
String formatHint,
Map<String, String> httpHeaders,
VideoPlayerOptions options) {
this(
context,
eventChannel,
textureEntry,
dataSource,
formatHint,
httpHeaders,
options,
null);
}

VideoPlayer(
Context context,
EventChannel eventChannel,
TextureRegistry.SurfaceTextureEntry textureEntry,
String dataSource,
String formatHint,
Map<String, String> httpHeaders,
VideoPlayerOptions options,
SimpleExoPlayer exoPlayer) {
this.eventChannel = eventChannel;
this.textureEntry = textureEntry;
this.options = options;

if (exoPlayer != null) { // Skip remaining setup in tests if using a mock exoPlayer.
this.exoPlayer = exoPlayer;
return;
}
this.exoPlayer = new SimpleExoPlayer.Builder(context).build();
exoPlayer = new SimpleExoPlayer.Builder(context).build();

Uri uri = Uri.parse(dataSource);

Expand All @@ -115,12 +91,24 @@ final class VideoPlayer {
}

MediaSource mediaSource = buildMediaSource(uri, dataSourceFactory, formatHint, context);
this.exoPlayer.setMediaSource(mediaSource);
this.exoPlayer.prepare();
exoPlayer.setMediaSource(mediaSource);
exoPlayer.prepare();

setupVideoPlayer(eventChannel, textureEntry);
}

@VisibleForTesting
VideoPlayer(
EventChannel eventChannel,
TextureRegistry.SurfaceTextureEntry textureEntry,
VideoPlayerOptions options,
SimpleExoPlayer exoPlayer) {
this.eventChannel = eventChannel;
this.textureEntry = textureEntry;
this.options = options;
this.exoPlayer = exoPlayer;
}

private static boolean isHTTP(Uri uri) {
if (uri == null || uri.getScheme() == null) {
return false;
Expand Down Expand Up @@ -306,11 +294,15 @@ void sendInitialized() {
width = exoPlayer.getVideoFormat().height;
height = exoPlayer.getVideoFormat().width;
}
if (rotationDegrees == 180) {
event.put("rotation", Math.PI);
}
event.put("width", width);
event.put("height", height);

// 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.
if (rotationDegrees == 180) {
event.put("rotationCorrection", Math.PI);
}
}
eventSink.success(event);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.content.Context;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.SimpleExoPlayer;
import io.flutter.plugin.common.EventChannel;
import io.flutter.view.TextureRegistry;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
Expand All @@ -28,17 +26,13 @@ public void initPluginDoesNotThrow() {
}

@Test
public void videoPlayerSendInitializedSetsRotationForRotationDegrees180() {
public void videoPlayerSendInitializedSetsRotationCorrectionForRotationDegrees180() {
Format format = new Format.Builder().setRotationDegrees(180).build();
SimpleExoPlayer mockExoPlayer = mock(SimpleExoPlayer.class);
when(mockExoPlayer.getVideoFormat()).thenReturn(format);
final VideoPlayer player = new VideoPlayer(
mock(Context.class),
mock(EventChannel.class),
mock(TextureRegistry.SurfaceTextureEntry.class),
"",
"",
new HashMap<String, String>(),
mock(VideoPlayerOptions.class),
mockExoPlayer
);
Expand All @@ -52,21 +46,17 @@ public void videoPlayerSendInitializedSetsRotationForRotationDegrees180() {
verify(mockEventSink).success(eventCaptor.capture());
@SuppressWarnings("unchecked") Map<String, Object> capturedEventMap =
(Map<String, Object>) eventCaptor.getValue();
assertEquals(Math.PI, capturedEventMap.get("rotation"));
assertEquals(Math.PI, capturedEventMap.get("rotationCorrection"));
}

@Test
public void videoPlayerSendInitializedDoesNotSetRotationForRotationDegreesNot180() {
public void videoPlayerSendInitializedDoesNotSetRotationCorrectionForRotationDegreesNot180() {
Format format = new Format.Builder().setRotationDegrees(90).build();
SimpleExoPlayer mockExoPlayer = mock(SimpleExoPlayer.class);
when(mockExoPlayer.getVideoFormat()).thenReturn(format);
final VideoPlayer player = new VideoPlayer(
mock(Context.class),
mock(EventChannel.class),
mock(TextureRegistry.SurfaceTextureEntry.class),
"",
"",
new HashMap<String, String>(),
mock(VideoPlayerOptions.class),
mockExoPlayer
);
Expand All @@ -80,6 +70,6 @@ public void videoPlayerSendInitializedDoesNotSetRotationForRotationDegreesNot180
verify(mockEventSink).success(eventCaptor.capture());
@SuppressWarnings("unchecked") Map<String, Object> capturedEventMap =
(Map<String, Object>) eventCaptor.getValue();
assertFalse(capturedEventMap.containsKey("rotation"));
assertFalse(capturedEventMap.containsKey("rotationCorrection"));
}
}
14 changes: 7 additions & 7 deletions packages/video_player/video_player/lib/video_player.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class VideoPlayerValue {
this.isBuffering = false,
this.volume = 1.0,
this.playbackSpeed = 1.0,
this.rotation = 0.0,
this.rotationCorrection = 0.0,
this.errorDescription,
});

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

/// The [rotation] of the video.
final double rotation;
/// Radians to rotate the video so it is displayed correctly.
final double rotationCorrection;

/// Indicates whether or not the video has been loaded and is ready to play.
final bool isInitialized;
Expand Down Expand Up @@ -135,7 +135,7 @@ class VideoPlayerValue {
bool? isBuffering,
double? volume,
double? playbackSpeed,
double? rotation,
double? rotationCorrection,
String? errorDescription,
}) {
return VideoPlayerValue(
Expand All @@ -150,7 +150,7 @@ class VideoPlayerValue {
isBuffering: isBuffering ?? this.isBuffering,
volume: volume ?? this.volume,
playbackSpeed: playbackSpeed ?? this.playbackSpeed,
rotation: rotation ?? this.rotation,
rotationCorrection: rotationCorrection ?? this.rotationCorrection,
errorDescription: errorDescription ?? this.errorDescription,
);
}
Expand Down Expand Up @@ -326,7 +326,7 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
value = value.copyWith(
duration: event.duration,
size: event.size,
rotation: event.rotation,
rotationCorrection: event.rotationCorrection,
isInitialized: event.duration != null,
);
initializingCompleter.complete(null);
Expand Down Expand Up @@ -669,7 +669,7 @@ class _VideoPlayerState extends State<VideoPlayer> {
return _textureId == VideoPlayerController.kUninitializedTextureId
? Container()
: Transform.rotate(
angle: widget.controller.value.rotation,
angle: widget.controller.value.rotationCorrection,
child: _videoPlayerPlatform.buildView(_textureId),
);
}
Expand Down
15 changes: 8 additions & 7 deletions packages/video_player/video_player/test/video_player_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -134,16 +134,17 @@ void main() {
findsOneWidget);
});

testWidgets('rotation value is used', (WidgetTester tester) async {
final double expectedRotation = 3.14;
final FakeController controller = FakeController.value(
VideoPlayerValue(duration: Duration.zero, rotation: expectedRotation));
testWidgets('rotationCorrection value is used', (WidgetTester tester) async {
final double expectedRotationCorrection = 3.14;
final FakeController controller = FakeController.value(VideoPlayerValue(
duration: Duration.zero,
rotationCorrection: expectedRotationCorrection));
controller.textureId = 1;
await tester.pumpWidget(VideoPlayer(controller));
Transform actualRotation =
Transform actualRotationCorrection =
find.byType(Transform).evaluate().single.widget as Transform;
expect(
actualRotation.transform, equals(Matrix4.rotationZ(expectedRotation)));
expect(actualRotationCorrection.transform,
equals(Matrix4.rotationZ(expectedRotationCorrection)));
});

group('ClosedCaption widget', () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class MethodChannelVideoPlayer extends VideoPlayerPlatform {
duration: Duration(milliseconds: map['duration']),
size: Size(map['width']?.toDouble() ?? 0.0,
map['height']?.toDouble() ?? 0.0),
rotation: map['rotation']?.toDouble() ?? 0.0,
rotationCorrection: map['rotationCorrection']?.toDouble() ?? 0.0,
);
case 'completed':
return VideoEvent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,13 +219,13 @@ class VideoEvent {
///
/// The [eventType] argument is required.
///
/// Depending on the [eventType], the [duration], [size], [rotation], and
/// [buffered] arguments can be null.
/// Depending on the [eventType], the [duration], [size],
/// [rotationCorrection], and [buffered] arguments can be null.
VideoEvent({
required this.eventType,
this.duration,
this.size,
this.rotation,
this.rotationCorrection,
this.buffered,
});

Expand All @@ -242,10 +242,10 @@ class VideoEvent {
/// Only used if [eventType] is [VideoEventType.initialized].
final Size? size;

/// Rotation of the video.
/// Radians to rotate the video so it is displayed correctly.
///
/// Only used if [eventType] is [VideoEventType.initialized].
final double? rotation;
final double? rotationCorrection;

/// Buffered parts of the video.
///
Expand Down

0 comments on commit 5f95287

Please sign in to comment.