jhomlala / betterplayer

Better video player for Flutter, with multiple configuration options. Solving typical use cases!
Apache License 2.0
931 stars 1.03k forks source link

[BUG] BetterPlayerPlayList gets disposed after playing 2 videos #389

Closed ronaldmaymone closed 3 years ago

ronaldmaymone commented 3 years ago

History check didn't found a solution for BetterPlayerPlayList.

Describe the bug BetterPlayerPlayList gets disposed after playing 2 videos. THE ERROR OUTPUT:

E/flutter (30918): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: setState() called after dispose(): _BetterPlayerVideoFitWidgetState#ac9b6(lifecycle state: defunct, not mounted) E/flutter (30918): This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree (e.g., whose parent widget no longer includes the widget in its build). This error can occur when code calls setState() from a timer or an animation callback. E/flutter (30918): The preferred solution is to cancel the timer or stop listening to the animation in the dispose() callback. Another solution is to check the "mounted" property of this object before calling setState() to ensure the object is still in the tree. E/flutter (30918): This error might indicate a memory leak if setState() is being called because another object is retaining a reference to this State object after it has been removed from the tree. To avoid memory leaks, consider breaking the reference to this object during dispose(). E/flutter (30918): #0 State.setState. (package:flutter/src/widgets/framework.dart:1208:9) E/flutter (30918): #1 State.setState (package:flutter/src/widgets/framework.dart:1243:6) E/flutter (30918): #2 _BetterPlayerVideoFitWidgetState._initialize. (package:better_player/src/core/better_player_with_controls.dart:290:9) E/flutter (30918): #3 BetterPlayerController._postEvent (package:better_player/src/core/better_player_controller.dart:599:22) E/flutter (30918): #4 BetterPlayerController.postEvent (package:better_player/src/core/better_player_controller.dart:592:5) E/flutter (30918): #5 BetterPlayerController.setupDataSource (package:better_player/src/core/better_player_controller.dart:222:5) E/flutter (30918): #6 BetterPlayerPlaylistController.setupDataSource (package:better_player/src/playlist/better_player_playlist_controller.dart:112:12) E/flutter (30918): #7 BetterPlayerPlaylistController._onVideoChange (package:better_player/src/playlist/better_player_playlist_controller.dart:84:5) E/flutter (30918): #8 BetterPlayerPlaylistController._setup. (package:better_player/src/playlist/better_player_playlist_controller.dart:65:9) E/flutter (30918): #9 _rootRunUnary (dart:async/zone.dart:1198:47) E/flutter (30918): #10 _CustomZone.runUnary (dart:async/zone.dart:1100:19) E/flutter (30918): #11 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1005:7) E/flutter (30918): #12 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:357:11) E/flutter (30918): #13 _DelayedData.perform (dart:async/stream_impl.dart:611:14) E/flutter (30918): #14 _StreamImplEvents.handleNext (dart:async/stream_impl.dart:730:11) E/flutter (30918): #15 _PendingEvents.schedule. (dart:async/stream_impl.dart:687:7) E/flutter (30918): #16 _rootRun (dart:async/zone.dart:1182:47) E/flutter (30918): #17 _CustomZone.run (dart:async/zone.dart:1093:19) E/flutter (30918): #18 _CustomZone.runGuarded (dart:async/zone.dart:997:7) E/flutter (30918): #19 _CustomZone.bindCallbackGuarded. (dart:async/zone.dart:1037:23) E/flutter (30918): #20 _rootRun (dart:async/zone.dart:1190:13) E/flutter (30918): #21 _CustomZone.run (dart:async/zone.dart:1093:19) E/flutter (30918): #22 _CustomZone.runGuarded (dart:async/zone.dart:997:7) E/flutter (30918): #23 _CustomZone.bindCallbackGuarded. (dart:async/zone.dart:1037:23) E/flutter (30918): #24 _microtaskLoop (dart:async/schedule_microtask.dart:41:21) E/flutter (30918): #25 _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5) E/flutter (30918):

To Reproduce Steps to reproduce the behavior:

  1. Create the PlayList with autoplay and fullscreenbydefault

*Example code The page creating the widget. This is a body of a scaffold on a StatelessWidget. body: Container( child: GetBuilder<HomeController>( builder: (_) { return _.dataSourceList != null ? AspectRatio( aspectRatio: 16 / 9, child: BetterPlayerPlaylist( betterPlayerConfiguration: BetterPlayerConfiguration(autoPlay: true, fullScreenByDefault: true,allowedScreenSleep: false,autoDispose: false,deviceOrientationsAfterFullScreen: [DeviceOrientation.landscapeLeft]), betterPlayerPlaylistConfiguration: BetterPlayerPlaylistConfiguration(initialStartIndex: 2,nextVideoDelay: Duration(milliseconds: 500)), betterPlayerDataSourceList: _.dataSourceList), ): Center(child: CircularProgressIndicator(),);

The creation of the dataSet that is called on the page initialization. void createDataSet() { print("ADDING to LIST"); dataSourceList = List<BetterPlayerDataSource>(); for (String videoName in fileNames){ dataSourceList.add( BetterPlayerDataSource( BetterPlayerDataSourceType.file, "$directory/$videoName", ), ); } update(); }

This update() is the same as setState() on statefullWidgets. I use the Get package. Expected behavior The videos play and loop.

Flutter doctor [✓] Flutter (Channel stable, 1.22.6, on Linux, locale en_US.UTF-8) • Flutter version 1.22.6 at /home/ronald/Documents/dev/flutter • Framework revision 9b2d32b605 (8 weeks ago), 2021-01-22 14:36:39 -0800 • Engine revision 2f0af37152 • Dart version 2.10.5

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3) • Android SDK at /home/ronald/Android/Sdk • Platform android-30, build-tools 30.0.3 • Java binary at: /usr/bin/java • Java version Java(TM) SE Runtime Environment (build 15.0.2+7-27) • All Android licenses accepted.

[!] Android Studio (not installed) • Android Studio not found; download from https://developer.android.com/studio/index.html (or visit https://flutter.dev/docs/get-started/install/linux#android-setup for detailed instructions).

[!] VS Code (version 1.54.3) • VS Code at /usr/share/code ✗ Flutter extension not installed; install from https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter

[✓] Connected device (1 available) • MX6 (mobile) • M95HACQ732LX8 • android-arm64 • Android 7.1.1 (API 25)

Better Player version

Smartphone (please complete the following information):

EDIT: don't know why the code is ugly like this. Here are they as print screens: https://imgur.com/a/cZ2CpW0

jhomlala commented 3 years ago

For future updates you need to upgrade to null safety. You can mix null safety and not null safety libs together. I've looked into your sample code and from my perspective your widget get updated somehow again after init. You should block widget updates where BetterPlayer is placed because it leads to dispose() on controller. Try to detect what causes refresh (rebuild) of your widget or use key to prevent rebuilds.

ronaldmaymone commented 3 years ago

So I tested here, putted a print right on the first line of GetBuilder and it gets rebuilt only once, after the list of videos was created. You think that on 0.0.62 this will be fixed? Thx for the reply.

jhomlala commented 3 years ago

Right now, latest version is 0.0.63, so you may try this version.

jhomlala commented 3 years ago

Closed due to no activity.