From 9217602b48a2152bd18d0ad331379f758eacb30f Mon Sep 17 00:00:00 2001 From: creativecreatorormaybenot Date: Tue, 15 Sep 2020 16:59:31 +0000 Subject: [PATCH] Platform interface changes --- .../CHANGELOG.md | 4 + .../lib/messages.dart | 326 +++++++++++------- .../lib/method_channel_video_player.dart | 9 + .../lib/video_player_platform_interface.dart | 9 +- .../pubspec.yaml | 2 +- .../method_channel_video_player_test.dart | 19 +- 6 files changed, 246 insertions(+), 123 deletions(-) diff --git a/packages/video_player/video_player_platform_interface/CHANGELOG.md b/packages/video_player/video_player_platform_interface/CHANGELOG.md index 2af6f01ffe88..8af22f783675 100644 --- a/packages/video_player/video_player_platform_interface/CHANGELOG.md +++ b/packages/video_player/video_player_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.2.0 + +* Added option to set the video playback speed on the video controller. + ## 2.1.1 * Fix mixWithOthers test channel. diff --git a/packages/video_player/video_player_platform_interface/lib/messages.dart b/packages/video_player/video_player_platform_interface/lib/messages.dart index c5e8cd413b70..8618c7925204 100644 --- a/packages/video_player/video_player_platform_interface/lib/messages.dart +++ b/packages/video_player/video_player_platform_interface/lib/messages.dart @@ -1,8 +1,9 @@ -// Autogenerated from Pigeon (v0.1.0-experimental.11), do not edit directly. +// Autogenerated from Pigeon (v0.1.5), do not edit directly. // See also: https://pub.dev/packages/pigeon // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import import 'dart:async'; import 'package:flutter/services.dart'; +import 'dart:typed_data' show Uint8List, Int32List, Int64List, Float64List; class TextureMessage { int textureId; @@ -15,6 +16,9 @@ class TextureMessage { // ignore: unused_element static TextureMessage _fromMap(Map pigeonMap) { + if (pigeonMap == null) { + return null; + } final TextureMessage result = TextureMessage(); result.textureId = pigeonMap['textureId']; return result; @@ -38,6 +42,9 @@ class CreateMessage { // ignore: unused_element static CreateMessage _fromMap(Map pigeonMap) { + if (pigeonMap == null) { + return null; + } final CreateMessage result = CreateMessage(); result.asset = pigeonMap['asset']; result.uri = pigeonMap['uri']; @@ -60,6 +67,9 @@ class LoopingMessage { // ignore: unused_element static LoopingMessage _fromMap(Map pigeonMap) { + if (pigeonMap == null) { + return null; + } final LoopingMessage result = LoopingMessage(); result.textureId = pigeonMap['textureId']; result.isLooping = pigeonMap['isLooping']; @@ -80,6 +90,9 @@ class VolumeMessage { // ignore: unused_element static VolumeMessage _fromMap(Map pigeonMap) { + if (pigeonMap == null) { + return null; + } final VolumeMessage result = VolumeMessage(); result.textureId = pigeonMap['textureId']; result.volume = pigeonMap['volume']; @@ -87,6 +100,29 @@ class VolumeMessage { } } +class PlaybackSpeedMessage { + int textureId; + double speed; + // ignore: unused_element + Map _toMap() { + final Map pigeonMap = {}; + pigeonMap['textureId'] = textureId; + pigeonMap['speed'] = speed; + return pigeonMap; + } + + // ignore: unused_element + static PlaybackSpeedMessage _fromMap(Map pigeonMap) { + if (pigeonMap == null) { + return null; + } + final PlaybackSpeedMessage result = PlaybackSpeedMessage(); + result.textureId = pigeonMap['textureId']; + result.speed = pigeonMap['speed']; + return result; + } +} + class PositionMessage { int textureId; int position; @@ -100,6 +136,9 @@ class PositionMessage { // ignore: unused_element static PositionMessage _fromMap(Map pigeonMap) { + if (pigeonMap == null) { + return null; + } final PositionMessage result = PositionMessage(); result.textureId = pigeonMap['textureId']; result.position = pigeonMap['position']; @@ -118,128 +157,15 @@ class MixWithOthersMessage { // ignore: unused_element static MixWithOthersMessage _fromMap(Map pigeonMap) { + if (pigeonMap == null) { + return null; + } final MixWithOthersMessage result = MixWithOthersMessage(); result.mixWithOthers = pigeonMap['mixWithOthers']; return result; } } -abstract class VideoPlayerApiTest { - void initialize(); - TextureMessage create(CreateMessage arg); - void dispose(TextureMessage arg); - void setLooping(LoopingMessage arg); - void setVolume(VolumeMessage arg); - void play(TextureMessage arg); - PositionMessage position(TextureMessage arg); - void seekTo(PositionMessage arg); - void pause(TextureMessage arg); - void setMixWithOthers(MixWithOthersMessage arg); -} - -void VideoPlayerApiTestSetup(VideoPlayerApiTest api) { - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.initialize', StandardMessageCodec()); - channel.setMockMessageHandler((dynamic message) async { - api.initialize(); - return {}; - }); - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.create', StandardMessageCodec()); - channel.setMockMessageHandler((dynamic message) async { - final Map mapMessage = message as Map; - final CreateMessage input = CreateMessage._fromMap(mapMessage); - final TextureMessage output = api.create(input); - return {'result': output._toMap()}; - }); - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.dispose', StandardMessageCodec()); - channel.setMockMessageHandler((dynamic message) async { - final Map mapMessage = message as Map; - final TextureMessage input = TextureMessage._fromMap(mapMessage); - api.dispose(input); - return {}; - }); - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.setLooping', StandardMessageCodec()); - channel.setMockMessageHandler((dynamic message) async { - final Map mapMessage = message as Map; - final LoopingMessage input = LoopingMessage._fromMap(mapMessage); - api.setLooping(input); - return {}; - }); - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.setVolume', StandardMessageCodec()); - channel.setMockMessageHandler((dynamic message) async { - final Map mapMessage = message as Map; - final VolumeMessage input = VolumeMessage._fromMap(mapMessage); - api.setVolume(input); - return {}; - }); - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.play', StandardMessageCodec()); - channel.setMockMessageHandler((dynamic message) async { - final Map mapMessage = message as Map; - final TextureMessage input = TextureMessage._fromMap(mapMessage); - api.play(input); - return {}; - }); - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.position', StandardMessageCodec()); - channel.setMockMessageHandler((dynamic message) async { - final Map mapMessage = message as Map; - final TextureMessage input = TextureMessage._fromMap(mapMessage); - final PositionMessage output = api.position(input); - return {'result': output._toMap()}; - }); - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.seekTo', StandardMessageCodec()); - channel.setMockMessageHandler((dynamic message) async { - final Map mapMessage = message as Map; - final PositionMessage input = PositionMessage._fromMap(mapMessage); - api.seekTo(input); - return {}; - }); - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.pause', StandardMessageCodec()); - channel.setMockMessageHandler((dynamic message) async { - final Map mapMessage = message as Map; - final TextureMessage input = TextureMessage._fromMap(mapMessage); - api.pause(input); - return {}; - }); - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.setMixWithOthers', - StandardMessageCodec()); - channel.setMockMessageHandler((dynamic message) async { - final Map mapMessage = message as Map; - final MixWithOthersMessage input = - MixWithOthersMessage._fromMap(mapMessage); - api.setMixWithOthers(input); - return {}; - }); - } -} - class VideoPlayerApi { Future initialize() async { const BasicMessageChannel channel = BasicMessageChannel( @@ -350,6 +276,29 @@ class VideoPlayerApi { } } + Future setPlaybackSpeed(PlaybackSpeedMessage arg) async { + final Map requestMap = arg._toMap(); + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.VideoPlayerApi.setPlaybackSpeed', + StandardMessageCodec()); + + final Map replyMap = await channel.send(requestMap); + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null); + } else if (replyMap['error'] != null) { + final Map error = replyMap['error']; + throw PlatformException( + code: error['code'], + message: error['message'], + details: error['details']); + } else { + // noop + } + } + Future play(TextureMessage arg) async { final Map requestMap = arg._toMap(); const BasicMessageChannel channel = BasicMessageChannel( @@ -461,3 +410,146 @@ class VideoPlayerApi { } } } + +abstract class TestHostVideoPlayerApi { + void initialize(); + TextureMessage create(CreateMessage arg); + void dispose(TextureMessage arg); + void setLooping(LoopingMessage arg); + void setVolume(VolumeMessage arg); + void setPlaybackSpeed(PlaybackSpeedMessage arg); + void play(TextureMessage arg); + PositionMessage position(TextureMessage arg); + void seekTo(PositionMessage arg); + void pause(TextureMessage arg); + void setMixWithOthers(MixWithOthersMessage arg); + static void setup(TestHostVideoPlayerApi api) { + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.VideoPlayerApi.initialize', + StandardMessageCodec()); + channel.setMockMessageHandler((dynamic message) async { + final Map mapMessage = + message as Map; + api.initialize(); + return {}; + }); + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.VideoPlayerApi.create', StandardMessageCodec()); + channel.setMockMessageHandler((dynamic message) async { + final Map mapMessage = + message as Map; + final CreateMessage input = CreateMessage._fromMap(mapMessage); + final TextureMessage output = api.create(input); + return {'result': output._toMap()}; + }); + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.VideoPlayerApi.dispose', StandardMessageCodec()); + channel.setMockMessageHandler((dynamic message) async { + final Map mapMessage = + message as Map; + final TextureMessage input = TextureMessage._fromMap(mapMessage); + api.dispose(input); + return {}; + }); + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.VideoPlayerApi.setLooping', + StandardMessageCodec()); + channel.setMockMessageHandler((dynamic message) async { + final Map mapMessage = + message as Map; + final LoopingMessage input = LoopingMessage._fromMap(mapMessage); + api.setLooping(input); + return {}; + }); + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.VideoPlayerApi.setVolume', + StandardMessageCodec()); + channel.setMockMessageHandler((dynamic message) async { + final Map mapMessage = + message as Map; + final VolumeMessage input = VolumeMessage._fromMap(mapMessage); + api.setVolume(input); + return {}; + }); + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.VideoPlayerApi.setPlaybackSpeed', + StandardMessageCodec()); + channel.setMockMessageHandler((dynamic message) async { + final Map mapMessage = + message as Map; + final PlaybackSpeedMessage input = + PlaybackSpeedMessage._fromMap(mapMessage); + api.setPlaybackSpeed(input); + return {}; + }); + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.VideoPlayerApi.play', StandardMessageCodec()); + channel.setMockMessageHandler((dynamic message) async { + final Map mapMessage = + message as Map; + final TextureMessage input = TextureMessage._fromMap(mapMessage); + api.play(input); + return {}; + }); + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.VideoPlayerApi.position', StandardMessageCodec()); + channel.setMockMessageHandler((dynamic message) async { + final Map mapMessage = + message as Map; + final TextureMessage input = TextureMessage._fromMap(mapMessage); + final PositionMessage output = api.position(input); + return {'result': output._toMap()}; + }); + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.VideoPlayerApi.seekTo', StandardMessageCodec()); + channel.setMockMessageHandler((dynamic message) async { + final Map mapMessage = + message as Map; + final PositionMessage input = PositionMessage._fromMap(mapMessage); + api.seekTo(input); + return {}; + }); + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.VideoPlayerApi.pause', StandardMessageCodec()); + channel.setMockMessageHandler((dynamic message) async { + final Map mapMessage = + message as Map; + final TextureMessage input = TextureMessage._fromMap(mapMessage); + api.pause(input); + return {}; + }); + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.VideoPlayerApi.setMixWithOthers', + StandardMessageCodec()); + channel.setMockMessageHandler((dynamic message) async { + final Map mapMessage = + message as Map; + final MixWithOthersMessage input = + MixWithOthersMessage._fromMap(mapMessage); + api.setMixWithOthers(input); + return {}; + }); + } + } +} diff --git a/packages/video_player/video_player_platform_interface/lib/method_channel_video_player.dart b/packages/video_player/video_player_platform_interface/lib/method_channel_video_player.dart index 8c0f1de39661..d28d7ddea8df 100644 --- a/packages/video_player/video_player_platform_interface/lib/method_channel_video_player.dart +++ b/packages/video_player/video_player_platform_interface/lib/method_channel_video_player.dart @@ -71,6 +71,15 @@ class MethodChannelVideoPlayer extends VideoPlayerPlatform { ..volume = volume); } + @override + Future setPlaybackSpeed(int textureId, double speed) { + assert(speed >= 0); + + return _api.setPlaybackSpeed(PlaybackSpeedMessage() + ..textureId = textureId + ..speed = speed); + } + @override Future seekTo(int textureId, Duration position) { return _api.seekTo(PositionMessage() diff --git a/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart b/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart index 279810aaaf63..2757fb135af6 100644 --- a/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart +++ b/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart @@ -100,6 +100,11 @@ abstract class VideoPlayerPlatform { throw UnimplementedError('seekTo() has not been implemented.'); } + /// Sets the playback speed to a [speed] value indicating the playback rate. + Future setPlaybackSpeed(int textureId, double speed) { + throw UnimplementedError('setPlaybackSpeed() has not been implemented.'); + } + /// Gets the video position as [Duration] from the start. Future getPosition(int textureId) { throw UnimplementedError('getPosition() has not been implemented.'); @@ -184,7 +189,7 @@ enum DataSourceType { network, /// The video was loaded off of the local filesystem. - file + file, } /// The file format of the given video. @@ -199,7 +204,7 @@ enum VideoFormat { ss, /// Any format other than the other ones defined in this enum. - other + other, } /// Event emitted from the platform implementation. diff --git a/packages/video_player/video_player_platform_interface/pubspec.yaml b/packages/video_player/video_player_platform_interface/pubspec.yaml index 38bc6851f376..4b61245653fc 100644 --- a/packages/video_player/video_player_platform_interface/pubspec.yaml +++ b/packages/video_player/video_player_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the video_player plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player_platform_interface # 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: 2.1.1 +version: 2.2.0 dependencies: flutter: diff --git a/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart b/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart index 185953163350..3917bd5485b3 100644 --- a/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart +++ b/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart @@ -4,13 +4,12 @@ import 'dart:ui'; -import 'package:mockito/mockito.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; - +import 'package:mockito/mockito.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/video_player_platform_interface.dart'; -import 'package:video_player_platform_interface/messages.dart'; class _ApiLogger implements VideoPlayerApiTest { final List log = []; @@ -19,6 +18,7 @@ class _ApiLogger implements VideoPlayerApiTest { PositionMessage positionMessage; LoopingMessage loopingMessage; VolumeMessage volumeMessage; + PlaybackSpeedMessage playbackSpeedMessage; MixWithOthersMessage mixWithOthersMessage; @override @@ -81,6 +81,12 @@ class _ApiLogger implements VideoPlayerApiTest { log.add('setVolume'); volumeMessage = arg; } + + @override + void setPlaybackSpeed(PlaybackSpeedMessage arg) { + log.add('setPlaybackSpeed'); + playbackSpeedMessage = arg; + } } void main() { @@ -203,6 +209,13 @@ void main() { expect(log.volumeMessage.volume, 0.7); }); + test('setPlaybackSpeed', () async { + await player.setPlaybackSpeed(1, 1.5); + expect(log.log.last, 'setPlaybackSpeed'); + expect(log.playbackSpeedMessage.textureId, 1); + expect(log.playbackSpeedMessage.speed, 1.5); + }); + test('seekTo', () async { await player.seekTo(1, const Duration(milliseconds: 12345)); expect(log.log.last, 'seekTo');