Skip to content

Commit 1f4312f

Browse files
committed
Merge commit 'da3e08270c8a8e2d0e4b8fadd65d805d52dd58dc' into custom-lg
* commit 'da3e08270c8a8e2d0e4b8fadd65d805d52dd58dc': chewie, version 1.11.2. Adds PR fluttercommunity#912. Updated comment Added information about getIsBuffering Fixed README links Removed usage of dart:io Added additional instructions for android buffering workaround Added workaround information for android to README Moved buffer detection logic for andorid into shared function Workaround loading spinner after video finished not disappearing on android Add workaround for invalid buffering info on android
2 parents 7dded2d + da3e082 commit 1f4312f

File tree

7 files changed

+93
-8
lines changed

7 files changed

+93
-8
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## [1.11.2]
2+
* 🛠️ [#912](https://github.com/fluttercommunity/chewie/pull/912): Add workaround for invalid buffering info on android. Thanks [timoxd7](https://github.com/timoxd7).
3+
14
## [1.11.1]
25
* ⬆️ [#875](https://github.com/fluttercommunity/chewie/pull/875): Add background tap to pause video feature. Thanks [Ortes](https://github.com/Ortes).
36
* 🛠️ [#896](https://github.com/fluttercommunity/chewie/pull/896): Fixed allowMute being ignored on Desktop. Thanks [mpoimer](https://github.com/mpoimer).

README.md

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ Chewie uses the `video_player` under the hood and wraps it in a friendly Materia
2424
8. 🧪 [Example](#-example)
2525
9.[Migrating from Chewie < 0.9.0](#-migrating-from-chewie--090)
2626
10. 🗺️ [Roadmap](#%EF%B8%8F-roadmap)
27-
11. 📱 [iOS warning](#-ios-warning-)
27+
11. ⚠️ [Android warning](#%EF%B8%8F-android-warning)
28+
12. 📱 [iOS warning](#-ios-warning)
2829

2930

3031
## 🚨 IMPORTANT!!! (READ THIS FIRST)
@@ -286,6 +287,42 @@ final playerWidget = Chewie(
286287
- [ ] Screen-Mirroring / Casting (Google Chromecast)
287288

288289

290+
## ⚠️ Android warning
291+
292+
There is an open [issue](https://github.com/flutter/flutter/issues/165149) that the buffering state of a video is not reported correctly. With this, the loading state is always triggered, hiding controls to play, pause or seek the video. A workaround was implemented until this is fixed, however it can't be perfect and still hides controls if seeking backwards while the video is paused, as a result of lack of correct buffering information (see #912).
293+
294+
Add the following to partly fix this behavior:
295+
296+
```dart
297+
// Your init code can be above
298+
videoController.addListener(yourListeningMethod);
299+
300+
// ...
301+
302+
bool wasPlayingBefore = false;
303+
void yourListeningMethod() {
304+
if (!videoController.value.isPlaying && !wasPlayingBefore) {
305+
// -> Workaround if seekTo another position while it was paused before.
306+
// On Android this might lead to infinite loading, so just play the
307+
// video again.
308+
videoController.play();
309+
}
310+
311+
wasPlayingBefore = videoController.value.isPlaying;
312+
313+
// ...
314+
}
315+
```
316+
317+
You can also disable the loading spinner entirely to fix this problem in a more _complete_ way, however will remove the loading indicator if a video is buffering.
318+
319+
```dart
320+
_chewieController = ChewieController(
321+
videoPlayerController: _videoPlayerController,
322+
progressIndicatorDelay: Platform.isAndroid ? const Duration(days: 1) : null,
323+
);
324+
```
325+
289326
## 📱 iOS warning
290327

291328
The video_player plugin used by chewie will only work in iOS simulators if you are on flutter 1.26.0 or above. You may need to switch to the beta channel `flutter channel beta`

lib/src/cupertino/cupertino_controls.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -810,9 +810,11 @@ class _CupertinoControlsState extends State<CupertinoControls>
810810
void _updateState() {
811811
if (!mounted) return;
812812

813+
final bool buffering = getIsBuffering(controller);
814+
813815
// display the progress bar indicator only after the buffering delay if it has been set
814816
if (chewieController.progressIndicatorDelay != null) {
815-
if (controller.value.isBuffering) {
817+
if (buffering) {
816818
_bufferingDisplayTimer ??= Timer(
817819
chewieController.progressIndicatorDelay!,
818820
_bufferingTimerTimeout,
@@ -823,7 +825,7 @@ class _CupertinoControlsState extends State<CupertinoControls>
823825
_displayBufferingIndicator = false;
824826
}
825827
} else {
826-
_displayBufferingIndicator = controller.value.isBuffering;
828+
_displayBufferingIndicator = buffering;
827829
}
828830

829831
setState(() {

lib/src/helpers/utils.dart

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import 'package:flutter/foundation.dart';
2+
import 'package:video_player/video_player.dart';
3+
14
String formatDuration(Duration position) {
25
final ms = position.inMilliseconds;
36

@@ -30,3 +33,39 @@ String formatDuration(Duration position) {
3033

3134
return formattedTime;
3235
}
36+
37+
/// Gets the current buffering state of the video player.
38+
///
39+
/// For Android, it will use a workaround due to a [bug](https://github.com/flutter/flutter/issues/165149)
40+
/// affecting the `video_player` plugin, preventing it from getting the
41+
/// actual buffering state. This currently results in the `VideoPlayerController` always buffering,
42+
/// thus breaking UI elements.
43+
///
44+
/// For this, the actual buffer position is used to determine if the video is
45+
/// buffering or not. See Issue [#912](https://github.com/fluttercommunity/chewie/pull/912) for more details.
46+
bool getIsBuffering(VideoPlayerController controller) {
47+
final VideoPlayerValue value = controller.value;
48+
49+
if (defaultTargetPlatform == TargetPlatform.android) {
50+
if (value.isBuffering) {
51+
// -> Check if we actually buffer, as android has a bug preventing to
52+
// get the correct buffering state from this single bool.
53+
final int position = value.position.inMilliseconds;
54+
55+
// Special case, if the video is finished, we don't want to show the
56+
// buffering indicator anymore
57+
if (position >= value.duration.inMilliseconds) {
58+
return false;
59+
} else {
60+
final int buffer = value.buffered.lastOrNull?.end.inMilliseconds ?? -1;
61+
62+
return position >= buffer;
63+
}
64+
} else {
65+
// -> No buffering
66+
return false;
67+
}
68+
}
69+
70+
return value.isBuffering;
71+
}

lib/src/material/material_controls.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -645,9 +645,11 @@ class _MaterialControlsState extends State<MaterialControls>
645645
void _updateState() {
646646
if (!mounted) return;
647647

648+
final bool buffering = getIsBuffering(controller);
649+
648650
// display the progress bar indicator only after the buffering delay if it has been set
649651
if (chewieController.progressIndicatorDelay != null) {
650-
if (controller.value.isBuffering) {
652+
if (buffering) {
651653
_bufferingDisplayTimer ??= Timer(
652654
chewieController.progressIndicatorDelay!,
653655
_bufferingTimerTimeout,
@@ -658,7 +660,7 @@ class _MaterialControlsState extends State<MaterialControls>
658660
_displayBufferingIndicator = false;
659661
}
660662
} else {
661-
_displayBufferingIndicator = controller.value.isBuffering;
663+
_displayBufferingIndicator = buffering;
662664
}
663665

664666
setState(() {

lib/src/material/material_desktop_controls.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -581,9 +581,11 @@ class _MaterialDesktopControlsState extends State<MaterialDesktopControls>
581581
void _updateState() {
582582
if (!mounted) return;
583583

584+
final bool buffering = getIsBuffering(controller);
585+
584586
// display the progress bar indicator only after the buffering delay if it has been set
585587
if (chewieController.progressIndicatorDelay != null) {
586-
if (controller.value.isBuffering) {
588+
if (buffering) {
587589
_bufferingDisplayTimer ??= Timer(
588590
chewieController.progressIndicatorDelay!,
589591
_bufferingTimerTimeout,
@@ -594,7 +596,7 @@ class _MaterialDesktopControlsState extends State<MaterialDesktopControls>
594596
_displayBufferingIndicator = false;
595597
}
596598
} else {
597-
_displayBufferingIndicator = controller.value.isBuffering;
599+
_displayBufferingIndicator = buffering;
598600
}
599601

600602
setState(() {

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: chewie
22
description: A video player for Flutter with Cupertino and Material play controls
3-
version: 1.11.1
3+
version: 1.11.2
44
homepage: https://github.com/fluttercommunity/chewie
55

66
environment:

0 commit comments

Comments
 (0)