[video_player_platform_interface] Add setPlaybackSpeed method (#3032)
diff --git a/packages/video_player/video_player_platform_interface/CHANGELOG.md b/packages/video_player/video_player_platform_interface/CHANGELOG.md
index 2af6f01..8af22f7 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 c5e8cd4..bfe65f1 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,10 @@
-// Autogenerated from Pigeon (v0.1.0-experimental.11), do not edit directly.
+// Autogenerated from Pigeon (v0.1.7), 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
+// @dart = 2.8
import 'dart:async';
import 'package:flutter/services.dart';
+import 'dart:typed_data' show Uint8List, Int32List, Int64List, Float64List;
class TextureMessage {
int textureId;
@@ -15,6 +17,9 @@
// ignore: unused_element
static TextureMessage _fromMap(Map<dynamic, dynamic> pigeonMap) {
+ if (pigeonMap == null) {
+ return null;
+ }
final TextureMessage result = TextureMessage();
result.textureId = pigeonMap['textureId'];
return result;
@@ -38,6 +43,9 @@
// ignore: unused_element
static CreateMessage _fromMap(Map<dynamic, dynamic> pigeonMap) {
+ if (pigeonMap == null) {
+ return null;
+ }
final CreateMessage result = CreateMessage();
result.asset = pigeonMap['asset'];
result.uri = pigeonMap['uri'];
@@ -60,6 +68,9 @@
// ignore: unused_element
static LoopingMessage _fromMap(Map<dynamic, dynamic> pigeonMap) {
+ if (pigeonMap == null) {
+ return null;
+ }
final LoopingMessage result = LoopingMessage();
result.textureId = pigeonMap['textureId'];
result.isLooping = pigeonMap['isLooping'];
@@ -80,6 +91,9 @@
// ignore: unused_element
static VolumeMessage _fromMap(Map<dynamic, dynamic> pigeonMap) {
+ if (pigeonMap == null) {
+ return null;
+ }
final VolumeMessage result = VolumeMessage();
result.textureId = pigeonMap['textureId'];
result.volume = pigeonMap['volume'];
@@ -87,6 +101,29 @@
}
}
+class PlaybackSpeedMessage {
+ int textureId;
+ double speed;
+ // ignore: unused_element
+ Map<dynamic, dynamic> _toMap() {
+ final Map<dynamic, dynamic> pigeonMap = <dynamic, dynamic>{};
+ pigeonMap['textureId'] = textureId;
+ pigeonMap['speed'] = speed;
+ return pigeonMap;
+ }
+
+ // ignore: unused_element
+ static PlaybackSpeedMessage _fromMap(Map<dynamic, dynamic> 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 +137,9 @@
// ignore: unused_element
static PositionMessage _fromMap(Map<dynamic, dynamic> pigeonMap) {
+ if (pigeonMap == null) {
+ return null;
+ }
final PositionMessage result = PositionMessage();
result.textureId = pigeonMap['textureId'];
result.position = pigeonMap['position'];
@@ -118,128 +158,15 @@
// ignore: unused_element
static MixWithOthersMessage _fromMap(Map<dynamic, dynamic> 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<dynamic> channel = BasicMessageChannel<dynamic>(
- 'dev.flutter.pigeon.VideoPlayerApi.initialize', StandardMessageCodec());
- channel.setMockMessageHandler((dynamic message) async {
- api.initialize();
- return {};
- });
- }
- {
- const BasicMessageChannel<dynamic> channel = BasicMessageChannel<dynamic>(
- 'dev.flutter.pigeon.VideoPlayerApi.create', StandardMessageCodec());
- channel.setMockMessageHandler((dynamic message) async {
- final Map<dynamic, dynamic> mapMessage = message as Map<dynamic, dynamic>;
- final CreateMessage input = CreateMessage._fromMap(mapMessage);
- final TextureMessage output = api.create(input);
- return {'result': output._toMap()};
- });
- }
- {
- const BasicMessageChannel<dynamic> channel = BasicMessageChannel<dynamic>(
- 'dev.flutter.pigeon.VideoPlayerApi.dispose', StandardMessageCodec());
- channel.setMockMessageHandler((dynamic message) async {
- final Map<dynamic, dynamic> mapMessage = message as Map<dynamic, dynamic>;
- final TextureMessage input = TextureMessage._fromMap(mapMessage);
- api.dispose(input);
- return {};
- });
- }
- {
- const BasicMessageChannel<dynamic> channel = BasicMessageChannel<dynamic>(
- 'dev.flutter.pigeon.VideoPlayerApi.setLooping', StandardMessageCodec());
- channel.setMockMessageHandler((dynamic message) async {
- final Map<dynamic, dynamic> mapMessage = message as Map<dynamic, dynamic>;
- final LoopingMessage input = LoopingMessage._fromMap(mapMessage);
- api.setLooping(input);
- return {};
- });
- }
- {
- const BasicMessageChannel<dynamic> channel = BasicMessageChannel<dynamic>(
- 'dev.flutter.pigeon.VideoPlayerApi.setVolume', StandardMessageCodec());
- channel.setMockMessageHandler((dynamic message) async {
- final Map<dynamic, dynamic> mapMessage = message as Map<dynamic, dynamic>;
- final VolumeMessage input = VolumeMessage._fromMap(mapMessage);
- api.setVolume(input);
- return {};
- });
- }
- {
- const BasicMessageChannel<dynamic> channel = BasicMessageChannel<dynamic>(
- 'dev.flutter.pigeon.VideoPlayerApi.play', StandardMessageCodec());
- channel.setMockMessageHandler((dynamic message) async {
- final Map<dynamic, dynamic> mapMessage = message as Map<dynamic, dynamic>;
- final TextureMessage input = TextureMessage._fromMap(mapMessage);
- api.play(input);
- return {};
- });
- }
- {
- const BasicMessageChannel<dynamic> channel = BasicMessageChannel<dynamic>(
- 'dev.flutter.pigeon.VideoPlayerApi.position', StandardMessageCodec());
- channel.setMockMessageHandler((dynamic message) async {
- final Map<dynamic, dynamic> mapMessage = message as Map<dynamic, dynamic>;
- final TextureMessage input = TextureMessage._fromMap(mapMessage);
- final PositionMessage output = api.position(input);
- return {'result': output._toMap()};
- });
- }
- {
- const BasicMessageChannel<dynamic> channel = BasicMessageChannel<dynamic>(
- 'dev.flutter.pigeon.VideoPlayerApi.seekTo', StandardMessageCodec());
- channel.setMockMessageHandler((dynamic message) async {
- final Map<dynamic, dynamic> mapMessage = message as Map<dynamic, dynamic>;
- final PositionMessage input = PositionMessage._fromMap(mapMessage);
- api.seekTo(input);
- return {};
- });
- }
- {
- const BasicMessageChannel<dynamic> channel = BasicMessageChannel<dynamic>(
- 'dev.flutter.pigeon.VideoPlayerApi.pause', StandardMessageCodec());
- channel.setMockMessageHandler((dynamic message) async {
- final Map<dynamic, dynamic> mapMessage = message as Map<dynamic, dynamic>;
- final TextureMessage input = TextureMessage._fromMap(mapMessage);
- api.pause(input);
- return {};
- });
- }
- {
- const BasicMessageChannel<dynamic> channel = BasicMessageChannel<dynamic>(
- 'dev.flutter.pigeon.VideoPlayerApi.setMixWithOthers',
- StandardMessageCodec());
- channel.setMockMessageHandler((dynamic message) async {
- final Map<dynamic, dynamic> mapMessage = message as Map<dynamic, dynamic>;
- final MixWithOthersMessage input =
- MixWithOthersMessage._fromMap(mapMessage);
- api.setMixWithOthers(input);
- return {};
- });
- }
-}
-
class VideoPlayerApi {
Future<void> initialize() async {
const BasicMessageChannel<dynamic> channel = BasicMessageChannel<dynamic>(
@@ -350,6 +277,29 @@
}
}
+ Future<void> setPlaybackSpeed(PlaybackSpeedMessage arg) async {
+ final Map<dynamic, dynamic> requestMap = arg._toMap();
+ const BasicMessageChannel<dynamic> channel = BasicMessageChannel<dynamic>(
+ 'dev.flutter.pigeon.VideoPlayerApi.setPlaybackSpeed',
+ StandardMessageCodec());
+
+ final Map<dynamic, dynamic> 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<dynamic, dynamic> error = replyMap['error'];
+ throw PlatformException(
+ code: error['code'],
+ message: error['message'],
+ details: error['details']);
+ } else {
+ // noop
+ }
+ }
+
Future<void> play(TextureMessage arg) async {
final Map<dynamic, dynamic> requestMap = arg._toMap();
const BasicMessageChannel<dynamic> channel = BasicMessageChannel<dynamic>(
@@ -461,3 +411,144 @@
}
}
}
+
+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<dynamic> channel = BasicMessageChannel<dynamic>(
+ 'dev.flutter.pigeon.VideoPlayerApi.initialize',
+ StandardMessageCodec());
+ channel.setMockMessageHandler((dynamic message) async {
+ api.initialize();
+ return <dynamic, dynamic>{};
+ });
+ }
+ {
+ const BasicMessageChannel<dynamic> channel = BasicMessageChannel<dynamic>(
+ 'dev.flutter.pigeon.VideoPlayerApi.create', StandardMessageCodec());
+ channel.setMockMessageHandler((dynamic message) async {
+ final Map<dynamic, dynamic> mapMessage =
+ message as Map<dynamic, dynamic>;
+ final CreateMessage input = CreateMessage._fromMap(mapMessage);
+ final TextureMessage output = api.create(input);
+ return <dynamic, dynamic>{'result': output._toMap()};
+ });
+ }
+ {
+ const BasicMessageChannel<dynamic> channel = BasicMessageChannel<dynamic>(
+ 'dev.flutter.pigeon.VideoPlayerApi.dispose', StandardMessageCodec());
+ channel.setMockMessageHandler((dynamic message) async {
+ final Map<dynamic, dynamic> mapMessage =
+ message as Map<dynamic, dynamic>;
+ final TextureMessage input = TextureMessage._fromMap(mapMessage);
+ api.dispose(input);
+ return <dynamic, dynamic>{};
+ });
+ }
+ {
+ const BasicMessageChannel<dynamic> channel = BasicMessageChannel<dynamic>(
+ 'dev.flutter.pigeon.VideoPlayerApi.setLooping',
+ StandardMessageCodec());
+ channel.setMockMessageHandler((dynamic message) async {
+ final Map<dynamic, dynamic> mapMessage =
+ message as Map<dynamic, dynamic>;
+ final LoopingMessage input = LoopingMessage._fromMap(mapMessage);
+ api.setLooping(input);
+ return <dynamic, dynamic>{};
+ });
+ }
+ {
+ const BasicMessageChannel<dynamic> channel = BasicMessageChannel<dynamic>(
+ 'dev.flutter.pigeon.VideoPlayerApi.setVolume',
+ StandardMessageCodec());
+ channel.setMockMessageHandler((dynamic message) async {
+ final Map<dynamic, dynamic> mapMessage =
+ message as Map<dynamic, dynamic>;
+ final VolumeMessage input = VolumeMessage._fromMap(mapMessage);
+ api.setVolume(input);
+ return <dynamic, dynamic>{};
+ });
+ }
+ {
+ const BasicMessageChannel<dynamic> channel = BasicMessageChannel<dynamic>(
+ 'dev.flutter.pigeon.VideoPlayerApi.setPlaybackSpeed',
+ StandardMessageCodec());
+ channel.setMockMessageHandler((dynamic message) async {
+ final Map<dynamic, dynamic> mapMessage =
+ message as Map<dynamic, dynamic>;
+ final PlaybackSpeedMessage input =
+ PlaybackSpeedMessage._fromMap(mapMessage);
+ api.setPlaybackSpeed(input);
+ return <dynamic, dynamic>{};
+ });
+ }
+ {
+ const BasicMessageChannel<dynamic> channel = BasicMessageChannel<dynamic>(
+ 'dev.flutter.pigeon.VideoPlayerApi.play', StandardMessageCodec());
+ channel.setMockMessageHandler((dynamic message) async {
+ final Map<dynamic, dynamic> mapMessage =
+ message as Map<dynamic, dynamic>;
+ final TextureMessage input = TextureMessage._fromMap(mapMessage);
+ api.play(input);
+ return <dynamic, dynamic>{};
+ });
+ }
+ {
+ const BasicMessageChannel<dynamic> channel = BasicMessageChannel<dynamic>(
+ 'dev.flutter.pigeon.VideoPlayerApi.position', StandardMessageCodec());
+ channel.setMockMessageHandler((dynamic message) async {
+ final Map<dynamic, dynamic> mapMessage =
+ message as Map<dynamic, dynamic>;
+ final TextureMessage input = TextureMessage._fromMap(mapMessage);
+ final PositionMessage output = api.position(input);
+ return <dynamic, dynamic>{'result': output._toMap()};
+ });
+ }
+ {
+ const BasicMessageChannel<dynamic> channel = BasicMessageChannel<dynamic>(
+ 'dev.flutter.pigeon.VideoPlayerApi.seekTo', StandardMessageCodec());
+ channel.setMockMessageHandler((dynamic message) async {
+ final Map<dynamic, dynamic> mapMessage =
+ message as Map<dynamic, dynamic>;
+ final PositionMessage input = PositionMessage._fromMap(mapMessage);
+ api.seekTo(input);
+ return <dynamic, dynamic>{};
+ });
+ }
+ {
+ const BasicMessageChannel<dynamic> channel = BasicMessageChannel<dynamic>(
+ 'dev.flutter.pigeon.VideoPlayerApi.pause', StandardMessageCodec());
+ channel.setMockMessageHandler((dynamic message) async {
+ final Map<dynamic, dynamic> mapMessage =
+ message as Map<dynamic, dynamic>;
+ final TextureMessage input = TextureMessage._fromMap(mapMessage);
+ api.pause(input);
+ return <dynamic, dynamic>{};
+ });
+ }
+ {
+ const BasicMessageChannel<dynamic> channel = BasicMessageChannel<dynamic>(
+ 'dev.flutter.pigeon.VideoPlayerApi.setMixWithOthers',
+ StandardMessageCodec());
+ channel.setMockMessageHandler((dynamic message) async {
+ final Map<dynamic, dynamic> mapMessage =
+ message as Map<dynamic, dynamic>;
+ final MixWithOthersMessage input =
+ MixWithOthersMessage._fromMap(mapMessage);
+ api.setMixWithOthers(input);
+ return <dynamic, dynamic>{};
+ });
+ }
+ }
+}
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 8c0f1de..0ea443f 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
@@ -72,6 +72,15 @@
}
@override
+ Future<void> setPlaybackSpeed(int textureId, double speed) {
+ assert(speed > 0);
+
+ return _api.setPlaybackSpeed(PlaybackSpeedMessage()
+ ..textureId = textureId
+ ..speed = speed);
+ }
+
+ @override
Future<void> seekTo(int textureId, Duration position) {
return _api.seekTo(PositionMessage()
..textureId = textureId
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 279810a..2757fb1 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 @@
throw UnimplementedError('seekTo() has not been implemented.');
}
+ /// Sets the playback speed to a [speed] value indicating the playback rate.
+ Future<void> setPlaybackSpeed(int textureId, double speed) {
+ throw UnimplementedError('setPlaybackSpeed() has not been implemented.');
+ }
+
/// Gets the video position as [Duration] from the start.
Future<Duration> getPosition(int textureId) {
throw UnimplementedError('getPosition() has not been implemented.');
@@ -184,7 +189,7 @@
network,
/// The video was loaded off of the local filesystem.
- file
+ file,
}
/// The file format of the given video.
@@ -199,7 +204,7 @@
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 38bc685..cc3cd79 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 @@
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:
@@ -17,5 +17,5 @@
pedantic: ^1.8.0
environment:
- sdk: ">=2.1.0 <3.0.0"
+ sdk: ">=2.8.0 <3.0.0"
flutter: ">=1.10.0 <2.0.0"
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 1859531..c479100 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,21 +4,21 @@
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 {
+class _ApiLogger implements TestHostVideoPlayerApi {
final List<String> log = [];
TextureMessage textureMessage;
CreateMessage createMessage;
PositionMessage positionMessage;
LoopingMessage loopingMessage;
VolumeMessage volumeMessage;
+ PlaybackSpeedMessage playbackSpeedMessage;
MixWithOthersMessage mixWithOthersMessage;
@override
@@ -81,6 +81,12 @@
log.add('setVolume');
volumeMessage = arg;
}
+
+ @override
+ void setPlaybackSpeed(PlaybackSpeedMessage arg) {
+ log.add('setPlaybackSpeed');
+ playbackSpeedMessage = arg;
+ }
}
void main() {
@@ -116,7 +122,7 @@
setUp(() {
log = _ApiLogger();
- VideoPlayerApiTestSetup(log);
+ TestHostVideoPlayerApi.setup(log);
});
test('init', () async {
@@ -203,6 +209,13 @@
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');