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

[video_player] Platform interface changes to fix Android rotation for videos recorded in landscapeRight #4633

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
## 5.0.0
## 4.2.1

* **BREAKING CHANGES**:
* Updates to extending `PlatformInterface`. Removes `isMock`, in favor of the
now-standard `MockPlatformInterfaceMixin`.
* Removes test.dart from the public interface. Tests in other packages should
mock `VideoPlatformInterface` rather than the method channel.
* Added rotation on Android for videos recorded in landscapeRight Fixes [#60327](https://github.com/flutter/flutter/issues/60327).

## 4.2.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ class MethodChannelVideoPlayer extends VideoPlayerPlatform {
duration: Duration(milliseconds: map['duration']),
size: Size(map['width']?.toDouble() ?? 0.0,
map['height']?.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 @@ -2,9 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';
import 'dart:ui';

import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'package:meta/meta.dart' show visibleForTesting;

import 'method_channel_video_player.dart';

Expand All @@ -15,24 +18,37 @@ import 'method_channel_video_player.dart';
/// (using `extends`) ensures that the subclass will get the default implementation, while
/// platform implementations that `implements` this interface will be broken by newly added
/// [VideoPlayerPlatform] methods.
abstract class VideoPlayerPlatform extends PlatformInterface {
/// Constructs a VideoPlayerPlatform.
VideoPlayerPlatform() : super(token: _token);

static final Object _token = Object();
abstract class VideoPlayerPlatform {
/// Only mock implementations should set this to true.
///
/// Mockito mocks are implementing this class with `implements` which is forbidden for anything
/// other than mocks (see class docs). This property provides a backdoor for mockito mocks to
/// skip the verification that the class isn't implemented with `implements`.
@visibleForTesting
bool get isMock => false;

static VideoPlayerPlatform _instance = MethodChannelVideoPlayer();

/// The default instance of [VideoPlayerPlatform] to use.
///
/// Defaults to [MethodChannelVideoPlayer].
static VideoPlayerPlatform get instance => _instance;

/// Platform-specific plugins should override this with their own
/// platform-specific class that extends [VideoPlayerPlatform] when they
/// register themselves.
///
/// Defaults to [MethodChannelVideoPlayer].
static VideoPlayerPlatform get instance => _instance;

// TODO(amirh): Extract common platform interface logic.
// https://github.com/flutter/flutter/issues/43368
static set instance(VideoPlayerPlatform instance) {
PlatformInterface.verifyToken(instance, _token);
if (!instance.isMock) {
try {
instance._verifyProvidesDefaultImplementations();
} on NoSuchMethodError catch (_) {
throw AssertionError(
'Platform interfaces must not be implemented with `implements`');
}
}
_instance = instance;
}

Expand Down Expand Up @@ -103,6 +119,14 @@ abstract class VideoPlayerPlatform extends PlatformInterface {
Future<void> setMixWithOthers(bool mixWithOthers) {
throw UnimplementedError('setMixWithOthers() has not been implemented.');
}

// This method makes sure that VideoPlayer isn't implemented with `implements`.
//
// See class doc for more details on why implementing this class is forbidden.
//
// This private method is called by the instance setter, which fails if the class is
// implemented with `implements`.
void _verifyProvidesDefaultImplementations() {}
}

/// Description of the data source used to create an instance of
Expand Down Expand Up @@ -198,12 +222,13 @@ class VideoEvent {
///
/// The [eventType] argument is required.
///
/// Depending on the [eventType], the [duration], [size] 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.rotationCorrection,
this.buffered,
});

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

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

/// Buffered parts of the video.
///
/// Only used if [eventType] is [VideoEventType.bufferingUpdate].
Expand All @@ -233,6 +263,7 @@ class VideoEvent {
eventType == other.eventType &&
duration == other.duration &&
size == other.size &&
rotationCorrection == other.rotationCorrection &&
listEquals(buffered, other.buffered);
}

Expand All @@ -241,6 +272,7 @@ class VideoEvent {
eventType.hashCode ^
duration.hashCode ^
size.hashCode ^
rotationCorrection.hashCode ^
buffered.hashCode;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ repository: https://github.com/flutter/plugins/tree/master/packages/video_player
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22
# NOTE: We strongly prefer non-breaking changes, even at the expense of a
# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
version: 5.0.0
version: 4.2.1

environment:
sdk: ">=2.12.0 <3.0.0"
Expand All @@ -13,9 +13,9 @@ environment:
dependencies:
flutter:
sdk: flutter
plugin_platform_interface: ^2.0.0

dev_dependencies:
flutter_test:
sdk: flutter
meta: ^1.3.0

dev_dependencies:
pedantic: ^1.10.0
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:video_player_platform_interface/messages.dart';
import 'package:video_player_platform_interface/method_channel_video_player.dart';
import 'package:video_player_platform_interface/test.dart';
import 'package:video_player_platform_interface/video_player_platform_interface.dart';

import 'test.dart';

class _ApiLogger implements TestHostVideoPlayerApi {
final List<String> log = [];
TextureMessage? textureMessage;
Expand Down Expand Up @@ -256,6 +255,20 @@ void main() {
}),
(ByteData? data) {});

await _ambiguate(ServicesBinding.instance)
?.defaultBinaryMessenger
.handlePlatformMessage(
"flutter.io/videoPlayer/videoEvents123",
const StandardMethodCodec()
.encodeSuccessEnvelope(<String, dynamic>{
'event': 'initialized',
'duration': 98765,
'width': 1920,
'height': 1080,
'rotationCorrection': 3.14,
}),
(ByteData? data) {});

await _ambiguate(ServicesBinding.instance)
?.defaultBinaryMessenger
.handlePlatformMessage(
Expand Down Expand Up @@ -315,6 +328,13 @@ void main() {
eventType: VideoEventType.initialized,
duration: const Duration(milliseconds: 98765),
size: const Size(1920, 1080),
rotationCorrection: 0.0,
),
VideoEvent(
eventType: VideoEventType.initialized,
duration: const Duration(milliseconds: 98765),
size: const Size(1920, 1080),
rotationCorrection: 3.14,
),
VideoEvent(eventType: VideoEventType.completed),
VideoEvent(
Expand Down