From 7b2736318abde0ef8af7ea93cc3af0e5e699bd9d Mon Sep 17 00:00:00 2001 From: "yying.jin" Date: Wed, 12 Nov 2025 19:44:40 +0800 Subject: [PATCH 1/4] fix subtitle rendering issue --- .../lib/src/video_player_tizen.dart | 1 + .../video_player_avplay/lib/video_player.dart | 22 ++++++++++++++++--- .../lib/video_player_platform_interface.dart | 8 +++++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/packages/video_player_avplay/lib/src/video_player_tizen.dart b/packages/video_player_avplay/lib/src/video_player_tizen.dart index ec133cdef..03d4af72d 100644 --- a/packages/video_player_avplay/lib/src/video_player_tizen.dart +++ b/packages/video_player_avplay/lib/src/video_player_tizen.dart @@ -437,6 +437,7 @@ class VideoPlayerTizen extends VideoPlayerPlatform { return VideoEvent( eventType: VideoEventType.subtitleUpdate, text: map['text']! as String, + textDuration: map['duration'] as int?, subtitleAttributes: map['attributes']! as List, ); case 'isPlayingStateUpdate': diff --git a/packages/video_player_avplay/lib/video_player.dart b/packages/video_player_avplay/lib/video_player.dart index 9aa15ef99..10c1e3b37 100644 --- a/packages/video_player_avplay/lib/video_player.dart +++ b/packages/video_player_avplay/lib/video_player.dart @@ -182,6 +182,16 @@ class VideoPlayerValue { return aspectRatio; } + /// Returns the [Caption] that should be displayed based on the current [position]. + /// If the value of [caption.end] has greater than the current [position], this will be a [Caption.none] object. + /// Only used for [copyWith]. + Caption get _currentCaption { + if (position > caption.end) { + return Caption.none; + } + return caption; + } + /// Returns a new instance that has the same values as this current instance, /// except for any overrides passed in as arguments to [copyWidth]. VideoPlayerValue copyWith({ @@ -206,7 +216,7 @@ class VideoPlayerValue { duration: duration ?? this.duration, size: size ?? this.size, position: position ?? this.position, - caption: caption ?? this.caption, + caption: caption ?? _currentCaption, captionOffset: captionOffset ?? this.captionOffset, tracks: tracks ?? this.tracks, buffered: buffered ?? this.buffered, @@ -594,7 +604,7 @@ class VideoPlayerController extends ValueNotifier { // we use pause() and seekTo() to ensure the platform stops playing // and seeks to the last frame of the video. pause().then((void pauseResult) => seekTo(value.duration.end)); - value = value.copyWith(isCompleted: true); + value = value.copyWith(isCompleted: true, caption: Caption.none); _durationTimer?.cancel(); case VideoEventType.bufferingUpdate: value = value.copyWith(buffered: event.buffered); @@ -607,13 +617,19 @@ class VideoPlayerController extends ValueNotifier { SubtitleAttribute.fromEventSubtitleAttrList( event.subtitleAttributes, ); + final Duration textDuration = event.textDuration == 0 + ? Duration.zero + : Duration(milliseconds: event.textDuration!); + print('*****textDuration is $textDuration*******'); final Caption caption = Caption( number: 0, start: value.position, - end: value.position + (event.duration?.end ?? Duration.zero), + end: value.position + textDuration, text: event.text ?? '', subtitleAttributes: subtitleAttributes, ); + print( + '*****Caption start is ${caption.start}, end is ${caption.end}*******'); value = value.copyWith(caption: caption); case VideoEventType.isPlayingStateUpdate: if (event.isPlaying ?? false) { diff --git a/packages/video_player_avplay/lib/video_player_platform_interface.dart b/packages/video_player_avplay/lib/video_player_platform_interface.dart index c55a51e17..cbc21b86e 100644 --- a/packages/video_player_avplay/lib/video_player_platform_interface.dart +++ b/packages/video_player_avplay/lib/video_player_platform_interface.dart @@ -555,6 +555,7 @@ class VideoEvent { this.size, this.buffered, this.text, + this.textDuration, this.isPlaying, this.subtitleAttributes, this.adInfo, @@ -583,6 +584,11 @@ class VideoEvent { /// Only used if [eventType] is [VideoEventType.subtitleUpdate]. final String? text; + /// The duration of text + /// + /// Only used if [eventType] is [VideoEventType.subtitleUpdate]. + final int? textDuration; + /// Whether the video is currently playing. /// /// Only used if [eventType] is [VideoEventType.isPlayingStateUpdate]. @@ -606,6 +612,7 @@ class VideoEvent { size == other.size && buffered == other.buffered && text == other.text && + textDuration == other.textDuration && isPlaying == other.isPlaying && subtitleAttributes == other.subtitleAttributes && adInfo == other.adInfo; @@ -618,6 +625,7 @@ class VideoEvent { size.hashCode ^ buffered.hashCode ^ text.hashCode ^ + textDuration.hashCode ^ isPlaying.hashCode ^ subtitleAttributes.hashCode ^ adInfo.hashCode; From 09134ef9b999dd007a105988d94e77cb1eaf657d Mon Sep 17 00:00:00 2001 From: "yying.jin" Date: Wed, 12 Nov 2025 19:53:55 +0800 Subject: [PATCH 2/4] ignore print --- packages/video_player_avplay/lib/video_player.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/video_player_avplay/lib/video_player.dart b/packages/video_player_avplay/lib/video_player.dart index 10c1e3b37..caa1d7a49 100644 --- a/packages/video_player_avplay/lib/video_player.dart +++ b/packages/video_player_avplay/lib/video_player.dart @@ -620,6 +620,7 @@ class VideoPlayerController extends ValueNotifier { final Duration textDuration = event.textDuration == 0 ? Duration.zero : Duration(milliseconds: event.textDuration!); + // ignore: avoid_print print('*****textDuration is $textDuration*******'); final Caption caption = Caption( number: 0, @@ -628,6 +629,7 @@ class VideoPlayerController extends ValueNotifier { text: event.text ?? '', subtitleAttributes: subtitleAttributes, ); + // ignore: avoid_print print( '*****Caption start is ${caption.start}, end is ${caption.end}*******'); value = value.copyWith(caption: caption); From aeec03c457e4f3a0611519f14b3d20dba4ef3cc4 Mon Sep 17 00:00:00 2001 From: "yying.jin" Date: Thu, 20 Nov 2025 09:45:58 +0800 Subject: [PATCH 3/4] Add periodic update checks to subtitle --- packages/video_player_avplay/lib/video_player.dart | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/packages/video_player_avplay/lib/video_player.dart b/packages/video_player_avplay/lib/video_player.dart index caa1d7a49..674e9cedd 100644 --- a/packages/video_player_avplay/lib/video_player.dart +++ b/packages/video_player_avplay/lib/video_player.dart @@ -186,10 +186,7 @@ class VideoPlayerValue { /// If the value of [caption.end] has greater than the current [position], this will be a [Caption.none] object. /// Only used for [copyWith]. Caption get _currentCaption { - if (position > caption.end) { - return Caption.none; - } - return caption; + return position > caption.end ? Caption.none : caption; } /// Returns a new instance that has the same values as this current instance, @@ -620,8 +617,6 @@ class VideoPlayerController extends ValueNotifier { final Duration textDuration = event.textDuration == 0 ? Duration.zero : Duration(milliseconds: event.textDuration!); - // ignore: avoid_print - print('*****textDuration is $textDuration*******'); final Caption caption = Caption( number: 0, start: value.position, @@ -629,9 +624,6 @@ class VideoPlayerController extends ValueNotifier { text: event.text ?? '', subtitleAttributes: subtitleAttributes, ); - // ignore: avoid_print - print( - '*****Caption start is ${caption.start}, end is ${caption.end}*******'); value = value.copyWith(caption: caption); case VideoEventType.isPlayingStateUpdate: if (event.isPlaying ?? false) { @@ -1143,7 +1135,7 @@ class VideoPlayerController extends ValueNotifier { /// [Caption]. Caption _getCaptionAt(Duration position) { if (_closedCaptionFile == null) { - return value.caption; + return position > value.caption.end ? Caption.none : value.caption; } final Duration delayedPosition = position + value.captionOffset; From 77a9e96627461623f06bb0feb7e4100296ed3ea4 Mon Sep 17 00:00:00 2001 From: "yying.jin" Date: Thu, 20 Nov 2025 09:53:25 +0800 Subject: [PATCH 4/4] update version --- packages/video_player_avplay/CHANGELOG.md | 3 +++ packages/video_player_avplay/README.md | 2 +- packages/video_player_avplay/pubspec.yaml | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/video_player_avplay/CHANGELOG.md b/packages/video_player_avplay/CHANGELOG.md index 416a2bd59..aefb02899 100644 --- a/packages/video_player_avplay/CHANGELOG.md +++ b/packages/video_player_avplay/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.7.5 +* Fix the issue of subtitles remaining longer than their end time. + ## 0.7.4 * Update plusplayer 1. [DASH] Fix this issue of audio switching not working in the dash video stream. diff --git a/packages/video_player_avplay/README.md b/packages/video_player_avplay/README.md index 97293ce3c..c80faba91 100644 --- a/packages/video_player_avplay/README.md +++ b/packages/video_player_avplay/README.md @@ -12,7 +12,7 @@ To use this package, add `video_player_avplay` as a dependency in your `pubspec. ```yaml dependencies: - video_player_avplay: ^0.7.4 + video_player_avplay: ^0.7.5 ``` Then you can import `video_player_avplay` in your Dart code: diff --git a/packages/video_player_avplay/pubspec.yaml b/packages/video_player_avplay/pubspec.yaml index c517b6013..8c5590e87 100644 --- a/packages/video_player_avplay/pubspec.yaml +++ b/packages/video_player_avplay/pubspec.yaml @@ -2,7 +2,7 @@ name: video_player_avplay description: Flutter plugin for displaying inline video on Tizen TV devices. homepage: https://github.com/flutter-tizen/plugins repository: https://github.com/flutter-tizen/plugins/tree/master/packages/video_player_avplay -version: 0.7.4 +version: 0.7.5 environment: sdk: ">=3.1.0 <4.0.0"