[video_player] Add setClosedCaptionFile method to VideoPlayerController#5105
Conversation
stuartmorgan-g
left a comment
There was a problem hiding this comment.
Thanks for the submission!
stuartmorgan-g
left a comment
There was a problem hiding this comment.
Looks good other than the version issue.
@bparrishMines Could you do the secondary review here?
| @@ -1,6 +1,7 @@ | |||
| ## NEXT | |||
| ## 2.3.1 | |||
There was a problem hiding this comment.
Sorry, I missed this before: this version change should be 2.4.0 rather than 2.3.1, since this is a new feature rather than a bugfix.
| 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.3.0 | ||
| version: 2.3.1 |
There was a problem hiding this comment.
This needs to match.
| ## 2.4.0 | ||
|
|
||
| * Updates minimum Flutter version to 2.10. | ||
| * Adds `setClosedCaptionFile` method to `VideoPlayerController` |
There was a problem hiding this comment.
Nit: missing period at the end (missed this in the previous review).
There was a problem hiding this comment.
This hasn't been resolved.
There was a problem hiding this comment.
Still not resolved.
| /// | ||
| /// If [closedCaptionFile] is null, closed caption file will be removed. | ||
| Future<void> setClosedCaptionFile( | ||
| Future<ClosedCaptionFile>? closedCaptionFile, |
There was a problem hiding this comment.
I think this would be better as FutureOr<ClosedCaptionFile?> closedCaptionFile so a user wouldn't have to use Future.value() to pass a value synchronously.
There was a problem hiding this comment.
Or better yet, I think just making it synchronous would be best if possible: ClosedCaptionFile? closedCaptionFile.
There was a problem hiding this comment.
Actually, I made it synchronous but then I turned it to async because closedCaptionFile parameter in initialize method is async. I don't know why closedCaptionFile parameter is Future but I thought if they made it Future, there was a logic behind it. However, my main thought is to make it synchronous as I mentioned in the issue (In short, removing closedCaptionFile parameter and adding a sync setter and getter for closedCaptionFile). But this would be a breaking change, so I decided to add just a setter method. I discussed this with stuartmorgan but I want to ask that question to you too because I'm wondering your thoughts, Can we make this breaking change? I think synchronous would be better in general.
There was a problem hiding this comment.
I missed in my review that you didn't change final Future<ClosedCaptionFile>? closedCaptionFile; to a getter, which was part of what we discussed. This change will leave the public accessor returning the wrong file.
(That should also be added to the tests, since it was missed.)
Can we make this breaking change
We are not making a breaking change in video_player for this; that's a disruptive change, and this is a niche use case that can easily be accommodated by a non-breaking change.
@bparrishMines I forgot the previous discussion was in Discord rather than here, so you wouldn't have context, sorry about that. I suggested the Future<> version for consistency; I could see an argument for making it take a file directly and then convert to a Future internally for compatibility with the existing public getter API; I don't have a strong opinion on that.
There was a problem hiding this comment.
Ah, I hadn't realized this was already discussed. No worries. This solution sounds good to me! (Assuming @stuartmorgan will wait for the accessor change.)
There was a problem hiding this comment.
A getter does not allow assigning a value (nor is the
finalkeyword applicable to it)
Yes, I know.
To be honest, I don't know how to change final Future<ClosedCaptionFile>? closedCaptionFile; to a getter. I turned it to Future<ClosedCaptionFile>? closedCaptionFile; but it became assignable. That's what i'm trying to say. So, how can I change it to a getter?
There was a problem hiding this comment.
I believe @stuartmorgan was thinking something like:
VideoPlayerController.asset(/*other params*/, {Future<closedCaptionFile>? closedCaptionFile, /*otherparams*/})
: _closedCaptionFile = closedCaptionFile;
Future<ClosedCaptionFile>? _closedCaptionFile;
Future<ClosedCaptionFile>? get closedCaptionFile {
return _closedCaptureFile;
}There was a problem hiding this comment.
Exactly, with the caveat that the member variable will need to be called something like _closedCaptionFileFuture since there's already a _closedCaptionFile.
To be honest, I don't know how to change
final Future<ClosedCaptionFile>? closedCaptionFile;to a getter. I turned it toFuture<ClosedCaptionFile>? closedCaptionFile;but it became assignable. That's what i'm trying to say.
In the future, if you aren't sure how to implement a suggestion it is much more effective to simply ask, rather than doing something completely different without explaining what you did and then ask questions about that instead. I had absolutely no context for the question you were asking since I didn't know what the code you'd actually written was (or that it was different from my suggestion).
There was a problem hiding this comment.
Exactly, with the caveat that the member variable will need to be called something like _closedCaptionFileFuture since there's already a _closedCaptionFile.
Thanks for the answer. I implemented this and everything works fine except the document. Now, the closedCaptionFile parameter shows the constructors' document. (I'm not talking about the getter, its document is ok)
In the future, if you aren't sure how to implement a suggestion it is much more effective to simply ask, rather than doing something completely different without explaining what you did and then ask questions about that instead. I had absolutely no context for the question you were asking since I didn't know what the code you'd actually written was (or that it was different from my suggestion).
Thanks for your feedback. I'll do.
There was a problem hiding this comment.
I committed the changes
| /// | ||
| /// If [closedCaptionFile] is null, closed caption file will be removed. | ||
| Future<void> setClosedCaptionFile( | ||
| Future<ClosedCaptionFile>? closedCaptionFile, |
There was a problem hiding this comment.
I missed in my review that you didn't change final Future<ClosedCaptionFile>? closedCaptionFile; to a getter, which was part of what we discussed. This change will leave the public accessor returning the wrong file.
(That should also be added to the tests, since it was missed.)
Can we make this breaking change
We are not making a breaking change in video_player for this; that's a disruptive change, and this is a niche use case that can easily be accommodated by a non-breaking change.
@bparrishMines I forgot the previous discussion was in Discord rather than here, so you wouldn't have context, sorry about that. I suggested the Future<> version for consistency; I could see an argument for making it take a file directly and then convert to a Future internally for compatibility with the existing public getter API; I don't have a strong opinion on that.
| ## 2.4.0 | ||
|
|
||
| * Updates minimum Flutter version to 2.10. | ||
| * Adds `setClosedCaptionFile` method to `VideoPlayerController` |
There was a problem hiding this comment.
This hasn't been resolved.
| /// This future will be awaited and the file will be loaded when | ||
| /// [initialize()] is called. | ||
| final Future<ClosedCaptionFile>? closedCaptionFile; | ||
| Future<ClosedCaptionFile>? get closedCaptionFile { |
There was a problem hiding this comment.
Please put this after the field declarations, not in the middle of them. Right before setClosedCaptionFile would be the best place.
| _closedCaptionFile ??= await closedCaptionFile; | ||
| value = value.copyWith(caption: _getCaptionAt(value.position)); | ||
| if (_closedCaptionFileFuture != null) { | ||
| await setClosedCaptionFile(_closedCaptionFileFuture); |
There was a problem hiding this comment.
Calling the setter to set the same value that the field is already set to in order to benefit from side-effects in the setter is an anti-pattern; it makes the code less understandable, and is subject to subtle breakage if someone later optimizes the setter to be a no-op if the new and old values are the same.
The way to share code here would be to make a new _updateClosedCaptionWithFuture(...) method and put the logic there, then implement both initialize and setClosedCaptionFile using that.
There was a problem hiding this comment.
I guess everything is okay now.
| ## 2.4.0 | ||
|
|
||
| * Updates minimum Flutter version to 2.10. | ||
| * Adds `setClosedCaptionFile` method to `VideoPlayerController` |
There was a problem hiding this comment.
Still not resolved.
| return Caption.none; | ||
| } | ||
|
|
||
| /// Optional field to specify a file containing the closed |
There was a problem hiding this comment.
This sentence is no longer correct, since it's not a field now.
/// Returns the file containing closed captions for the video, if any.
|
|
||
| /// Sets a closed caption file. | ||
| /// | ||
| /// If [closedCaptionFile] is null, closed caption file will be removed. |
There was a problem hiding this comment.
s/closed caption file/closed captions/
There was a problem hiding this comment.
I didn't understand what you mean
There was a problem hiding this comment.
Sorry, I shouldn't use that shorthand in reviews.
Please replace "closed caption file" with "closed captions" in this comment.
|
Hope everything is fine now. And by the way, I want to thank you for your help @stuartmorgan. |
|
The CHANGELOG issue that I've commented on three times is still unaddressed. We do require that PRs follow our style guides (which is why it's part of the checklist). |
|
Sorry, my bad |
This PR adds setClosedCaptionFile method to VideoPlayerController to add, change or remove closedCaptionFile.
Fixes flutter/flutter#100302
Pre-launch Checklist
dart format.)[shared_preferences]pubspec.yamlwith an appropriate new version according to the pub versioning philosophy, or this PR is exempt from version changes.CHANGELOG.mdto add a description of the change, following repository CHANGELOG style.///).