From a4710b95d8d056b72373c09ee59f123e34337e24 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Fri, 6 Sep 2024 17:11:25 +0900 Subject: [PATCH] [video_player] Update video_player to 2.5.0 (#730) Co-authored-by: Seungsoo Lee --- packages/video_player/CHANGELOG.md | 8 ++- packages/video_player/README.md | 6 +- .../integration_test/video_player_test.dart | 68 ++++++++++++++----- packages/video_player/example/lib/main.dart | 40 ++++++----- packages/video_player/example/pubspec.yaml | 6 +- .../video_player/lib/video_player_tizen.dart | 5 ++ packages/video_player/pubspec.yaml | 8 +-- .../video_player/tizen/src/video_player.cc | 14 ++++ .../video_player/tizen/src/video_player.h | 1 + 9 files changed, 111 insertions(+), 45 deletions(-) diff --git a/packages/video_player/CHANGELOG.md b/packages/video_player/CHANGELOG.md index 3f0e106d9..6424d1d42 100644 --- a/packages/video_player/CHANGELOG.md +++ b/packages/video_player/CHANGELOG.md @@ -1,7 +1,11 @@ -## NEXT +## 2.5.0 +* Update video_player to 2.9.1. +* Update video_player_platform_interface to 6.2.0. +* Update the example app and integration_test. * Fix new lint warnings. -* Update minimum Flutter and Dart version to 3.13 and 3.1. +* Update minimum Flutter and Dart version to 3.19 and 3.3. +* Synchronize VideoPlayerValue.isPlaying with underlying video player. ## 2.4.9 diff --git a/packages/video_player/README.md b/packages/video_player/README.md index 426a663cc..b426e5e10 100644 --- a/packages/video_player/README.md +++ b/packages/video_player/README.md @@ -14,8 +14,8 @@ This package is not an _endorsed_ implementation of `video_player`. Therefore, y ```yaml dependencies: - video_player: ^2.4.2 - video_player_tizen: ^2.4.9 + video_player: ^2.9.1 + video_player_tizen: ^2.5.0 ``` Then you can import `video_player` in your Dart code: @@ -50,7 +50,7 @@ This plugin is not supported on TV emulators. The following options are not supported on Tizen. -- The `httpHeaders` option of `VideoPlayerController.network` +- The `httpHeaders` option of `VideoPlayerController.networkUrl` - `VideoPlayerOptions.allowBackgroundPlayback` - `VideoPlayerOptions.mixWithOthers` diff --git a/packages/video_player/example/integration_test/video_player_test.dart b/packages/video_player/example/integration_test/video_player_test.dart index d249847e0..64955f3f2 100644 --- a/packages/video_player/example/integration_test/video_player_test.dart +++ b/packages/video_player/example/integration_test/video_player_test.dart @@ -24,9 +24,9 @@ const String _videoAssetKey = // TODO(stuartmorgan): Convert this to a local `HttpServer` that vends the // assets directly, https://github.com/flutter/flutter/issues/95420 String getUrlForAssetAsNetworkSource(String assetKey) { - return 'https://github.com/flutter/plugins/blob/' + return 'https://github.com/flutter/packages/blob/' // This hash can be rolled forward to pick up newly-added assets. - 'cb381ced070d356799dddf24aca38ce0579d3d7b' + '2e1673307ff7454aff40b47024eaed49a9e77e81' '/packages/video_player/video_player/example/' '$assetKey' '?raw=true'; @@ -57,8 +57,9 @@ void main() { 'live stream duration != 0', (WidgetTester tester) async { final VideoPlayerController networkController = - VideoPlayerController.network( - 'https://flutter.github.io/assets-for-api-docs/assets/videos/hls/bee.m3u8', + VideoPlayerController.networkUrl( + Uri.parse( + 'https://flutter.github.io/assets-for-api-docs/assets/videos/hls/bee.m3u8'), ); await networkController.initialize(); @@ -127,20 +128,36 @@ void main() { // Mute to allow playing without DOM interaction on Web. // See https://developers.google.com/web/updates/2017/09/autoplay-policy-changes await controller.setVolume(0); - final Duration timeBeforeEnd = - controller.value.duration - const Duration(milliseconds: 500); - await controller.seekTo(timeBeforeEnd); + final Duration tenMillisBeforeEnd = + controller.value.duration - const Duration(milliseconds: 10); + await controller.seekTo(tenMillisBeforeEnd); await controller.play(); await tester.pumpAndSettle(_playDuration); + // Android emulators in our CI have frequent flake where the video + // reports as still playing (usually without having advanced at all + // past the seek position, but sometimes having advanced some); if that + // happens, the thing being tested hasn't even had a chance to happen + // due to CI issues, so just report it as skipped. + // TODO(stuartmorgan): Remove once + // https://github.com/flutter/flutter/issues/141145 is fixed. + if ((!kIsWeb && Platform.isAndroid) && controller.value.isPlaying) { + markTestSkipped( + 'Skipping due to https://github.com/flutter/flutter/issues/141145'); + return; + } expect(controller.value.isPlaying, false); expect(controller.value.position, controller.value.duration); - await controller.seekTo(timeBeforeEnd); + await controller.seekTo(tenMillisBeforeEnd); await tester.pumpAndSettle(_playDuration); expect(controller.value.isPlaying, false); - expect(controller.value.position, timeBeforeEnd); + expect(controller.value.position, tenMillisBeforeEnd); }, + // Flaky on web: https://github.com/flutter/flutter/issues/130147 + //skip: kIsWeb, + // NOTE(jsuya): In Tizen, isPlaying returns true after the play() call. + skip: true, ); testWidgets( @@ -151,9 +168,24 @@ void main() { // See https://developers.google.com/web/updates/2017/09/autoplay-policy-changes await controller.setVolume(0); await controller.seekTo( - controller.value.duration - const Duration(milliseconds: 500)); + controller.value.duration - const Duration(milliseconds: 10)); await controller.play(); await tester.pumpAndSettle(_playDuration); + // Android emulators in our CI have frequent flake where the video + // reports as still playing (usually without having advanced at all + // past the seek position, but sometimes having advanced some); if that + // happens, the thing being tested hasn't even had a chance to happen + // due to CI issues, so just report it as skipped. + // TODO(stuartmorgan): Remove once + // https://github.com/flutter/flutter/issues/141145 is fixed. + + // NOTE(jsuya): In Tizen, isPlaying returns true after the play() + // call,so subsequent tests cannot be performed. + if ((!kIsWeb && Platform.isAndroid) && controller.value.isPlaying) { + markTestSkipped( + 'Skipping due to https://github.com/flutter/flutter/issues/141145'); + return; + } expect(controller.value.isPlaying, false); expect(controller.value.position, controller.value.duration); @@ -163,13 +195,17 @@ void main() { expect(controller.value.position, lessThanOrEqualTo(controller.value.duration)); }, + // NOTE(jsuya): In Tizen, isPlaying returns true after the play() call. + skip: true, ); testWidgets('test video player view with local asset', (WidgetTester tester) async { + final Completer loaded = Completer(); Future started() async { await controller.initialize(); await controller.play(); + loaded.complete(); return true; } @@ -194,12 +230,12 @@ void main() { ), )); + await loaded.future; await tester.pumpAndSettle(); expect(controller.value.isPlaying, true); }, - skip: kIsWeb || // Web does not support local assets. - // Extremely flaky on iOS: https://github.com/flutter/flutter/issues/86915 - defaultTargetPlatform == TargetPlatform.iOS); + // Web does not support local assets. + skip: kIsWeb); }); group('file-based videos', () { @@ -230,8 +266,8 @@ void main() { group('network videos', () { setUp(() { - controller = VideoPlayerController.network( - getUrlForAssetAsNetworkSource(_videoAssetKey)); + controller = VideoPlayerController.networkUrl( + Uri.parse(getUrlForAssetAsNetworkSource(_videoAssetKey))); }); testWidgets( @@ -283,7 +319,7 @@ void main() { expect(controller.value.isInitialized, true); expect(controller.value.position, Duration.zero); expect(controller.value.isPlaying, false); - // Due to the duration calculation accurancy between platforms, + // Due to the duration calculation accuracy between platforms, // the milliseconds on Web will be a slightly different from natives. // The audio was made with 44100 Hz, 192 Kbps CBR, and 32 bits. expect( diff --git a/packages/video_player/example/lib/main.dart b/packages/video_player/example/lib/main.dart index c1ab86097..0ce77d603 100644 --- a/packages/video_player/example/lib/main.dart +++ b/packages/video_player/example/lib/main.dart @@ -122,21 +122,26 @@ class _ExampleCard extends StatelessWidget { leading: const Icon(Icons.airline_seat_flat_angled), title: Text(title), ), - ButtonBar( - children: [ - TextButton( - child: const Text('BUY TICKETS'), - onPressed: () { - /* ... */ - }, - ), - TextButton( - child: const Text('SELL TICKETS'), - onPressed: () { - /* ... */ - }, - ), - ], + Padding( + padding: const EdgeInsets.all(8.0), + child: OverflowBar( + alignment: MainAxisAlignment.end, + spacing: 8.0, + children: [ + TextButton( + child: const Text('BUY TICKETS'), + onPressed: () { + /* ... */ + }, + ), + TextButton( + child: const Text('SELL TICKETS'), + onPressed: () { + /* ... */ + }, + ), + ], + ), ), ], ), @@ -218,8 +223,9 @@ class _BumbleBeeRemoteVideoState extends State<_BumbleBeeRemoteVideo> { @override void initState() { super.initState(); - _controller = VideoPlayerController.network( - 'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4', + _controller = VideoPlayerController.networkUrl( + Uri.parse( + 'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4'), closedCaptionFile: _loadCaptions(), videoPlayerOptions: VideoPlayerOptions(mixWithOthers: true), ); diff --git a/packages/video_player/example/pubspec.yaml b/packages/video_player/example/pubspec.yaml index 5d553675a..6c6326685 100644 --- a/packages/video_player/example/pubspec.yaml +++ b/packages/video_player/example/pubspec.yaml @@ -3,13 +3,13 @@ description: Demonstrates how to use the video_player_tizen plugin. publish_to: "none" environment: - sdk: ">=3.1.0 <4.0.0" - flutter: ">=3.13.0" + sdk: ">=3.3.0 <4.0.0" + flutter: ">=3.19.0" dependencies: flutter: sdk: flutter - video_player: ^2.4.2 + video_player: ^2.9.1 video_player_tizen: path: ../ diff --git a/packages/video_player/lib/video_player_tizen.dart b/packages/video_player/lib/video_player_tizen.dart index 2a4ba3359..bf85f4d14 100644 --- a/packages/video_player/lib/video_player_tizen.dart +++ b/packages/video_player/lib/video_player_tizen.dart @@ -143,6 +143,11 @@ class VideoPlayerTizen extends VideoPlayerPlatform { return VideoEvent(eventType: VideoEventType.bufferingStart); case 'bufferingEnd': return VideoEvent(eventType: VideoEventType.bufferingEnd); + case 'isPlayingStateUpdate': + return VideoEvent( + eventType: VideoEventType.isPlayingStateUpdate, + isPlaying: map['isPlaying'] as bool, + ); default: return VideoEvent(eventType: VideoEventType.unknown); } diff --git a/packages/video_player/pubspec.yaml b/packages/video_player/pubspec.yaml index 98cf21e23..6c9a54f41 100644 --- a/packages/video_player/pubspec.yaml +++ b/packages/video_player/pubspec.yaml @@ -2,11 +2,11 @@ name: video_player_tizen description: Tizen implementation of the video_player plugin. homepage: https://github.com/flutter-tizen/plugins repository: https://github.com/flutter-tizen/plugins/tree/master/packages/video_player -version: 2.4.9 +version: 2.5.0 environment: - sdk: ">=3.1.0 <4.0.0" - flutter: ">=3.13.0" + sdk: ">=3.3.0 <4.0.0" + flutter: ">=3.19.0" flutter: plugin: @@ -19,7 +19,7 @@ flutter: dependencies: flutter: sdk: flutter - video_player_platform_interface: ^5.1.2 + video_player_platform_interface: ^6.2.0 dev_dependencies: pigeon: ^10.0.0 diff --git a/packages/video_player/tizen/src/video_player.cc b/packages/video_player/tizen/src/video_player.cc index 18b855d8e..b08a44838 100644 --- a/packages/video_player/tizen/src/video_player.cc +++ b/packages/video_player/tizen/src/video_player.cc @@ -270,6 +270,8 @@ void VideoPlayer::Play() { #ifdef TV_PROFILE timer_ = ecore_timer_add(30, ResetScreensaverTimeout, this); #endif + + SendIsPlayingStateUpdate(true); } void VideoPlayer::Pause() { @@ -294,6 +296,8 @@ void VideoPlayer::Pause() { ecore_timer_del(timer_); timer_ = nullptr; } + + SendIsPlayingStateUpdate(false); } void VideoPlayer::SetLooping(bool is_looping) { @@ -474,6 +478,16 @@ void VideoPlayer::SendInitialized() { } } +void VideoPlayer::SendIsPlayingStateUpdate(bool is_playing) { + flutter::EncodableMap result = { + {flutter::EncodableValue("event"), + flutter::EncodableValue("isPlayingStateUpdate")}, + {flutter::EncodableValue("isPlaying"), + flutter::EncodableValue(is_playing)}, + }; + PushEvent(flutter::EncodableValue(result)); +} + Eina_Bool VideoPlayer::ResetScreensaverTimeout(void *data) { LOG_DEBUG("[VideoPlayer] Reset screen saver timeout."); diff --git a/packages/video_player/tizen/src/video_player.h b/packages/video_player/tizen/src/video_player.h index d58ea6ba4..6833a5789 100644 --- a/packages/video_player/tizen/src/video_player.h +++ b/packages/video_player/tizen/src/video_player.h @@ -54,6 +54,7 @@ class VideoPlayer { void SetUpEventChannel(flutter::BinaryMessenger *messenger); void Initialize(); void SendInitialized(); + void SendIsPlayingStateUpdate(bool is_playing); void InitScreenSaverApi(); static void OnPrepared(void *data);