From f2aaaeea52bd110ca18680f72209426e2b8719fb Mon Sep 17 00:00:00 2001 From: Sailendra Bathi Date: Wed, 27 May 2026 13:51:22 +0000 Subject: [PATCH 1/6] [video_player] Improve seek performance on Android Adds `backBufferDurationMs` to `VideoPlayerOptions` and configures ExoPlayer's `DefaultLoadControl` to retain the back buffer from keyframes. This significantly improves seek performance and responsiveness during video playback on Android. --- .../video_player/video_player/CHANGELOG.md | 4 ++++ .../video_player/example/lib/main.dart | 2 +- .../video_player/lib/video_player.dart | 1 + .../video_player/video_player/pubspec.yaml | 6 ++--- .../video_player_initialization_test.dart | 22 ++++++++++++++++++- .../video_player/test/video_player_test.dart | 14 ++++++------ .../video_player_android/CHANGELOG.md | 4 ++++ .../CHANGELOG.md | 4 ++++ .../lib/video_player_platform_interface.dart | 2 +- .../test/video_player_options_test.dart | 4 ++-- 10 files changed, 48 insertions(+), 15 deletions(-) diff --git a/packages/video_player/video_player/CHANGELOG.md b/packages/video_player/video_player/CHANGELOG.md index 4e4c13b0a0f2..eb02504e15ad 100644 --- a/packages/video_player/video_player/CHANGELOG.md +++ b/packages/video_player/video_player/CHANGELOG.md @@ -2,6 +2,10 @@ * Updates minimum supported SDK version to Flutter 3.38/Dart 3.10. +## 2.12.0 + +* Passes `backBufferDurationMs` from `VideoPlayerOptions` to the underlying platform interface. + ## 2.11.1 * Optimizes caption retrieval with binary search. diff --git a/packages/video_player/video_player/example/lib/main.dart b/packages/video_player/video_player/example/lib/main.dart index 61e24a891079..b018e92e5cf2 100644 --- a/packages/video_player/video_player/example/lib/main.dart +++ b/packages/video_player/video_player/example/lib/main.dart @@ -296,7 +296,7 @@ class _BumbleBeeRemoteVideoState extends State<_BumbleBeeRemoteVideo> { _controller = VideoPlayerController.networkUrl( Uri.parse('https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4'), closedCaptionFile: _loadCaptions(), - videoPlayerOptions: VideoPlayerOptions(mixWithOthers: true), + videoPlayerOptions: const VideoPlayerOptions(mixWithOthers: true), viewType: widget.viewType, ); diff --git a/packages/video_player/video_player/lib/video_player.dart b/packages/video_player/video_player/lib/video_player.dart index b287a39fed24..cd5a110ec28d 100644 --- a/packages/video_player/video_player/lib/video_player.dart +++ b/packages/video_player/video_player/lib/video_player.dart @@ -560,6 +560,7 @@ class VideoPlayerController extends ValueNotifier { final creationOptions = platform_interface.VideoCreationOptions( dataSource: dataSourceDescription, viewType: viewType, + videoPlayerOptions: videoPlayerOptions, ); if (videoPlayerOptions?.mixWithOthers != null) { diff --git a/packages/video_player/video_player/pubspec.yaml b/packages/video_player/video_player/pubspec.yaml index c55f4e823c4e..f4ea96251aa7 100644 --- a/packages/video_player/video_player/pubspec.yaml +++ b/packages/video_player/video_player/pubspec.yaml @@ -3,7 +3,7 @@ description: Flutter plugin for displaying inline video with other Flutter widgets on Android, iOS, macOS and web. repository: https://github.com/flutter/packages/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.11.1 +version: 2.12.0 environment: sdk: ^3.10.0 @@ -26,9 +26,9 @@ dependencies: flutter: sdk: flutter html: ^0.15.0 - video_player_android: ^2.9.1 + video_player_android: ^2.10.0 video_player_avfoundation: ^2.9.0 - video_player_platform_interface: ^6.6.0 + video_player_platform_interface: ^6.8.0 video_player_web: ^2.1.0 dev_dependencies: diff --git a/packages/video_player/video_player/test/video_player_initialization_test.dart b/packages/video_player/video_player/test/video_player_initialization_test.dart index 4524e8aca167..40a1e748fb8b 100644 --- a/packages/video_player/video_player/test/video_player_initialization_test.dart +++ b/packages/video_player/video_player/test/video_player_initialization_test.dart @@ -33,7 +33,7 @@ void main() { final controller = VideoPlayerController.networkUrl( Uri.parse('https://127.0.0.1'), - videoPlayerOptions: VideoPlayerOptions(webOptions: expected), + videoPlayerOptions: const VideoPlayerOptions(webOptions: expected), ); await controller.initialize(); @@ -73,4 +73,24 @@ void main() { reason: 'view type must be passed to the platform', ); }); + + test('back buffer duration is forwarded to platform', () async { + const expectedBackBufferDurationMs = 20000; + + final controller = VideoPlayerController.networkUrl( + Uri.parse('https://127.0.0.1'), + videoPlayerOptions: const VideoPlayerOptions( + backBufferDurationMs: expectedBackBufferDurationMs, + ), + ); + + await controller.initialize(); + + expect( + fakeVideoPlayerPlatform.videoPlayerOptions.last?.backBufferDurationMs, + expectedBackBufferDurationMs, + reason: + 'backBufferDurationMs must be forwarded to the platform via VideoCreationOptions.videoPlayerOptions', + ); + }); } diff --git a/packages/video_player/video_player/test/video_player_test.dart b/packages/video_player/video_player/test/video_player_test.dart index 56cd402f1228..11cb340068b3 100644 --- a/packages/video_player/video_player/test/video_player_test.dart +++ b/packages/video_player/video_player/test/video_player_test.dart @@ -1027,13 +1027,11 @@ void main() { } expect(isSorted, false, reason: 'Expected captions to be unsorted'); - expect(captions.map((Caption c) => c.text).toList(), [ - 'one', - 'two', - 'three', - 'five', - 'four', - ], reason: 'Captions should be in original unsorted order'); + expect( + captions.map((Caption c) => c.text).toList(), + ['one', 'two', 'three', 'five', 'four'], + reason: 'Captions should be in original unsorted order', + ); }); test('works when seeking, includes all captions', () async { @@ -1900,6 +1898,7 @@ class FakeVideoPlayerPlatform extends VideoPlayerPlatform { List dataSources = []; List viewTypes = []; final Map> streams = >{}; + List videoPlayerOptions = []; bool forceInitError = false; int nextPlayerId = 0; final Map _positions = {}; @@ -1943,6 +1942,7 @@ class FakeVideoPlayerPlatform extends VideoPlayerPlatform { } dataSources.add(options.dataSource); viewTypes.add(options.viewType); + videoPlayerOptions.add(options.videoPlayerOptions); return nextPlayerId++; } diff --git a/packages/video_player/video_player_android/CHANGELOG.md b/packages/video_player/video_player_android/CHANGELOG.md index 467d0b1dce3b..1a546bd21cd6 100644 --- a/packages/video_player/video_player_android/CHANGELOG.md +++ b/packages/video_player/video_player_android/CHANGELOG.md @@ -15,6 +15,10 @@ * Migrates to Built-in Kotlin to support AGP 9. * Updates minimum supported SDK version to Flutter 3.44/Dart 3.12. +## 2.10.0 + +* Adds `backBufferDurationMs` to `CreationOptions` to configure ExoPlayer `DefaultLoadControl` back buffer duration. + ## 2.9.5 * Updates build files from Groovy to Kotlin. diff --git a/packages/video_player/video_player_platform_interface/CHANGELOG.md b/packages/video_player/video_player_platform_interface/CHANGELOG.md index 617d0983b225..bef152914e89 100644 --- a/packages/video_player/video_player_platform_interface/CHANGELOG.md +++ b/packages/video_player/video_player_platform_interface/CHANGELOG.md @@ -10,6 +10,10 @@ controlling display sleep silently fall back to their default behavior. * Updates minimum supported SDK version to Flutter 3.38/Dart 3.10. +## 6.8.0 + +* Adds `backBufferDurationMs` to `VideoPlayerOptions` to support configuring ExoPlayer back buffer duration on Android. + ## 6.7.0 * Adds `VideoTrack` class and `getVideoTracks()`, `selectVideoTrack()`, `isVideoTrackSupportAvailable()` methods for video track (quality) selection. diff --git a/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart b/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart index ca5edf84739b..25cac0ff335e 100644 --- a/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart +++ b/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart @@ -467,7 +467,7 @@ class VideoPlayerOptions { // in all of the other video player packages, fix this, and then update // the other packages to use const. // ignore: prefer_const_constructors_in_immutables - VideoPlayerOptions({ + const VideoPlayerOptions({ this.mixWithOthers = false, this.allowBackgroundPlayback = false, this.preventsDisplaySleepDuringVideoPlayback = true, diff --git a/packages/video_player/video_player_platform_interface/test/video_player_options_test.dart b/packages/video_player/video_player_platform_interface/test/video_player_options_test.dart index 91e4d8fdb062..758f9e974137 100644 --- a/packages/video_player/video_player_platform_interface/test/video_player_options_test.dart +++ b/packages/video_player/video_player_platform_interface/test/video_player_options_test.dart @@ -7,11 +7,11 @@ import 'package:video_player_platform_interface/video_player_platform_interface. void main() { test('VideoPlayerOptions allowBackgroundPlayback defaults to false', () { - final options = VideoPlayerOptions(); + const options = VideoPlayerOptions(); expect(options.allowBackgroundPlayback, false); }); test('VideoPlayerOptions mixWithOthers defaults to false', () { - final options = VideoPlayerOptions(); + const options = VideoPlayerOptions(); expect(options.mixWithOthers, false); }); test('VideoPlayerOptions preventsDisplaySleepDuringVideoPlayback defaults to true', () { From b4385aee43b81c97ff09f0da847d1a3f6ee9e4a5 Mon Sep 17 00:00:00 2001 From: Sailendra Bathi Date: Wed, 10 Jun 2026 17:07:50 +0000 Subject: [PATCH 2/6] Address PR review comments and format files --- packages/video_player/video_player/CHANGELOG.md | 5 +---- packages/video_player/video_player_android/CHANGELOG.md | 4 ---- .../video_player_platform_interface/CHANGELOG.md | 4 ---- 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/packages/video_player/video_player/CHANGELOG.md b/packages/video_player/video_player/CHANGELOG.md index eb02504e15ad..20671d46a4cd 100644 --- a/packages/video_player/video_player/CHANGELOG.md +++ b/packages/video_player/video_player/CHANGELOG.md @@ -1,10 +1,7 @@ -## NEXT - -* Updates minimum supported SDK version to Flutter 3.38/Dart 3.10. - ## 2.12.0 * Passes `backBufferDurationMs` from `VideoPlayerOptions` to the underlying platform interface. +* Updates minimum supported SDK version to Flutter 3.38/Dart 3.10. ## 2.11.1 diff --git a/packages/video_player/video_player_android/CHANGELOG.md b/packages/video_player/video_player_android/CHANGELOG.md index 1a546bd21cd6..467d0b1dce3b 100644 --- a/packages/video_player/video_player_android/CHANGELOG.md +++ b/packages/video_player/video_player_android/CHANGELOG.md @@ -15,10 +15,6 @@ * Migrates to Built-in Kotlin to support AGP 9. * Updates minimum supported SDK version to Flutter 3.44/Dart 3.12. -## 2.10.0 - -* Adds `backBufferDurationMs` to `CreationOptions` to configure ExoPlayer `DefaultLoadControl` back buffer duration. - ## 2.9.5 * Updates build files from Groovy to Kotlin. diff --git a/packages/video_player/video_player_platform_interface/CHANGELOG.md b/packages/video_player/video_player_platform_interface/CHANGELOG.md index bef152914e89..617d0983b225 100644 --- a/packages/video_player/video_player_platform_interface/CHANGELOG.md +++ b/packages/video_player/video_player_platform_interface/CHANGELOG.md @@ -10,10 +10,6 @@ controlling display sleep silently fall back to their default behavior. * Updates minimum supported SDK version to Flutter 3.38/Dart 3.10. -## 6.8.0 - -* Adds `backBufferDurationMs` to `VideoPlayerOptions` to support configuring ExoPlayer back buffer duration on Android. - ## 6.7.0 * Adds `VideoTrack` class and `getVideoTracks()`, `selectVideoTrack()`, `isVideoTrackSupportAvailable()` methods for video track (quality) selection. From f56842addc9dc4bce7639ffabf38aa03fa6f6ee6 Mon Sep 17 00:00:00 2001 From: Sailendra Bathi Date: Wed, 10 Jun 2026 18:10:57 +0000 Subject: [PATCH 3/6] Revert VideoPlayerOptions const constructor to match main and satisfy linter --- packages/video_player/video_player/example/lib/main.dart | 2 +- .../video_player/test/video_player_initialization_test.dart | 6 ++---- .../lib/video_player_platform_interface.dart | 2 +- .../test/video_player_options_test.dart | 4 ++-- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/video_player/video_player/example/lib/main.dart b/packages/video_player/video_player/example/lib/main.dart index b018e92e5cf2..61e24a891079 100644 --- a/packages/video_player/video_player/example/lib/main.dart +++ b/packages/video_player/video_player/example/lib/main.dart @@ -296,7 +296,7 @@ class _BumbleBeeRemoteVideoState extends State<_BumbleBeeRemoteVideo> { _controller = VideoPlayerController.networkUrl( Uri.parse('https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4'), closedCaptionFile: _loadCaptions(), - videoPlayerOptions: const VideoPlayerOptions(mixWithOthers: true), + videoPlayerOptions: VideoPlayerOptions(mixWithOthers: true), viewType: widget.viewType, ); diff --git a/packages/video_player/video_player/test/video_player_initialization_test.dart b/packages/video_player/video_player/test/video_player_initialization_test.dart index 40a1e748fb8b..470eb1f98199 100644 --- a/packages/video_player/video_player/test/video_player_initialization_test.dart +++ b/packages/video_player/video_player/test/video_player_initialization_test.dart @@ -33,7 +33,7 @@ void main() { final controller = VideoPlayerController.networkUrl( Uri.parse('https://127.0.0.1'), - videoPlayerOptions: const VideoPlayerOptions(webOptions: expected), + videoPlayerOptions: VideoPlayerOptions(webOptions: expected), ); await controller.initialize(); @@ -79,9 +79,7 @@ void main() { final controller = VideoPlayerController.networkUrl( Uri.parse('https://127.0.0.1'), - videoPlayerOptions: const VideoPlayerOptions( - backBufferDurationMs: expectedBackBufferDurationMs, - ), + videoPlayerOptions: VideoPlayerOptions(backBufferDurationMs: expectedBackBufferDurationMs), ); await controller.initialize(); diff --git a/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart b/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart index 25cac0ff335e..ca5edf84739b 100644 --- a/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart +++ b/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart @@ -467,7 +467,7 @@ class VideoPlayerOptions { // in all of the other video player packages, fix this, and then update // the other packages to use const. // ignore: prefer_const_constructors_in_immutables - const VideoPlayerOptions({ + VideoPlayerOptions({ this.mixWithOthers = false, this.allowBackgroundPlayback = false, this.preventsDisplaySleepDuringVideoPlayback = true, diff --git a/packages/video_player/video_player_platform_interface/test/video_player_options_test.dart b/packages/video_player/video_player_platform_interface/test/video_player_options_test.dart index 758f9e974137..91e4d8fdb062 100644 --- a/packages/video_player/video_player_platform_interface/test/video_player_options_test.dart +++ b/packages/video_player/video_player_platform_interface/test/video_player_options_test.dart @@ -7,11 +7,11 @@ import 'package:video_player_platform_interface/video_player_platform_interface. void main() { test('VideoPlayerOptions allowBackgroundPlayback defaults to false', () { - const options = VideoPlayerOptions(); + final options = VideoPlayerOptions(); expect(options.allowBackgroundPlayback, false); }); test('VideoPlayerOptions mixWithOthers defaults to false', () { - const options = VideoPlayerOptions(); + final options = VideoPlayerOptions(); expect(options.mixWithOthers, false); }); test('VideoPlayerOptions preventsDisplaySleepDuringVideoPlayback defaults to true', () { From 98f54af4bfb5f22d3f03cceafc59cbf52de350f4 Mon Sep 17 00:00:00 2001 From: Sailendra Bathi Date: Wed, 17 Jun 2026 08:50:47 +0000 Subject: [PATCH 4/6] Fix dart format errors --- .../video_player/test/video_player_test.dart | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/video_player/video_player/test/video_player_test.dart b/packages/video_player/video_player/test/video_player_test.dart index 11cb340068b3..e662dd4f9b7c 100644 --- a/packages/video_player/video_player/test/video_player_test.dart +++ b/packages/video_player/video_player/test/video_player_test.dart @@ -1027,11 +1027,13 @@ void main() { } expect(isSorted, false, reason: 'Expected captions to be unsorted'); - expect( - captions.map((Caption c) => c.text).toList(), - ['one', 'two', 'three', 'five', 'four'], - reason: 'Captions should be in original unsorted order', - ); + expect(captions.map((Caption c) => c.text).toList(), [ + 'one', + 'two', + 'three', + 'five', + 'four', + ], reason: 'Captions should be in original unsorted order'); }); test('works when seeking, includes all captions', () async { From d89834a6e2b3b38f963090d3627d4527d49ae566 Mon Sep 17 00:00:00 2001 From: Sailendra Bathi Date: Fri, 26 Jun 2026 17:31:51 +0000 Subject: [PATCH 5/6] update video_player_platform_interface and video_player_android version in pubspec --- packages/video_player/video_player/pubspec.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/video_player/video_player/pubspec.yaml b/packages/video_player/video_player/pubspec.yaml index f4ea96251aa7..c01a93a54a22 100644 --- a/packages/video_player/video_player/pubspec.yaml +++ b/packages/video_player/video_player/pubspec.yaml @@ -26,9 +26,9 @@ dependencies: flutter: sdk: flutter html: ^0.15.0 - video_player_android: ^2.10.0 + video_player_android: ^2.11.0 video_player_avfoundation: ^2.9.0 - video_player_platform_interface: ^6.8.0 + video_player_platform_interface: ^6.9.0 video_player_web: ^2.1.0 dev_dependencies: From b8e5a67d99610db9dec7d6131d4c5770ad83f962 Mon Sep 17 00:00:00 2001 From: stuartmorgan-g Date: Fri, 10 Jul 2026 14:11:28 -0400 Subject: [PATCH 6/6] Bump min SDK versions --- packages/video_player/video_player/pubspec.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/video_player/video_player/pubspec.yaml b/packages/video_player/video_player/pubspec.yaml index c01a93a54a22..fcadff731d35 100644 --- a/packages/video_player/video_player/pubspec.yaml +++ b/packages/video_player/video_player/pubspec.yaml @@ -6,8 +6,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 2.12.0 environment: - sdk: ^3.10.0 - flutter: ">=3.38.0" + sdk: ^3.12.0 + flutter: ">=3.44.0" flutter: plugin: