Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 71 commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
9788b63
Web VTT Supported Added
Jul 15, 2020
a66f5d7
Fixes
Jul 15, 2020
6481331
VTT with header added
Jul 15, 2020
8f8b095
VTT with header added
Jul 15, 2020
da1c6e4
VTT with header added
Jul 15, 2020
1a21621
VTT with header added
Jul 15, 2020
0d3549e
New tests added
Jul 15, 2020
b018ea9
tests organized by group
Jul 15, 2020
b92f305
Changelog updated
Jul 15, 2020
1573670
Sample vtt renamed
Jul 15, 2020
1e53fc5
Sample vtt renamed
Jul 15, 2020
9034263
Todo Styles commented
Jul 15, 2020
d9647a9
Sample VTT file fixed
Jul 16, 2020
2ebf99f
Sample VTT file fixed
Jul 16, 2020
43abfd6
Sample VTT file fixed
Jul 16, 2020
a44edea
Credentials added
ferrazrx Jul 16, 2020
d92e820
Credentials added
ferrazrx Jul 16, 2020
10e717c
Merge branch 'ferrazrx/web_vtt' of github.com:ferrazrx/plugins into f…
ferrazrx Jul 16, 2020
98e21c1
[image_picker] Add web support to the example app. (#2816)
ferrazrx Jun 5, 2020
e146366
Fix bug in example (#2801)
ferrazrx Jun 6, 2020
c05a6f1
Update Linux desktop Dockerfile for GTK switch (#2826)
ferrazrx Jun 13, 2020
50044cc
[image_picker] fixes for iOS which doesn't present camera/albums with…
ferrazrx Jun 15, 2020
2aacc0f
[path_provider] Updated documentation reflecting changes needed for t…
ferrazrx Jun 16, 2020
928bfb4
[url_launcher] docs: note about encoding URIs (#2172)
ferrazrx Jun 17, 2020
ee9e13a
[In_App_Purchase]queryPastPurchases() shouldn't block transaction upd…
ferrazrx Jun 22, 2020
bf3e958
[e2e] Fix e2e pixel ratio (#2842)
ferrazrx Jun 23, 2020
91bba0f
Update README for plugin list (#2843)
ferrazrx Jun 24, 2020
459b7f8
[connectivity_for_web] Introduce connectivity_for_web package. (#2820)
ferrazrx Jun 30, 2020
b43b1a8
[url_launcher_web] Adds "tel" and "sms" URL support (#2847)
ferrazrx Jun 30, 2020
db547b6
[shared_preferences_linux] Add support for Linux (#2836)
ferrazrx Jun 30, 2020
7864399
[e2e] Use SettableFuture instead of CompletableFuture (#2854)
ferrazrx Jul 1, 2020
7afa2c2
[connectivity] Endorse connectivity_for_web. (#2853)
ferrazrx Jul 1, 2020
a8a5994
[e2e] Bump version to 0.6.0 (#2855)
ferrazrx Jul 1, 2020
0fdc514
[multiple] Improve video playback in image_picker example (#2819)
ferrazrx Jul 1, 2020
1ca27a7
[image_picker] updated VALID_ARCHS to support iPhone simulator (#2761)
ferrazrx Jul 6, 2020
39ba0ae
[url_launcher_linux] Add Linux url_launcher plugin (#2857)
ferrazrx Jul 7, 2020
7391c73
[url_launcher] Endorse url_launcher_linux (#2863)
ferrazrx Jul 7, 2020
00efa43
[shared_preferences_linux] Add iOS stub (#2865)
ferrazrx Jul 8, 2020
8e1dcad
[shared_preferences] Shared preferences linux endorsement (#2864)
ferrazrx Jul 8, 2020
9fdcb05
[connectivity_for_web] Fix JS Interop in release mode. (#2869)
ferrazrx Jul 13, 2020
f0e286b
[google_sign_in] Bridge google_sign_in and googleapis. (#2824)
ferrazrx Jul 14, 2020
1350f8e
Web VTT Supported Added
ferrazrx Jul 15, 2020
c72a068
Fixes
ferrazrx Jul 15, 2020
226b9c6
VTT with header added
ferrazrx Jul 15, 2020
4554771
VTT with header added
ferrazrx Jul 15, 2020
0b7dde4
VTT with header added
ferrazrx Jul 15, 2020
7aa17ba
VTT with header added
ferrazrx Jul 15, 2020
2f686c2
New tests added
ferrazrx Jul 15, 2020
5d09170
tests organized by group
ferrazrx Jul 15, 2020
78098ca
Changelog updated
ferrazrx Jul 15, 2020
46aecd8
Sample vtt renamed
ferrazrx Jul 15, 2020
cacf4dc
Sample vtt renamed
ferrazrx Jul 15, 2020
5524931
Todo Styles commented
ferrazrx Jul 15, 2020
110c115
Sample VTT file fixed
ferrazrx Jul 16, 2020
808b1a0
Sample VTT file fixed
ferrazrx Jul 16, 2020
a041f54
Sample VTT file fixed
ferrazrx Jul 16, 2020
2a16e2e
Credentials added
ferrazrx Jul 16, 2020
acf7417
Merge branch 'ferrazrx/web_vtt' of github.com:ferrazrx/plugins into f…
ferrazrx Jul 16, 2020
de3c973
Comments fixed
ferrazrx Jul 17, 2020
495b37c
Comments fixed
ferrazrx Jul 17, 2020
fc0d049
Version Changed
ferrazrx Jul 17, 2020
9db4ec1
Version Changed
ferrazrx Jul 17, 2020
c5bbba6
Comments fixed
ferrazrx Jul 22, 2020
7bb0d53
Public comments fixed
ferrazrx Aug 20, 2020
d47ea7f
CHANGELOG.md updated
ferrazrx Aug 20, 2020
4c66c38
Merge remote-tracking branch 'upstream/master' into ferrazrx/web_vtt
ferrazrx Aug 20, 2020
db79449
Format fixed
ferrazrx Aug 20, 2020
fa0d6dc
Version updated
ferrazrx Aug 20, 2020
a4fcbf7
merge master, nnbd migration
Sep 13, 2021
61a22a5
add issue links for TODOs
Sep 13, 2021
14468e5
Merge branch 'master' into ferrazrx/web_vtt
Sep 16, 2021
0d68872
review
Sep 21, 2021
c97876c
Merge branch 'ferrazrx/web_vtt' of github.com:ferrazrx/plugins into f…
Sep 21, 2021
6c457a5
Merge branch 'master' into ferrazrx/web_vtt
Sep 21, 2021
5ffff31
review 2
Sep 21, 2021
c8f7c2c
fix license header
Sep 22, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/video_player/video_player/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.2.4

* Support to closed caption web vtt format added.

## 2.2.3

* Fixed empty caption text still showing the caption widget.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
WEBVTT

00:00:00.200 --> 00:00:01.750
[ Birds chirping ]

00:00:02.300 --> 00:00:05.000
[ Buzzing ]
5 changes: 3 additions & 2 deletions packages/video_player/video_player/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,9 @@ class _BumbleBeeRemoteVideoState extends State<_BumbleBeeRemoteVideo> {

Future<ClosedCaptionFile> _loadCaptions() async {
final String fileContents = await DefaultAssetBundle.of(context)
.loadString('assets/bumble_bee_captions.srt');
return SubRipCaptionFile(fileContents);
.loadString('assets/bumble_bee_captions.vtt');
return WebVttCaptionFile(
fileContents); // For vtt files, use WebVttCaptionFile
}

@override
Expand Down
7 changes: 4 additions & 3 deletions packages/video_player/video_player/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ dev_dependencies:
flutter:
uses-material-design: true
assets:
- assets/flutter-mark-square-64.png
- assets/Butterfly-209.mp4
- assets/bumble_bee_captions.srt
- assets/flutter-mark-square-64.png
- assets/Butterfly-209.mp4
- assets/bumble_bee_captions.srt
- assets/bumble_bee_captions.vtt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import 'sub_rip.dart';
export 'sub_rip.dart' show SubRipCaptionFile;

import 'web_vtt.dart';
export 'web_vtt.dart' show WebVttCaptionFile;

/// A structured representation of a parsed closed caption file.
///
/// A closed caption file includes a list of captions, each with a start and end
Expand All @@ -15,6 +18,7 @@ export 'sub_rip.dart' show SubRipCaptionFile;
///
/// See:
/// * [SubRipCaptionFile].
/// * [WebVttCaptionFile].
abstract class ClosedCaptionFile {
/// The full list of captions from a given file.
///
Expand Down Expand Up @@ -42,10 +46,14 @@ class Caption {
final int number;

/// When in the given video should this [Caption] begin displaying.
final Duration start;
///
/// When the value is null, the caption object is invalid.
Comment thread
cyanglaz marked this conversation as resolved.
Outdated
final Duration? start;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a breaking change, because this whole file is exported.

Why do we need the ability to make invalid Caption objects in the first place? That seems like a strange thing to allow. If this is just for:

    final Caption newCaption = Caption(
      number: captionNumber,
      start: startAndEnd.start,
      end: startAndEnd.end,
      text: textWithoutFormat,
    );

    if (newCaption.start != null && newCaption.end != null) {
      captions.add(newCaption);
      captionNumber++;
    }

the caption is being thrown away anyway, so we can just not make it in the first place.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call.
Updated to make start and end non-null


/// When in the given video should this [Caption] be dismissed.
final Duration end;
///
/// When the value is null, the caption object is invalid.
Comment thread
cyanglaz marked this conversation as resolved.
Outdated
final Duration? end;

/// The actual text that should appear on screen to be read between [start]
/// and [end].
Expand Down
200 changes: 200 additions & 0 deletions packages/video_player/video_player/lib/src/web_vtt.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
// Copyright 2020 The Chromium Authors. All rights reserved.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be "Copyright 2013 The Flutter Authors." in both new files, which is why format is unhappy.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:convert';
Comment thread
cyanglaz marked this conversation as resolved.

import 'package:html/dom.dart';

import 'closed_caption_file.dart';
import 'package:html/parser.dart' as html_parser;

/// Represents a [ClosedCaptionFile], parsed from the WebVtt file format.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WebVTT

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated so all the appearance of WebVtt are WebVTT now.

/// See: https://en.wikipedia.org/wiki/WebVtt

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This link is broken; it's https://en.wikipedia.org/wiki/WebVTT

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

class WebVttCaptionFile extends ClosedCaptionFile {
/// Parses a string into a [ClosedCaptionFile], assuming [fileContents] is in
/// the WebVtt file format.
/// * See: https://en.wikipedia.org/wiki/WebVtt
WebVttCaptionFile(this.fileContents)
Comment thread
ferrazrx marked this conversation as resolved.
Outdated
: _captions = _parseCaptionsFromWebVttString(fileContents);

/// The entire body of the Vtt file.
final String fileContents;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this public?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was probably a copy paste from SubRipCaptionFile in sub_rip.dart. Removed fileContents completely. Also added TODO in sub_rip.dart . It's going to be a breaking change to update it in sub_rip.dart and I think it would be better to update it when there's a meaningful breaking change for this plugin.

I'm not sure how to keep track of this tho. We might forgot about this when doing breaking changes in the plugin.


@override
List<Caption> get captions => _captions;

final List<Caption> _captions;
}

List<Caption> _parseCaptionsFromWebVttString(String file) {
final List<Caption> captions = <Caption>[];

// Ignore metadata
List<String> metadata = ['HEADER', 'NOTE', 'REGION', 'WEBVTT'];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Set


int captionNumber = 1;
for (List<String> captionLines in _readWebVttFile(file)) {
// CaptionLines represent a complete caption
// E.g
// [
// [00:00.000 --> 01:24.000 align:center]
// ['Introduction']
// ]
// if caption has just header or time, but no text, captionLines.length will be 1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix the comments to be capitalized and end with a period, per normal style.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

if (captionLines.length < 2) continue;
Comment thread
cyanglaz marked this conversation as resolved.

// if caption has header equal metadata, ignore
String metadaType = captionLines[0].split(' ')[0];
if (metadata.contains(metadaType)) continue;

// Caption has header
bool hasHeader = captionLines.length > 2;
if (hasHeader && int.tryParse(captionLines[0]) != null) {
captionNumber = int.parse(captionLines[0]);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't parse twice just to avoid one more nested if.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}

final _StartAndEnd startAndEnd = _StartAndEnd.fromWebVttString(
hasHeader ? captionLines[1] : captionLines[0],
);

final String text = captionLines.sublist(hasHeader ? 2 : 1).join('\n');

// TODO(cyanglaz): Handle special syntax in vtt captions.
// https://github.com/flutter/flutter/issues/90007.
final String textWithoutFormat = _parseHtmlString(text);

final Caption newCaption = Caption(
number: captionNumber,
start: startAndEnd.start,
end: startAndEnd.end,
text: textWithoutFormat,
);

if (newCaption.start != null && newCaption.end != null) {
captions.add(newCaption);
captionNumber++;
}
}

return captions;
}

class _StartAndEnd {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a weird name; could we call it _CaptionRange?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another copy paste from sub_rip, will fix it there too

// When there's an error parsing the start or end, either could be null.
final Duration? start;
final Duration? end;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like it would be cleaner for fromWebVttString to return a nullable value, and for these to be non-nullable. We shouldn't allow invalid objects just to allow factories to sometimes create them.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


_StartAndEnd(this.start, this.end);

// Assumes format from an Vtt file.
// For example:
// 00:09.000 --> 00:11.000
static _StartAndEnd fromWebVttString(String line) {
final RegExp format =
RegExp(_webVttTimeStamp + _webVttArrow + _webVttTimeStamp);

if (!format.hasMatch(line)) {
return _StartAndEnd(null, null);
}

final List<String> times = line.split(_webVttArrow);

final Duration? start = _parseWebVttTimestamp(times[0]);
final Duration? end = _parseWebVttTimestamp(times[1]);

return _StartAndEnd(start, end);
}
}

String _parseHtmlString(String htmlString) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's call this _extractTextFromHtml; I would expect parse to return a tree or similar.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

final Document document = html_parser.parse(htmlString);
final Element? body = document.body;
if (body == null) {
return '';
}
final Element? bodyElement = html_parser.parse(body.text).documentElement;
if (bodyElement == null) {
return '';
}
return bodyElement.text;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional nit: return bodyElement?.text ?? '';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}

// Parses a time stamp in an Vtt file into a Duration.
// For example:
//
// _parseWebVttimestamp('00:01:08.430')
// returns
// Duration(hours: 0, minutes: 1, seconds: 8, milliseconds: 430)
Comment thread
cyanglaz marked this conversation as resolved.
Duration? _parseWebVttTimestamp(String timestampString) {
if (!RegExp(_webVttTimeStamp).hasMatch(timestampString)) {
return null;
}

final List<String> dotSections = timestampString.split('.');
final List<String> hoursMinutesSeconds = dotSections[0].split(':');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: timeComponents. There's no guarantee that this has all of these.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


int hours = 0;
int minutes = 0;
int seconds = 0;

if (hoursMinutesSeconds.length > 2) {
Comment thread
ferrazrx marked this conversation as resolved.
Outdated
// Timestamp takes the form of [hours]:[minutes]:[seconds].[milliseconds]
hours = int.parse(hoursMinutesSeconds[0]);
minutes = int.parse(hoursMinutesSeconds[1]);
seconds = int.parse(hoursMinutesSeconds[2]);
} else if (int.parse(hoursMinutesSeconds[0]) > 59) {
// Timestamp takes the form of [hours]:[minutes].[milliseconds]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seemed deeply strange to me so I checked the spec, and this isn't a valid timestamp. We shouldn't handle invalid values unless there's substantial real-world evidence that lots of people have written this (which seems unlikely, because even if other parsers allow this it is incapable of expressing any time within the first 59 hours of a video)

// First position is hours as it's over 59.
hours = int.parse(hoursMinutesSeconds[0]);
minutes = int.parse(hoursMinutesSeconds[1]);
} else {
// Timestamp takes the form of [minutes]:[seconds].[milliseconds]
minutes = int.parse(hoursMinutesSeconds[0]);
seconds = int.parse(hoursMinutesSeconds[1]);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once the above is removed, this can all condense to:

int hours = 0;
if (hoursMinutesSeconds.length == 3) {
  hours = int.parse(timeComponents.removeAt(0));
}
final int minutes = int.parse(timeComponents.removeAt(0));
final int seconds = int.parse(timeComponents.removeAt(0));

It would be good to add a safety check that the length is either 2 or 3 and returns null first, as well.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


List<String> milisecondsStyles = dotSections[1].split(" ");

// TODO(cyanglaz): Handle caption styles.

@stuartmorgan-g stuartmorgan-g Sep 21, 2021

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I'm reading this again: it's weird that _parseWebVTTTimestamp is where captions would be handled. I think the caller—which is already doing a regex match for timestamps anyway—should just use match groups (the regex would need to be adjusted slightly since right now it's making groups for all the sub-pieces of the timestamp, which isn't actually used) to extract just the timestamps, and then pass those here, removing the need for the milisecondsStyles = dotSections[1].split(" "). Then the caption-handling TODO would go in the calling function, not here.

But I'm fine with that being something that's cleaned up if/when this functionality is added since I don't want to keep piling changes onto a PR you adopted in the first place :)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, I'll put a note in the code and link this comment.

// https://github.com/flutter/flutter/issues/90009.
// if (milisecondsStyles.length > 1) {
// List<String> styles = milisecondsStyles.sublist(1);
// }
int milliseconds = int.parse(milisecondsStyles[0]);

return Duration(
hours: hours,
minutes: minutes,
seconds: seconds,
milliseconds: milliseconds,
);
}

// Reads on Vtt file and splits it into Lists of strings where each list is one
// caption.
List<List<String>> _readWebVttFile(String file) {
final List<String> lines = LineSplitter.split(file).toList();

final List<List<String>> captionStrings = <List<String>>[];
List<String> currentCaption = <String>[];
int lineIndex = 0;
for (final String line in lines) {
final bool isLineBlank = line.trim().isEmpty;
if (!isLineBlank) {
currentCaption.add(line);
}

if (isLineBlank || lineIndex == lines.length - 1) {
captionStrings.add(currentCaption);
currentCaption = <String>[];
}

lineIndex += 1;
}

return captionStrings;
}

const String _webVttTimeStamp = r'(\d+):(\d{2})(:\d{2})?\.(\d{3})';
const String _webVttArrow = r' --> ';
7 changes: 6 additions & 1 deletion packages/video_player/video_player/lib/video_player.dart
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,12 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {

// TODO: This would be more efficient as a binary search.
for (final caption in _closedCaptionFile!.captions) {
if (caption.start <= position && caption.end >= position) {
final Duration? start = caption.start;
final Duration? end = caption.end;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is no longer needed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

if (start == null || end == null) {
continue;
}
if (start <= position && end >= position) {
return caption;
}
}
Expand Down
4 changes: 3 additions & 1 deletion packages/video_player/video_player/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ description: Flutter plugin for displaying inline video with other Flutter
widgets on Android, iOS, and web.
repository: https://github.com/flutter/plugins/tree/master/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.3
version: 2.2.4


environment:
sdk: ">=2.12.0 <3.0.0"
Expand Down Expand Up @@ -32,6 +33,7 @@ dependencies:
# TODO(amirh): Revisit this (either update this part in the design or the pub tool).
# https://github.com/flutter/flutter/issues/46264
video_player_web: ^2.0.0
html: ^0.15.0

dev_dependencies:
flutter_test:
Expand Down
Loading