@@ -757,6 +757,45 @@ void main() {
757757 });
758758
759759 group ('caption' , () {
760+ test ('works when position updates' , () async {
761+ final VideoPlayerController controller =
762+ VideoPlayerController .networkUrl (
763+ _localhostUri,
764+ closedCaptionFile: _loadClosedCaption (),
765+ );
766+
767+ await controller.initialize ();
768+ await controller.play ();
769+
770+ // Optionally record caption changes for later verification.
771+ final Map <int , String > recordedCaptions = < int , String > {};
772+
773+ controller.addListener (() {
774+ // Record the caption for the current position (in milliseconds).
775+ final int ms = controller.value.position.inMilliseconds;
776+ recordedCaptions[ms] = controller.value.caption.text;
777+ });
778+
779+ const Duration updateInterval = Duration (milliseconds: 100 );
780+ const int totalDurationMs = 350 ;
781+
782+ // Simulate continuous playback by incrementing in 50ms steps.
783+ for (int ms = 0 ; ms <= totalDurationMs; ms += 50 ) {
784+ fakeVideoPlayerPlatform._positions[controller.textureId] =
785+ Duration (milliseconds: ms);
786+ await Future <void >.delayed (updateInterval);
787+ }
788+
789+ // Now, given your closed caption file and the 100ms update interval,
790+ // you expect:
791+ // • at 100ms: caption should be 'one'
792+ // • at 250ms: no caption (i.e. '')
793+ // • at 300ms: caption should be 'two'
794+ expect (recordedCaptions[100 ], 'one' );
795+ expect (recordedCaptions[250 ], '' );
796+ expect (recordedCaptions[300 ], 'two' );
797+ });
798+
760799 test ('works when seeking' , () async {
761800 final VideoPlayerController controller =
762801 VideoPlayerController .networkUrl (
@@ -995,6 +1034,41 @@ void main() {
9951034 });
9961035 });
9971036
1037+ test ('updates position' , () async {
1038+ final VideoPlayerController controller = VideoPlayerController .networkUrl (
1039+ _localhostUri,
1040+ videoPlayerOptions: VideoPlayerOptions (),
1041+ );
1042+
1043+ await controller.initialize ();
1044+
1045+ const Duration updatesInterval = Duration (milliseconds: 100 );
1046+
1047+ final List <Duration > positions = < Duration > [];
1048+ final Completer <void > intervalUpdateCompleter = Completer <void >();
1049+
1050+ // Listen for position updates
1051+ controller.addListener (() {
1052+ positions.add (controller.value.position);
1053+ if (positions.length >= 3 && ! intervalUpdateCompleter.isCompleted) {
1054+ intervalUpdateCompleter.complete ();
1055+ }
1056+ });
1057+ await controller.play ();
1058+ for (int i = 0 ; i < 3 ; i++ ) {
1059+ await Future <void >.delayed (updatesInterval);
1060+ fakeVideoPlayerPlatform._positions[controller.textureId] =
1061+ Duration (milliseconds: i * updatesInterval.inMilliseconds);
1062+ }
1063+
1064+ // Wait for at least 3 position updates
1065+ await intervalUpdateCompleter.future;
1066+
1067+ // Verify that the intervals between updates are approximately correct
1068+ expect (positions[1 ] - positions[0 ], greaterThanOrEqualTo (updatesInterval));
1069+ expect (positions[2 ] - positions[1 ], greaterThanOrEqualTo (updatesInterval));
1070+ });
1071+
9981072 group ('DurationRange' , () {
9991073 test ('uses given values' , () {
10001074 const Duration start = Duration (seconds: 2 );
0 commit comments