From 0da533e927c7bd7c095f0f73731c37bcc81703a4 Mon Sep 17 00:00:00 2001 From: engine-flutter-autoroll Date: Wed, 23 Feb 2022 14:59:16 -0500 Subject: [PATCH 1/4] Roll Flutter from 617de911982a to 3b05d806222a (2 revisions) (#4905) --- .ci/flutter_master.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/flutter_master.version b/.ci/flutter_master.version index 2db38147e55e..fb28fa78643f 100644 --- a/.ci/flutter_master.version +++ b/.ci/flutter_master.version @@ -1 +1 @@ -617de911982a07d0edd484dd017fa7470e23cb1c +3b05d806222a75a5076ffaeec4d93c95e3bb72ea From 5fc1fa7efd8fe8281500ab669f2d4b308eda55e0 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Wed, 23 Feb 2022 21:39:23 +0100 Subject: [PATCH 2/4] [in_app_purchase] Updates the dependency on in_app_purchase_storekit. (#4910) --- packages/in_app_purchase/in_app_purchase/CHANGELOG.md | 7 ++++++- packages/in_app_purchase/in_app_purchase/pubspec.yaml | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/in_app_purchase/in_app_purchase/CHANGELOG.md b/packages/in_app_purchase/in_app_purchase/CHANGELOG.md index 232dacf0b71e..588993a01fd0 100644 --- a/packages/in_app_purchase/in_app_purchase/CHANGELOG.md +++ b/packages/in_app_purchase/in_app_purchase/CHANGELOG.md @@ -1,3 +1,8 @@ +## 3.0.0 + +* **BREAKING CHANGE** Updates `restorePurchases` to emit an empty list of purchases on StoreKit when there are no purchases to restore (same as Android). + * This change was listed in the CHANGELOG for 2.0.0, but the change was accidentally not included in 2.0.0. + ## 2.0.1 * Removes the instructions on initializing the plugin since this functionality is deprecated. @@ -6,7 +11,7 @@ * **BREAKING CHANGES**: * Adds a new `PurchaseStatus` named `canceled`. This means developers can distinguish between an error and user cancellation. - * Updates `restorePurchases` to emit an empty list of purchases on StoreKit when there are no purchases to restore (same as Android). + * ~~Updates `restorePurchases` to emit an empty list of purchases on StoreKit when there are no purchases to restore (same as Android).~~ * Renames `in_app_purchase_ios` to `in_app_purchase_storekit`. * Renames `InAppPurchaseIosPlatform` to `InAppPurchaseStoreKitPlatform`. * Renames `InAppPurchaseIosPlatformAddition` to diff --git a/packages/in_app_purchase/in_app_purchase/pubspec.yaml b/packages/in_app_purchase/in_app_purchase/pubspec.yaml index b18853be2372..80c150d3f9e2 100644 --- a/packages/in_app_purchase/in_app_purchase/pubspec.yaml +++ b/packages/in_app_purchase/in_app_purchase/pubspec.yaml @@ -2,7 +2,7 @@ name: in_app_purchase description: A Flutter plugin for in-app purchases. Exposes APIs for making in-app purchases through the App Store and Google Play. repository: https://github.com/flutter/plugins/tree/main/packages/in_app_purchase/in_app_purchase issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+in_app_purchase%22 -version: 2.0.1 +version: 3.0.0 environment: sdk: ">=2.12.0 <3.0.0" @@ -21,7 +21,7 @@ dependencies: sdk: flutter in_app_purchase_platform_interface: ^1.0.0 in_app_purchase_android: ^0.2.1 - in_app_purchase_storekit: ^0.2.0 + in_app_purchase_storekit: ^0.3.0+1 dev_dependencies: flutter_driver: From 3daf0b7f14c5db845d4f88dd3d07293bba6cc94b Mon Sep 17 00:00:00 2001 From: engine-flutter-autoroll Date: Wed, 23 Feb 2022 16:24:22 -0500 Subject: [PATCH 3/4] Roll Flutter from 3b05d806222a to c74a646b7bba (21 revisions) (#4913) --- .ci/flutter_master.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/flutter_master.version b/.ci/flutter_master.version index fb28fa78643f..c09c5a5d6212 100644 --- a/.ci/flutter_master.version +++ b/.ci/flutter_master.version @@ -1 +1 @@ -3b05d806222a75a5076ffaeec4d93c95e3bb72ea +c74a646b7bba1641d0b2b29f6024dc867844e94c From cc868bc868a0fdbf1cb785f1c96d616a2c332e62 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Thu, 24 Feb 2022 12:26:23 -0500 Subject: [PATCH 4/4] [video_player] Update app-facing package analysis options (#4786) --- .../video_player/video_player/CHANGELOG.md | 4 + .../video_player/analysis_options.yaml | 1 - .../controller_swap_test.dart | 31 +++--- .../integration_test/video_player_test.dart | 23 ++--- .../video_player/example/lib/main.dart | 64 ++++++------- .../video_player/example/pubspec.yaml | 5 +- .../test_driver/video_player_test.dart | 4 +- .../lib/src/closed_caption_file.dart | 8 +- .../video_player/lib/src/sub_rip.dart | 10 +- .../video_player/lib/src/web_vtt.dart | 26 ++--- .../video_player/lib/video_player.dart | 57 +++++------ .../video_player/video_player/pubspec.yaml | 5 +- .../test/closed_caption_file_test.dart | 2 +- .../video_player/test/sub_rip_file_test.dart | 20 ++-- .../video_player_initialization_test.dart | 3 +- .../video_player/test/video_player_test.dart | 96 ++++++++++--------- .../video_player/test/web_vtt_test.dart | 42 ++++---- script/configs/custom_analysis.yaml | 1 - 18 files changed, 205 insertions(+), 197 deletions(-) delete mode 100644 packages/video_player/video_player/analysis_options.yaml diff --git a/packages/video_player/video_player/CHANGELOG.md b/packages/video_player/video_player/CHANGELOG.md index adf696ad0120..ee0accb22c79 100644 --- a/packages/video_player/video_player/CHANGELOG.md +++ b/packages/video_player/video_player/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.2.19 + +* Internal code cleanup for stricter analysis options. + ## 2.2.18 * Moves Android and iOS implementations to federated packages. diff --git a/packages/video_player/video_player/analysis_options.yaml b/packages/video_player/video_player/analysis_options.yaml deleted file mode 100644 index 5aeb4e7c5e21..000000000000 --- a/packages/video_player/video_player/analysis_options.yaml +++ /dev/null @@ -1 +0,0 @@ -include: ../../../analysis_options_legacy.yaml diff --git a/packages/video_player/video_player/example/integration_test/controller_swap_test.dart b/packages/video_player/video_player/example/integration_test/controller_swap_test.dart index 847807635f14..f80e600bcff5 100644 --- a/packages/video_player/video_player/example/integration_test/controller_swap_test.dart +++ b/packages/video_player/video_player/example/integration_test/controller_swap_test.dart @@ -6,8 +6,8 @@ import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:integration_test/integration_test.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; import 'package:video_player/video_player.dart'; const Duration _playDuration = Duration(seconds: 1); @@ -18,13 +18,13 @@ void main() { 'can substitute one controller by another without crashing', (WidgetTester tester) async { // Use WebM for web to allow CI to use Chromium. - final String videoAssetKey = + const String videoAssetKey = kIsWeb ? 'assets/Butterfly-209.webm' : 'assets/Butterfly-209.mp4'; - VideoPlayerController controller = VideoPlayerController.asset( + final VideoPlayerController controller = VideoPlayerController.asset( videoAssetKey, ); - VideoPlayerController another = VideoPlayerController.asset( + final VideoPlayerController another = VideoPlayerController.asset( videoAssetKey, ); await controller.initialize(); @@ -32,18 +32,16 @@ void main() { await controller.setVolume(0); await another.setVolume(0); - final Completer started = Completer(); - final Completer ended = Completer(); - bool startedBuffering = false; - bool endedBuffering = false; + final Completer started = Completer(); + final Completer ended = Completer(); another.addListener(() { - if (another.value.isBuffering && !startedBuffering) { - startedBuffering = true; + if (another.value.isBuffering && !started.isCompleted) { started.complete(); } - if (startedBuffering && !another.value.isBuffering && !endedBuffering) { - endedBuffering = true; + if (started.isCompleted && + !another.value.isBuffering && + !ended.isCompleted) { ended.complete(); } }); @@ -69,11 +67,8 @@ void main() { expect(another.value.position, (Duration position) => position > const Duration(seconds: 0)); - await started; - expect(startedBuffering, true); - - await ended; - expect(endedBuffering, true); + await expectLater(started.future, completes); + await expectLater(ended.future, completes); }, skip: !(kIsWeb || defaultTargetPlatform == TargetPlatform.android), ); @@ -86,7 +81,7 @@ Widget renderVideoWidget(VideoPlayerController controller) { textDirection: TextDirection.ltr, child: Center( child: AspectRatio( - key: Key('same'), + key: const Key('same'), aspectRatio: controller.value.aspectRatio, child: VideoPlayer(controller), ), diff --git a/packages/video_player/video_player/example/integration_test/video_player_test.dart b/packages/video_player/video_player/example/integration_test/video_player_test.dart index 0c2252bf7447..746c63fcbfd6 100644 --- a/packages/video_player/video_player/example/integration_test/video_player_test.dart +++ b/packages/video_player/video_player/example/integration_test/video_player_test.dart @@ -17,7 +17,7 @@ import 'package:video_player/video_player.dart'; const Duration _playDuration = Duration(seconds: 1); // Use WebM for web to allow CI to use Chromium. -final String _videoAssetKey = +const String _videoAssetKey = kIsWeb ? 'assets/Butterfly-209.webm' : 'assets/Butterfly-209.mp4'; // Returns the URL to load an asset from this example app as a network source. @@ -48,13 +48,14 @@ void main() { expect(_controller.value.isPlaying, false); // The WebM version has a slightly different duration than the MP4. expect(_controller.value.duration, - Duration(seconds: 7, milliseconds: kIsWeb ? 544 : 540)); + const Duration(seconds: 7, milliseconds: kIsWeb ? 544 : 540)); }); testWidgets( 'live stream duration != 0', (WidgetTester tester) async { - VideoPlayerController networkController = VideoPlayerController.network( + final VideoPlayerController networkController = + VideoPlayerController.network( 'https://cph-p2p-msl.akamaized.net/hls/live/2000341/test/master.m3u8', ); await networkController.initialize(); @@ -65,7 +66,7 @@ void main() { expect(networkController.value.duration, (Duration duration) => duration != Duration.zero); }, - skip: (kIsWeb), + skip: kIsWeb, ); testWidgets( @@ -124,7 +125,7 @@ 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); - Duration tenMillisBeforeEnd = + final Duration tenMillisBeforeEnd = _controller.value.duration - const Duration(milliseconds: 10); await _controller.seekTo(tenMillisBeforeEnd); await _controller.play(); @@ -203,12 +204,12 @@ void main() { group('file-based videos', () { setUp(() async { // Load the data from the asset. - String tempDir = (await getTemporaryDirectory()).path; - ByteData bytes = await rootBundle.load(_videoAssetKey); + final String tempDir = (await getTemporaryDirectory()).path; + final ByteData bytes = await rootBundle.load(_videoAssetKey); // Write it to a file to use as a source. final String filename = _videoAssetKey.split('/').last; - File file = File('$tempDir/$filename'); + final File file = File('$tempDir/$filename'); await file.writeAsBytes(bytes.buffer.asInt8List()); _controller = VideoPlayerController.file(file); @@ -244,8 +245,8 @@ 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 Completer started = Completer(); - final Completer ended = Completer(); + final Completer started = Completer(); + final Completer ended = Completer(); _controller.addListener(() { if (!started.isCompleted && _controller.value.isBuffering) { started.complete(); @@ -291,7 +292,7 @@ void main() { // The audio was made with 44100 Hz, 192 Kbps CBR, and 32 bits. expect( _controller.value.duration, - Duration(seconds: 5, milliseconds: kIsWeb ? 42 : 41), + const Duration(seconds: 5, milliseconds: kIsWeb ? 42 : 41), ); }); diff --git a/packages/video_player/video_player/example/lib/main.dart b/packages/video_player/video_player/example/lib/main.dart index 9297cc69470c..5d496a9f5e7d 100644 --- a/packages/video_player/video_player/example/lib/main.dart +++ b/packages/video_player/video_player/example/lib/main.dart @@ -47,10 +47,10 @@ class _App extends StatelessWidget { tabs: [ Tab( icon: Icon(Icons.cloud), - text: "Remote", + text: 'Remote', ), - Tab(icon: Icon(Icons.insert_drive_file), text: "Asset"), - Tab(icon: Icon(Icons.list), text: "List example"), + Tab(icon: Icon(Icons.insert_drive_file), text: 'Asset'), + Tab(icon: Icon(Icons.list), text: 'List example'), ], ), ), @@ -71,20 +71,20 @@ class _ButterFlyAssetVideoInList extends StatelessWidget { Widget build(BuildContext context) { return ListView( children: [ - _ExampleCard(title: "Item a"), - _ExampleCard(title: "Item b"), - _ExampleCard(title: "Item c"), - _ExampleCard(title: "Item d"), - _ExampleCard(title: "Item e"), - _ExampleCard(title: "Item f"), - _ExampleCard(title: "Item g"), + const _ExampleCard(title: 'Item a'), + const _ExampleCard(title: 'Item b'), + const _ExampleCard(title: 'Item c'), + const _ExampleCard(title: 'Item d'), + const _ExampleCard(title: 'Item e'), + const _ExampleCard(title: 'Item f'), + const _ExampleCard(title: 'Item g'), Card( child: Column(children: [ Column( children: [ const ListTile( leading: Icon(Icons.cake), - title: Text("Video video"), + title: Text('Video video'), ), Stack( alignment: FractionalOffset.bottomRight + @@ -96,11 +96,11 @@ class _ButterFlyAssetVideoInList extends StatelessWidget { ], ), ])), - _ExampleCard(title: "Item h"), - _ExampleCard(title: "Item i"), - _ExampleCard(title: "Item j"), - _ExampleCard(title: "Item k"), - _ExampleCard(title: "Item l"), + const _ExampleCard(title: 'Item h'), + const _ExampleCard(title: 'Item i'), + const _ExampleCard(title: 'Item j'), + const _ExampleCard(title: 'Item k'), + const _ExampleCard(title: 'Item l'), ], ); } @@ -269,7 +269,7 @@ class _ControlsOverlay extends StatelessWidget { const _ControlsOverlay({Key? key, required this.controller}) : super(key: key); - static const _exampleCaptionOffsets = [ + static const List _exampleCaptionOffsets = [ Duration(seconds: -10), Duration(seconds: -3), Duration(seconds: -1, milliseconds: -500), @@ -280,7 +280,7 @@ class _ControlsOverlay extends StatelessWidget { Duration(seconds: 3), Duration(seconds: 10), ]; - static const _examplePlaybackRates = [ + static const List _examplePlaybackRates = [ 0.25, 0.5, 1.0, @@ -298,13 +298,13 @@ class _ControlsOverlay extends StatelessWidget { return Stack( children: [ AnimatedSwitcher( - duration: Duration(milliseconds: 50), - reverseDuration: Duration(milliseconds: 200), + duration: const Duration(milliseconds: 50), + reverseDuration: const Duration(milliseconds: 200), child: controller.value.isPlaying - ? SizedBox.shrink() + ? const SizedBox.shrink() : Container( color: Colors.black26, - child: Center( + child: const Center( child: Icon( Icons.play_arrow, color: Colors.white, @@ -324,13 +324,13 @@ class _ControlsOverlay extends StatelessWidget { child: PopupMenuButton( initialValue: controller.value.captionOffset, tooltip: 'Caption Offset', - onSelected: (delay) { + onSelected: (Duration delay) { controller.setCaptionOffset(delay); }, - itemBuilder: (context) { - return [ - for (final offsetDuration in _exampleCaptionOffsets) - PopupMenuItem( + itemBuilder: (BuildContext context) { + return >[ + for (final Duration offsetDuration in _exampleCaptionOffsets) + PopupMenuItem( value: offsetDuration, child: Text('${offsetDuration.inMilliseconds}ms'), ) @@ -353,13 +353,13 @@ class _ControlsOverlay extends StatelessWidget { child: PopupMenuButton( initialValue: controller.value.playbackSpeed, tooltip: 'Playback speed', - onSelected: (speed) { + onSelected: (double speed) { controller.setPlaybackSpeed(speed); }, - itemBuilder: (context) { - return [ - for (final speed in _examplePlaybackRates) - PopupMenuItem( + itemBuilder: (BuildContext context) { + return >[ + for (final double speed in _examplePlaybackRates) + PopupMenuItem( value: speed, child: Text('${speed}x'), ) diff --git a/packages/video_player/video_player/example/pubspec.yaml b/packages/video_player/video_player/example/pubspec.yaml index eef6eb7ab63b..6032f3ceed65 100644 --- a/packages/video_player/video_player/example/pubspec.yaml +++ b/packages/video_player/video_player/example/pubspec.yaml @@ -18,14 +18,13 @@ dependencies: path: ../ dev_dependencies: - flutter_test: - sdk: flutter flutter_driver: sdk: flutter + flutter_test: + sdk: flutter integration_test: sdk: flutter path_provider: ^2.0.6 - pedantic: ^1.10.0 test: any flutter: diff --git a/packages/video_player/video_player/example/test_driver/video_player_test.dart b/packages/video_player/video_player/example/test_driver/video_player_test.dart index 1d5ac79c77bf..5fbed804d8d8 100644 --- a/packages/video_player/video_player/example/test_driver/video_player_test.dart +++ b/packages/video_player/video_player/example/test_driver/video_player_test.dart @@ -12,8 +12,8 @@ Future main() async { await driver.close(); }); - //TODO(cyanglaz): Use TabBar tabs to navigate between pages after https://github.com/flutter/flutter/issues/16991 is fixed. - //TODO(cyanglaz): Un-skip the test after https://github.com/flutter/flutter/issues/43012 is fixed + // TODO(cyanglaz): Use TabBar tabs to navigate between pages after https://github.com/flutter/flutter/issues/16991 is fixed. + // TODO(cyanglaz): Un-skip the test after https://github.com/flutter/flutter/issues/43012 is fixed test('Push a page contains video and pop back, do not crash.', () async { final SerializableFinder pushTab = find.byValueKey('push_tab'); await driver.waitFor(pushTab); diff --git a/packages/video_player/video_player/lib/src/closed_caption_file.dart b/packages/video_player/video_player/lib/src/closed_caption_file.dart index e410e2652ad3..324ffc471ffe 100644 --- a/packages/video_player/video_player/lib/src/closed_caption_file.dart +++ b/packages/video_player/video_player/lib/src/closed_caption_file.dart @@ -2,10 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'sub_rip.dart'; -export 'sub_rip.dart' show SubRipCaptionFile; +import 'package:flutter/foundation.dart' show objectRuntimeType; +import 'sub_rip.dart'; import 'web_vtt.dart'; + +export 'sub_rip.dart' show SubRipCaptionFile; export 'web_vtt.dart' show WebVTTCaptionFile; /// A structured representation of a parsed closed caption file. @@ -66,7 +68,7 @@ class Caption { @override String toString() { - return '$runtimeType(' + return '${objectRuntimeType(this, 'Caption')}(' 'number: $number, ' 'start: $start, ' 'end: $end, ' diff --git a/packages/video_player/video_player/lib/src/sub_rip.dart b/packages/video_player/video_player/lib/src/sub_rip.dart index 5d6863f72bb8..7b807cd4d5d9 100644 --- a/packages/video_player/video_player/lib/src/sub_rip.dart +++ b/packages/video_player/video_player/lib/src/sub_rip.dart @@ -28,8 +28,10 @@ class SubRipCaptionFile extends ClosedCaptionFile { List _parseCaptionsFromSubRipString(String file) { final List captions = []; - for (List captionLines in _readSubRipFile(file)) { - if (captionLines.length < 3) break; + for (final List captionLines in _readSubRipFile(file)) { + if (captionLines.length < 3) { + break; + } final int captionNumber = int.parse(captionLines[0]); final _CaptionRange captionRange = @@ -52,11 +54,11 @@ List _parseCaptionsFromSubRipString(String file) { } class _CaptionRange { + _CaptionRange(this.start, this.end); + final Duration start; final Duration end; - _CaptionRange(this.start, this.end); - // Assumes format from an SubRip file. // For example: // 00:01:54,724 --> 00:01:56,760 diff --git a/packages/video_player/video_player/lib/src/web_vtt.dart b/packages/video_player/video_player/lib/src/web_vtt.dart index 6c4527d34d67..5527e62b69f1 100644 --- a/packages/video_player/video_player/lib/src/web_vtt.dart +++ b/packages/video_player/video_player/lib/src/web_vtt.dart @@ -5,9 +5,9 @@ import 'dart:convert'; import 'package:html/dom.dart'; +import 'package:html/parser.dart' as html_parser; import 'closed_caption_file.dart'; -import 'package:html/parser.dart' as html_parser; /// Represents a [ClosedCaptionFile], parsed from the WebVTT file format. /// See: https://en.wikipedia.org/wiki/WebVTT @@ -28,10 +28,10 @@ List _parseCaptionsFromWebVTTString(String file) { final List captions = []; // Ignore metadata - Set metadata = {'HEADER', 'NOTE', 'REGION', 'WEBVTT'}; + final Set metadata = {'HEADER', 'NOTE', 'REGION', 'WEBVTT'}; int captionNumber = 1; - for (List captionLines in _readWebVTTFile(file)) { + for (final List captionLines in _readWebVTTFile(file)) { // CaptionLines represent a complete caption. // E.g // [ @@ -39,14 +39,18 @@ List _parseCaptionsFromWebVTTString(String file) { // ['Introduction'] // ] // If caption has just header or time, but no text, `captionLines.length` will be 1. - if (captionLines.length < 2) continue; + if (captionLines.length < 2) { + continue; + } // If caption has header equal metadata, ignore. - String metadaType = captionLines[0].split(' ')[0]; - if (metadata.contains(metadaType)) continue; + final String metadaType = captionLines[0].split(' ')[0]; + if (metadata.contains(metadaType)) { + continue; + } // Caption has header - bool hasHeader = captionLines.length > 2; + final bool hasHeader = captionLines.length > 2; if (hasHeader) { final int? tryParseCaptionNumber = int.tryParse(captionLines[0]); if (tryParseCaptionNumber != null) { @@ -82,11 +86,11 @@ List _parseCaptionsFromWebVTTString(String file) { } class _CaptionRange { + _CaptionRange(this.start, this.end); + final Duration start; final Duration end; - _CaptionRange(this.start, this.end); - // Assumes format from an VTT file. // For example: // 00:09.000 --> 00:11.000 @@ -161,7 +165,7 @@ Duration? _parseWebVTTTimestamp(String timestampString) { return null; } - List milisecondsStyles = dotSections[1].split(" "); + final List milisecondsStyles = dotSections[1].split(' '); // TODO(cyanglaz): Handle caption styles. // https://github.com/flutter/flutter/issues/90009. @@ -172,7 +176,7 @@ Duration? _parseWebVTTTimestamp(String timestampString) { // ``` // For a better readable code style, style parsing should happen before // calling this method. See: https://github.com/flutter/plugins/pull/2878/files#r713381134. - int milliseconds = int.parse(milisecondsStyles[0]); + final int milliseconds = int.parse(milisecondsStyles[0]); return Duration( hours: hours, diff --git a/packages/video_player/video_player/lib/video_player.dart b/packages/video_player/video_player/lib/video_player.dart index 8fd216286fca..672ba2efcde3 100644 --- a/packages/video_player/video_player/lib/video_player.dart +++ b/packages/video_player/video_player/lib/video_player.dart @@ -10,16 +10,17 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:video_player_platform_interface/video_player_platform_interface.dart'; +import 'src/closed_caption_file.dart'; + export 'package:video_player_platform_interface/video_player_platform_interface.dart' show DurationRange, DataSourceType, VideoFormat, VideoPlayerOptions; -import 'src/closed_caption_file.dart'; export 'src/closed_caption_file.dart'; VideoPlayerPlatform? _lastVideoPlayerPlatform; VideoPlayerPlatform get _videoPlayerPlatform { - VideoPlayerPlatform currentInstance = VideoPlayerPlatform.instance; + final VideoPlayerPlatform currentInstance = VideoPlayerPlatform.instance; if (_lastVideoPlayerPlatform != currentInstance) { // This will clear all open videos on the platform when a full restart is // performed. @@ -32,10 +33,6 @@ VideoPlayerPlatform get _videoPlayerPlatform { /// The duration, current position, buffering state, error state and settings /// of a [VideoPlayerController]. class VideoPlayerValue { - /// This constant is just to indicate that parameter is not passed to [copyWith] - /// workaround for this issue https://github.com/dart-lang/language/issues/2009 - static const _defaultErrorDescription = 'defaultErrorDescription'; - /// Constructs a video with the given values. Only [duration] is required. The /// rest will initialize with default values when unset. VideoPlayerValue({ @@ -65,6 +62,10 @@ class VideoPlayerValue { isInitialized: false, errorDescription: errorDescription); + /// This constant is just to indicate that parameter is not passed to [copyWith] + /// workaround for this issue https://github.com/dart-lang/language/issues/2009 + static const String _defaultErrorDescription = 'defaultErrorDescription'; + /// The total duration of the video. /// /// The duration is [Duration.zero] if the video hasn't been initialized. @@ -172,7 +173,7 @@ class VideoPlayerValue { @override String toString() { - return '$runtimeType(' + return '${objectRuntimeType(this, 'VideoPlayerValue')}(' 'duration: $duration, ' 'size: $size, ' 'position: $position, ' @@ -209,7 +210,7 @@ class VideoPlayerController extends ValueNotifier { {this.package, this.closedCaptionFile, this.videoPlayerOptions}) : dataSourceType = DataSourceType.asset, formatHint = null, - httpHeaders = const {}, + httpHeaders = const {}, super(VideoPlayerValue(duration: Duration.zero)); /// Constructs a [VideoPlayerController] playing a video from obtained from @@ -226,7 +227,7 @@ class VideoPlayerController extends ValueNotifier { this.formatHint, this.closedCaptionFile, this.videoPlayerOptions, - this.httpHeaders = const {}, + this.httpHeaders = const {}, }) : dataSourceType = DataSourceType.network, package = null, super(VideoPlayerValue(duration: Duration.zero)); @@ -241,7 +242,7 @@ class VideoPlayerController extends ValueNotifier { dataSourceType = DataSourceType.file, package = null, formatHint = null, - httpHeaders = const {}, + httpHeaders = const {}, super(VideoPlayerValue(duration: Duration.zero)); /// Constructs a [VideoPlayerController] playing a video from a contentUri. @@ -256,7 +257,7 @@ class VideoPlayerController extends ValueNotifier { dataSourceType = DataSourceType.contentUri, package = null, formatHint = null, - httpHeaders = const {}, + httpHeaders = const {}, super(VideoPlayerValue(duration: Duration.zero)); /// The URI to the video file. This will be in different formats depending on @@ -393,9 +394,7 @@ class VideoPlayerController extends ValueNotifier { } if (closedCaptionFile != null) { - if (_closedCaptionFile == null) { - _closedCaptionFile = await closedCaptionFile; - } + _closedCaptionFile ??= await closedCaptionFile; value = value.copyWith(caption: _getCaptionAt(value.position)); } @@ -513,7 +512,9 @@ class VideoPlayerController extends ValueNotifier { // Setting the playback speed on iOS will trigger the video to play. We // prevent this from happening by not applying the playback speed until // the video is manually played from Flutter. - if (!value.isPlaying) return; + if (!value.isPlaying) { + return; + } await _videoPlayerPlatform.setPlaybackSpeed( _textureId, @@ -618,9 +619,9 @@ class VideoPlayerController extends ValueNotifier { return Caption.none; } - final delayedPosition = position + value.captionOffset; - // TODO: This would be more efficient as a binary search. - for (final caption in _closedCaptionFile!.captions) { + final Duration delayedPosition = position + value.captionOffset; + // TODO(johnsonmh): This would be more efficient as a binary search. + for (final Caption caption in _closedCaptionFile!.captions) { if (caption.start <= delayedPosition && caption.end >= delayedPosition) { return caption; } @@ -682,7 +683,7 @@ class _VideoAppLifeCycleObserver extends Object with WidgetsBindingObserver { /// Widget that displays the video controlled by [controller]. class VideoPlayer extends StatefulWidget { /// Uses the given [controller] for all video rendered in this widget. - VideoPlayer(this.controller); + const VideoPlayer(this.controller); /// The [VideoPlayerController] responsible for the video being rendered in /// this widget. @@ -780,7 +781,7 @@ class VideoProgressColors { } class _VideoScrubber extends StatefulWidget { - _VideoScrubber({ + const _VideoScrubber({ required this.child, required this.controller, }); @@ -800,7 +801,7 @@ class _VideoScrubberState extends State<_VideoScrubber> { @override Widget build(BuildContext context) { void seekToRelativePosition(Offset globalPosition) { - final RenderBox box = context.findRenderObject() as RenderBox; + final RenderBox box = context.findRenderObject()! as RenderBox; final Offset tapPos = box.globalToLocal(globalPosition); final double relative = tapPos.dx / box.size.width; final Duration position = controller.value.duration * relative; @@ -855,7 +856,7 @@ class VideoProgressIndicator extends StatefulWidget { /// Defaults will be used for everything except [controller] if they're not /// provided. [allowScrubbing] defaults to false, and [padding] will default /// to `top: 5.0`. - VideoProgressIndicator( + const VideoProgressIndicator( this.controller, { this.colors = const VideoProgressColors(), required this.allowScrubbing, @@ -923,7 +924,7 @@ class _VideoProgressIndicatorState extends State { final int position = controller.value.position.inMilliseconds; int maxBuffering = 0; - for (DurationRange range in controller.value.buffered) { + for (final DurationRange range in controller.value.buffered) { final int end = range.end.inMilliseconds; if (end > maxBuffering) { maxBuffering = end; @@ -1005,9 +1006,9 @@ class ClosedCaption extends StatelessWidget { @override Widget build(BuildContext context) { - final text = this.text; + final String? text = this.text; if (text == null || text.isEmpty) { - return SizedBox.shrink(); + return const SizedBox.shrink(); } final TextStyle effectiveTextStyle = textStyle ?? @@ -1019,14 +1020,14 @@ class ClosedCaption extends StatelessWidget { return Align( alignment: Alignment.bottomCenter, child: Padding( - padding: EdgeInsets.only(bottom: 24.0), + padding: const EdgeInsets.only(bottom: 24.0), child: DecoratedBox( decoration: BoxDecoration( - color: Color(0xB8000000), + color: const Color(0xB8000000), borderRadius: BorderRadius.circular(2.0), ), child: Padding( - padding: EdgeInsets.symmetric(horizontal: 2.0), + padding: const EdgeInsets.symmetric(horizontal: 2.0), child: Text(text, style: effectiveTextStyle), ), ), diff --git a/packages/video_player/video_player/pubspec.yaml b/packages/video_player/video_player/pubspec.yaml index a444fc69c912..2f6e28919d00 100644 --- a/packages/video_player/video_player/pubspec.yaml +++ b/packages/video_player/video_player/pubspec.yaml @@ -3,7 +3,7 @@ description: Flutter plugin for displaying inline video with other Flutter widgets on Android, iOS, and web. repository: https://github.com/flutter/plugins/tree/main/packages/video_player/video_player issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22 -version: 2.2.18 +version: 2.2.19 environment: sdk: ">=2.14.0 <3.0.0" @@ -22,13 +22,12 @@ flutter: dependencies: flutter: sdk: flutter + html: ^0.15.0 video_player_android: ^2.2.17 video_player_avfoundation: ^2.2.17 video_player_platform_interface: ">=4.2.0 <6.0.0" video_player_web: ^2.0.0 - html: ^0.15.0 dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.10.0 diff --git a/packages/video_player/video_player/test/closed_caption_file_test.dart b/packages/video_player/video_player/test/closed_caption_file_test.dart index 369a3b362557..b5c0a8e1db12 100644 --- a/packages/video_player/video_player/test/closed_caption_file_test.dart +++ b/packages/video_player/video_player/test/closed_caption_file_test.dart @@ -8,7 +8,7 @@ import 'package:video_player/src/closed_caption_file.dart'; void main() { group('ClosedCaptionFile', () { test('toString()', () { - final Caption caption = const Caption( + const Caption caption = Caption( number: 1, start: Duration(seconds: 1), end: Duration(seconds: 2), diff --git a/packages/video_player/video_player/test/sub_rip_file_test.dart b/packages/video_player/video_player/test/sub_rip_file_test.dart index 5808e0b9d2e3..ea3bfda036ec 100644 --- a/packages/video_player/video_player/test/sub_rip_file_test.dart +++ b/packages/video_player/video_player/test/sub_rip_file_test.dart @@ -14,19 +14,19 @@ void main() { final Caption firstCaption = parsedFile.captions.first; expect(firstCaption.number, 1); - expect(firstCaption.start, Duration(seconds: 6)); - expect(firstCaption.end, Duration(seconds: 12, milliseconds: 74)); + expect(firstCaption.start, const Duration(seconds: 6)); + expect(firstCaption.end, const Duration(seconds: 12, milliseconds: 74)); expect(firstCaption.text, 'This is a test file'); final Caption secondCaption = parsedFile.captions[1]; expect(secondCaption.number, 2); expect( secondCaption.start, - Duration(minutes: 1, seconds: 54, milliseconds: 724), + const Duration(minutes: 1, seconds: 54, milliseconds: 724), ); expect( secondCaption.end, - Duration(minutes: 1, seconds: 56, milliseconds: 760), + const Duration(minutes: 1, seconds: 56, milliseconds: 760), ); expect(secondCaption.text, '- Hello.\n- Yes?'); @@ -34,11 +34,11 @@ void main() { expect(thirdCaption.number, 3); expect( thirdCaption.start, - Duration(minutes: 1, seconds: 56, milliseconds: 884), + const Duration(minutes: 1, seconds: 56, milliseconds: 884), ); expect( thirdCaption.end, - Duration(minutes: 1, seconds: 58, milliseconds: 954), + const Duration(minutes: 1, seconds: 58, milliseconds: 954), ); expect( thirdCaption.text, @@ -49,11 +49,11 @@ void main() { expect(fourthCaption.number, 4); expect( fourthCaption.start, - Duration(hours: 1, minutes: 1, seconds: 59, milliseconds: 84), + const Duration(hours: 1, minutes: 1, seconds: 59, milliseconds: 84), ); expect( fourthCaption.end, - Duration(hours: 1, minutes: 2, seconds: 1, milliseconds: 552), + const Duration(hours: 1, minutes: 2, seconds: 1, milliseconds: 552), ); expect( fourthCaption.text, @@ -68,8 +68,8 @@ void main() { final Caption firstCaption = parsedFile.captions.single; expect(firstCaption.number, 2); - expect(firstCaption.start, Duration(seconds: 15)); - expect(firstCaption.end, Duration(seconds: 17, milliseconds: 74)); + expect(firstCaption.start, const Duration(seconds: 15)); + expect(firstCaption.end, const Duration(seconds: 17, milliseconds: 74)); expect(firstCaption.text, 'This one is valid'); }); } diff --git a/packages/video_player/video_player/test/video_player_initialization_test.dart b/packages/video_player/video_player/test/video_player_initialization_test.dart index 1870934a931e..af0886fdec18 100644 --- a/packages/video_player/video_player/test/video_player_initialization_test.dart +++ b/packages/video_player/video_player/test/video_player_initialization_test.dart @@ -13,7 +13,8 @@ void main() { // in this file. test('plugin initialized', () async { TestWidgetsFlutterBinding.ensureInitialized(); - FakeVideoPlayerPlatform fakeVideoPlayerPlatform = FakeVideoPlayerPlatform(); + final FakeVideoPlayerPlatform fakeVideoPlayerPlatform = + FakeVideoPlayerPlatform(); VideoPlayerPlatform.instance = fakeVideoPlayerPlatform; final VideoPlayerController controller = VideoPlayerController.network( diff --git a/packages/video_player/video_player/test/video_player_test.dart b/packages/video_player/video_player/test/video_player_test.dart index 3bce821e8fe3..07afd0f65402 100644 --- a/packages/video_player/video_player/test/video_player_test.dart +++ b/packages/video_player/video_player/test/video_player_test.dart @@ -29,7 +29,7 @@ class FakeController extends ValueNotifier String get dataSource => ''; @override - Map get httpHeaders => {}; + Map get httpHeaders => {}; @override DataSourceType get dataSourceType => DataSourceType.file; @@ -81,13 +81,13 @@ class _FakeClosedCaptionFile extends ClosedCaptionFile { @override List get captions { return [ - Caption( + const Caption( text: 'one', number: 0, start: Duration(milliseconds: 100), end: Duration(milliseconds: 200), ), - Caption( + const Caption( text: 'two', number: 1, start: Duration(milliseconds: 300), @@ -135,8 +135,9 @@ void main() { group('ClosedCaption widget', () { testWidgets('uses a default text style', (WidgetTester tester) async { - final String text = 'foo'; - await tester.pumpWidget(MaterialApp(home: ClosedCaption(text: text))); + const String text = 'foo'; + await tester + .pumpWidget(const MaterialApp(home: ClosedCaption(text: text))); final Text textWidget = tester.widget(find.text(text)); expect(textWidget.style!.fontSize, 36.0); @@ -144,9 +145,9 @@ void main() { }); testWidgets('uses given text and style', (WidgetTester tester) async { - final String text = 'foo'; - final TextStyle textStyle = TextStyle(fontSize: 14.725); - await tester.pumpWidget(MaterialApp( + const String text = 'foo'; + const TextStyle textStyle = TextStyle(fontSize: 14.725); + await tester.pumpWidget(const MaterialApp( home: ClosedCaption( text: text, textStyle: textStyle, @@ -159,19 +160,20 @@ void main() { }); testWidgets('handles null text', (WidgetTester tester) async { - await tester.pumpWidget(MaterialApp(home: ClosedCaption(text: null))); + await tester + .pumpWidget(const MaterialApp(home: ClosedCaption(text: null))); expect(find.byType(Text), findsNothing); }); testWidgets('handles empty text', (WidgetTester tester) async { - await tester.pumpWidget(MaterialApp(home: ClosedCaption(text: ''))); + await tester.pumpWidget(const MaterialApp(home: ClosedCaption(text: ''))); expect(find.byType(Text), findsNothing); }); testWidgets('Passes text contrast ratio guidelines', (WidgetTester tester) async { - final String text = 'foo'; - await tester.pumpWidget(MaterialApp( + const String text = 'foo'; + await tester.pumpWidget(const MaterialApp( home: Scaffold( backgroundColor: Colors.white, body: ClosedCaption(text: text), @@ -218,7 +220,7 @@ void main() { ); expect( fakeVideoPlayerPlatform.dataSources[0].httpHeaders, - {}, + {}, ); }); @@ -246,7 +248,7 @@ void main() { test('network with some headers', () async { final VideoPlayerController controller = VideoPlayerController.network( 'https://127.0.0.1', - httpHeaders: {'Authorization': 'Bearer token'}, + httpHeaders: {'Authorization': 'Bearer token'}, ); await controller.initialize(); @@ -260,7 +262,7 @@ void main() { ); expect( fakeVideoPlayerPlatform.dataSources[0].httpHeaders, - {'Authorization': 'Bearer token'}, + {'Authorization': 'Bearer token'}, ); }); @@ -269,10 +271,10 @@ void main() { 'http://testing.com/invalid_url', ); - late dynamic error; + late Object error; fakeVideoPlayerPlatform.forceInitError = true; - await controller.initialize().catchError((dynamic e) => error = e); - final PlatformException platformEx = error; + await controller.initialize().catchError((Object e) => error = e); + final PlatformException platformEx = error as PlatformException; expect(platformEx.code, equals('VideoError')); }); @@ -493,7 +495,7 @@ void main() { 'https://127.0.0.1', ); await controller.initialize(); - final progressWidget = + final VideoProgressIndicator progressWidget = VideoProgressIndicator(controller, allowScrubbing: true); await tester.pumpWidget(Directionality( @@ -505,7 +507,7 @@ void main() { expect(controller.value.isPlaying, isTrue); final Rect progressRect = tester.getRect(find.byWidget(progressWidget)); - await tester.dragFrom(progressRect.center, Offset(1.0, 0.0)); + await tester.dragFrom(progressRect.center, const Offset(1.0, 0.0)); await tester.pumpAndSettle(); expect(controller.value.position, lessThan(controller.value.duration)); @@ -520,7 +522,7 @@ void main() { 'https://127.0.0.1', ); await controller.initialize(); - final progressWidget = + final VideoProgressIndicator progressWidget = VideoProgressIndicator(controller, allowScrubbing: true); await tester.pumpWidget(Directionality( @@ -580,7 +582,7 @@ void main() { ); await controller.initialize(); - controller.setCaptionOffset(Duration(milliseconds: 100)); + controller.setCaptionOffset(const Duration(milliseconds: 100)); expect(controller.value.position, const Duration()); expect(controller.value.caption.text, ''); @@ -616,7 +618,7 @@ void main() { ); await controller.initialize(); - controller.setCaptionOffset(Duration(milliseconds: -100)); + controller.setCaptionOffset(const Duration(milliseconds: -100)); expect(controller.value.position, const Duration()); expect(controller.value.caption.text, ''); @@ -688,12 +690,11 @@ void main() { const Duration bufferStart = Duration(seconds: 0); const Duration bufferEnd = Duration(milliseconds: 500); - fakeVideoEventStream - ..add(VideoEvent( - eventType: VideoEventType.bufferingUpdate, - buffered: [ - DurationRange(bufferStart, bufferEnd), - ])); + fakeVideoEventStream.add(VideoEvent( + eventType: VideoEventType.bufferingUpdate, + buffered: [ + DurationRange(bufferStart, bufferEnd), + ])); await tester.pumpAndSettle(); expect(controller.value.isBuffering, isTrue); expect(controller.value.buffered.length, 1); @@ -854,45 +855,45 @@ void main() { group('aspectRatio', () { test('640x480 -> 4:3', () { - final value = VideoPlayerValue( + final VideoPlayerValue value = VideoPlayerValue( isInitialized: true, - size: Size(640, 480), - duration: Duration(seconds: 1), + size: const Size(640, 480), + duration: const Duration(seconds: 1), ); expect(value.aspectRatio, 4 / 3); }); test('no size -> 1.0', () { - final value = VideoPlayerValue( + final VideoPlayerValue value = VideoPlayerValue( isInitialized: true, - duration: Duration(seconds: 1), + duration: const Duration(seconds: 1), ); expect(value.aspectRatio, 1.0); }); test('height = 0 -> 1.0', () { - final value = VideoPlayerValue( + final VideoPlayerValue value = VideoPlayerValue( isInitialized: true, - size: Size(640, 0), - duration: Duration(seconds: 1), + size: const Size(640, 0), + duration: const Duration(seconds: 1), ); expect(value.aspectRatio, 1.0); }); test('width = 0 -> 1.0', () { - final value = VideoPlayerValue( + final VideoPlayerValue value = VideoPlayerValue( isInitialized: true, - size: Size(0, 480), - duration: Duration(seconds: 1), + size: const Size(0, 480), + duration: const Duration(seconds: 1), ); expect(value.aspectRatio, 1.0); }); test('negative aspect ratio -> 1.0', () { - final value = VideoPlayerValue( + final VideoPlayerValue value = VideoPlayerValue( isInitialized: true, - size: Size(640, -480), - duration: Duration(seconds: 1), + size: const Size(640, -480), + duration: const Duration(seconds: 1), ); expect(value.aspectRatio, 1.0); }); @@ -904,7 +905,7 @@ void main() { const Color bufferedColor = Color.fromRGBO(0, 255, 0, 0.5); const Color backgroundColor = Color.fromRGBO(255, 255, 0, 0.25); - final VideoProgressColors colors = VideoProgressColors( + const VideoProgressColors colors = VideoProgressColors( playedColor: playedColor, bufferedColor: bufferedColor, backgroundColor: backgroundColor); @@ -936,7 +937,7 @@ class FakeVideoPlayerPlatform extends VideoPlayerPlatform { @override Future create(DataSource dataSource) async { calls.add('create'); - StreamController stream = StreamController(); + final StreamController stream = StreamController(); streams[nextTextureId] = stream; if (forceInitError) { stream.addError(PlatformException( @@ -944,8 +945,8 @@ class FakeVideoPlayerPlatform extends VideoPlayerPlatform { } else { stream.add(VideoEvent( eventType: VideoEventType.initialized, - size: Size(100, 100), - duration: Duration(seconds: 1))); + size: const Size(100, 100), + duration: const Duration(seconds: 1))); } dataSources.add(dataSource); return nextTextureId++; @@ -962,6 +963,7 @@ class FakeVideoPlayerPlatform extends VideoPlayerPlatform { initialized.complete(true); } + @override Stream videoEventsFor(int textureId) { return streams[textureId]!.stream; } diff --git a/packages/video_player/video_player/test/web_vtt_test.dart b/packages/video_player/video_player/test/web_vtt_test.dart index 59fce98c5b71..bde629219484 100644 --- a/packages/video_player/video_player/test/web_vtt_test.dart +++ b/packages/video_player/video_player/test/web_vtt_test.dart @@ -14,9 +14,9 @@ void main() { parsedFile = WebVTTCaptionFile(_valid_vtt_with_metadata); expect(parsedFile.captions.length, 1); - expect(parsedFile.captions[0].start, Duration(seconds: 1)); - expect( - parsedFile.captions[0].end, Duration(seconds: 2, milliseconds: 500)); + expect(parsedFile.captions[0].start, const Duration(seconds: 1)); + expect(parsedFile.captions[0].end, + const Duration(seconds: 2, milliseconds: 500)); expect(parsedFile.captions[0].text, 'We are in New York City'); }); @@ -25,11 +25,11 @@ void main() { expect(parsedFile.captions.length, 1); expect(parsedFile.captions[0].start, - Duration(seconds: 2, milliseconds: 800)); - expect( - parsedFile.captions[0].end, Duration(seconds: 3, milliseconds: 283)); + const Duration(seconds: 2, milliseconds: 800)); + expect(parsedFile.captions[0].end, + const Duration(seconds: 3, milliseconds: 283)); expect(parsedFile.captions[0].text, - "— It will perforate your stomach.\n— You could die."); + '— It will perforate your stomach.\n— You could die.'); }); test('with styles tags', () { @@ -37,9 +37,9 @@ void main() { expect(parsedFile.captions.length, 3); expect(parsedFile.captions[0].start, - Duration(seconds: 5, milliseconds: 200)); - expect( - parsedFile.captions[0].end, Duration(seconds: 6, milliseconds: 000)); + const Duration(seconds: 5, milliseconds: 200)); + expect(parsedFile.captions[0].end, + const Duration(seconds: 6, milliseconds: 000)); expect(parsedFile.captions[0].text, "You know I'm so excited my glasses are falling off here."); }); @@ -49,9 +49,9 @@ void main() { expect(parsedFile.captions.length, 3); expect(parsedFile.captions[0].number, 1); - expect(parsedFile.captions.last.start, Duration(seconds: 4)); - expect(parsedFile.captions.last.end, Duration(seconds: 5)); - expect(parsedFile.captions.last.text, "Transcrit par Célestes™"); + expect(parsedFile.captions.last.start, const Duration(seconds: 4)); + expect(parsedFile.captions.last.end, const Duration(seconds: 5)); + expect(parsedFile.captions.last.text, 'Transcrit par Célestes™'); }); test('with [hours]:[minutes]:[seconds].[milliseconds].', () { @@ -59,9 +59,9 @@ void main() { expect(parsedFile.captions.length, 1); expect(parsedFile.captions[0].number, 1); - expect(parsedFile.captions.last.start, Duration(seconds: 1)); - expect(parsedFile.captions.last.end, Duration(seconds: 2)); - expect(parsedFile.captions.last.text, "This is a test."); + expect(parsedFile.captions.last.start, const Duration(seconds: 1)); + expect(parsedFile.captions.last.end, const Duration(seconds: 2)); + expect(parsedFile.captions.last.text, 'This is a test.'); }); test('with [minutes]:[seconds].[milliseconds].', () { @@ -69,9 +69,9 @@ void main() { expect(parsedFile.captions.length, 1); expect(parsedFile.captions[0].number, 1); - expect(parsedFile.captions.last.start, Duration(seconds: 3)); - expect(parsedFile.captions.last.end, Duration(seconds: 4)); - expect(parsedFile.captions.last.text, "This is a test."); + expect(parsedFile.captions.last.start, const Duration(seconds: 3)); + expect(parsedFile.captions.last.end, const Duration(seconds: 4)); + expect(parsedFile.captions.last.text, 'This is a test.'); }); test('with invalid seconds format returns empty captions.', () { @@ -105,8 +105,8 @@ void main() { final Caption firstCaption = parsedFile.captions.single; expect(firstCaption.number, 1); - expect(firstCaption.start, Duration(seconds: 13)); - expect(firstCaption.end, Duration(seconds: 16, milliseconds: 0)); + expect(firstCaption.start, const Duration(seconds: 13)); + expect(firstCaption.end, const Duration(seconds: 16, milliseconds: 0)); expect(firstCaption.text, 'Valid'); }); } diff --git a/script/configs/custom_analysis.yaml b/script/configs/custom_analysis.yaml index d10424e0b944..71f6f03de917 100644 --- a/script/configs/custom_analysis.yaml +++ b/script/configs/custom_analysis.yaml @@ -17,4 +17,3 @@ - in_app_purchase/in_app_purchase - in_app_purchase/in_app_purchase_android - in_app_purchase/in_app_purchase_storekit -- video_player/video_player