-
Notifications
You must be signed in to change notification settings - Fork 9.8k
Conversation
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed (or fixed any issues), please reply here with What to do if you already signed the CLAIndividual signers
Corporate signers
ℹ️ Googlers: Go here for more info. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR looks awesome! Thank you so much for the contribution.
I just left a few comments for suggestions/nits here and there.
packages/video_player/video_player/example/ios/Flutter/Flutter.podspec
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for adding thorough tests!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for this PR, I have left some comments. Also we need to update the CHANGELOG and the version number in the pubspec.yaml
@@ -0,0 +1,200 @@ | |||
// Copyright 2020 The Chromium Authors. All rights reserved. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
final Duration start; | ||
/// | ||
/// When the value is null, the caption object is invalid. | ||
final Duration? start; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
: _captions = _parseCaptionsFromWebVttString(fileContents); | ||
|
||
/// The entire body of the Vtt file. | ||
final String fileContents; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this public?
There was a problem hiding this comment.
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.
final List<Caption> captions = <Caption>[]; | ||
|
||
// Ignore metadata | ||
List<String> metadata = ['HEADER', 'NOTE', 'REGION', 'WEBVTT']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Set
// [00:00.000 --> 01:24.000 align:center] | ||
// ['Introduction'] | ||
// ] | ||
// if caption has just header or time, but no text, captionLines.length will be 1 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
} | ||
|
||
final List<String> dotSections = timestampString.split('.'); | ||
final List<String> hoursMinutesSeconds = dotSections[0].split(':'); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
import 'closed_caption_file.dart'; | ||
import 'package:html/parser.dart' as html_parser; | ||
|
||
/// Represents a [ClosedCaptionFile], parsed from the WebVtt file format. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WebVTT
There was a problem hiding this comment.
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.
import 'package:html/parser.dart' as html_parser; | ||
|
||
/// Represents a [ClosedCaptionFile], parsed from the WebVtt file format. | ||
/// See: https://en.wikipedia.org/wiki/WebVtt |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
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] |
There was a problem hiding this comment.
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)
// Timestamp takes the form of [minutes]:[seconds].[milliseconds] | ||
minutes = int.parse(hoursMinutesSeconds[0]); | ||
seconds = int.parse(hoursMinutesSeconds[1]); | ||
} |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with various nits.
(If for whatever reason you feel like doing the bigger change, I can re-review that part, otherwise it's good to land without another review pass.)
packages/video_player/video_player/lib/src/closed_caption_file.dart
Outdated
Show resolved
Hide resolved
packages/video_player/video_player/lib/src/closed_caption_file.dart
Outdated
Show resolved
Hide resolved
|
||
List<String> milisecondsStyles = dotSections[1].split(" "); | ||
|
||
// TODO(cyanglaz): Handle caption styles. |
There was a problem hiding this comment.
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 :)
There was a problem hiding this comment.
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.
@@ -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; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
This pull request is not suitable for automatic merging in its current state.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approving to fix CI
* master: (51 commits) [webview_flutter] Update version number app_facing package (flutter#4375) [webview_flutter] Adjust integration test domains (flutter#4383) Remove some trivial custom analysis options files (flutter#4379) [google_maps_flutter_platfomr_interface] Add Marker drag events (flutter#2653) [flutter_plugin_tools] Improve version check error handling (flutter#4376) [flutter_plugin_tools] Allow overriding breaking change check (flutter#4369) [url_launcher] Error handling when URL cannot be parsed with Uri.parse (flutter#4365) [webview_flutter] Migrate main package to fully federated architecture. (flutter#4366) [google_sign_in] Bump minimum Flutter version and iOS deployment target (flutter#4334) Add false secret lists, and enforce ordering (flutter#4372) [camera_web] Update usage documentation (flutter#4371) [video_player] VTT Support (flutter#2878) Require authors file (flutter#4367) [flutter_plugin_tools] Fix federated safety check (flutter#4368) [webview_flutter] Extract WKWebView implementation into a separate package (flutter#4345) [webview_flutter] Extract Android implementation into a separate package (flutter#4343) [in_app_purchase] Ensure the `introductoryPriceMicros` field is populated correctly. (flutter#4364) [flutter_plugin_tools] Add a federated PR safety check (flutter#4329) [camera] Add web support (flutter#4240) [webview_flutter] Bump minimum Flutter version and iOS deployment target (flutter#4361) ... # Conflicts: # packages/webview_flutter/webview_flutter/lib/platform_interface.dart # packages/webview_flutter/webview_flutter/lib/src/webview_method_channel.dart # packages/webview_flutter/webview_flutter/lib/webview_flutter.dart
Description
Class WebVTTCaptionFile created.
Related Issues
flutter/flutter#50595
Checklist
Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes (
[x]
). This will ensure a smooth and quick review process.///
).flutter analyze
) does not report any problems on my PR.Breaking Change
Does your PR require plugin users to manually update their apps to accommodate your change?