fluttercommunity / chewie

The video player for Flutter with a heart of gold
MIT License
1.9k stars 983 forks source link

Changing video source in fullscreen mode not working? #742

Open JibuVarghese opened 1 year ago

JibuVarghese commented 1 year ago

Issue description:

Using a list of network mp4 videos. In player portrait mode toggle next video src working fine. In fullscreen mode the toggle next video src not working instead throwing error

The following assertion was thrown building PlayerWithControls(dependencies: [ChewieControllerProvider, MediaQuery, _InheritedTheme, _LocalizationsScope-[GlobalKey#537f6]]): setState() or markNeedsBuild() called during build.

Using customControls with ChewieController

ToggleVideo

Future<void> toggleVideo() async { await _videoPlayerController.pause(); currPlayIndex.value += 1; if (currPlayIndex >= playList.length) { currPlayIndex.value = 0; } await _initializePlayer(); }

initializePlayer

Future<void> _initializePlayer() async { _isPlayerInitialized.value = false; _videoPlayerController = VideoPlayerController.network(playList[currPlayIndex.value]); await _videoPlayerController .initialize() .then((value) => {_isPlayerInitialized.value = true}); _createChewieController(); _videoPlayerController.addListener(_videoPlayerListener); }

createChewieController

void _createChewieController() { _chewieController = ChewieController( customControls: CustomVideoPlayerControls( controller: _videoPlayerController, onFullScreenBtnClick: () { _chewieController?.enterFullScreen(); }, onBackPressed: () { Get.back(closeOverlays: false); }, onNextButtonPressed: () { toggleVideo(); }, ), aspectRatio: 16 / 9, videoPlayerController: _videoPlayerController, showControlsOnInitialize: true, autoPlay: true, looping: false, deviceOrientationsOnEnterFullScreen: [ DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight ], deviceOrientationsAfterFullScreen: [ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown ], ); }

VideoDetailsPage

Scaffold( body: SafeArea( child: Stack( children: [ Positioned( top: 0, left: 0, right: 0, child: Container( color: Colors.black, height: MediaQuery.of(context).size.width * 9 / 16, child: Obx(() { return controller.isPlayerInitialized == true ? Chewie( controller: controller.chewieController!, ) : const Column( mainAxisAlignment: MainAxisAlignment.center, children: [ CircularProgressIndicator(), ], ); })), ),])))

Am I missing any configuration?

Stacktrace ======== Exception caught by widgets library ======================================================= The following assertion was thrown building PlayerWithControls(dependencies: [ChewieControllerProvider, MediaQuery, _InheritedTheme, _LocalizationsScope-[GlobalKey#537f6]]): setState() or markNeedsBuild() called during build.

This Obx widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase. The widget on which setState() or markNeedsBuild() was called was: Obx has builder state: _ObxState#d27ff The widget which was currently being built when the offending call was made was: PlayerWithControls dependencies: [ChewieControllerProvider, MediaQuery, _InheritedTheme, _LocalizationsScope-[GlobalKey#537f6]] The relevant error-causing widget was: Chewie Chewie:file:///Users/user/app/lib/app/src/video_details/video_details_page.dart:54:27 When the exception was thrown, this was the stack: 0 Element.markNeedsBuild. (package:flutter/src/widgets/framework.dart:4651:9) 1 Element.markNeedsBuild (package:flutter/src/widgets/framework.dart:4663:6) 2 State.setState (package:flutter/src/widgets/framework.dart:1159:15) 3 _ObxState._updateTree (package:get/get_state_manager/src/rx_flutter/rx_obx_widget.dart:41:7) 4 GetStream._notifyData (package:get/get_rx/src/rx_stream/get_stream.dart:47:21) 5 GetStream.add (package:get/get_rx/src/rx_stream/get_stream.dart:97:5) 6 NotifyManager.addListener. (package:get/get_rx/src/rx_types/rx_core/rx_impl.dart:158:40) 7 GetStream._notifyData (package:get/get_rx/src/rx_stream/get_stream.dart:47:21) 8 GetStream.add (package:get/get_rx/src/rx_stream/get_stream.dart:97:5) 9 RxObjectMixin.value= (package:get/get_rx/src/rx_types/rx_core/rx_impl.dart:105:13) 10 MyVideoController.isPlaying= (package:app/src/video_details/contollers/video_controller.dart:55:16) 11 _CustomVideoPlayerControlsState._updateVideoState (package:app/src/video_details/widgets/custom_video_controls.dart:61:12) 12 _CustomVideoPlayerControlsState.initState (package:app/src/video_details/widgets/custom_video_controls.dart:45:5) 13 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:5219:55) 14 ComponentElement.mount (package:flutter/src/widgets/framework.dart:5062:5) 15 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3971:16) 16 MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6570:36) 17 MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6582:32) ... Normal element mounting (28 frames) 45 _InheritedProviderScopeElement.mount (package:provider/src/inherited_provider.dart:411:11) ... Normal element mounting (7 frames) 52 SingleChildWidgetElementMixin.mount (package:nested/nested.dart:222:11) ... Normal element mounting (15 frames) 67 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3971:16) 68 Element.updateChild (package:flutter/src/widgets/framework.dart:3702:20) 69 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5111:16) 70 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5251:11) 71 Element.rebuild (package:flutter/src/widgets/framework.dart:4805:7) 72 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2780:19) 73 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:903:21) 74 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:358:5) 75 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1284:15) 76 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1214:9) 77 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1072:5) 78 _invoke (dart:ui/hooks.dart:142:13) 79 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:359:5) 80 _drawFrame (dart:ui/hooks.dart:112:31)

flutter doctor -v

[✓] Flutter (Channel stable, 3.10.5, on macOS 13.4 22F66 darwin-arm64, locale en-IN) • Flutter version 3.10.5 on channel stable at /Users/user/Tools/flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision 796c8ef792 (6 days ago), 2023-06-13 15:51:02 -0700 • Engine revision 45f6e00911 • Dart version 3.0.5 • DevTools version 2.23.1

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.1) • Android SDK at /Users/user/Library/Android/sdk • Platform android-33, build-tools 33.0.1 • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694) • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.3) • Xcode at /Applications/Xcode.app/Contents/Developer • Build 14E222b • CocoaPods version 1.11.3

[✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2022.2) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)

[✓] IntelliJ IDEA Community Edition (version 2022.2.4) • IntelliJ at /Applications/IntelliJ IDEA CE.app • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart

[✓] Connected device (4 available) • SM M307F (mobile) • RZ8M83MNRZB • android-arm64 • Android 11 (API 30) • iPhone 14 Pro Max (mobile) • F47FD4F7-E2E7-426F-A1C4-D4A730A3CE58 • ios • com.apple.CoreSimulator.SimRuntime.iOS-16-4 (simulator) • macOS (desktop) • macos • darwin-arm64 • macOS 13.4 22F66 darwin-arm64 • Chrome (web) • chrome • web-javascript • Google Chrome 114.0.5735.133

[✓] Network resources • All expected network resources are available.

• No issues found!

z1047549075 commented 1 year ago

the same ploblem,how to you fix it,thx~

George-Abdelmessh commented 12 months ago

Don't use the Package fullscreen feature create it like this: 1- new screen with scaffold 2- SafeArea, AspectRatio, Chewie 3- pass the controller to the constructor 4- use state management to handle change video

JibuVarghese commented 12 months ago

@George-Abdelmessh Can you please help me with a sample app?

diegotori commented 10 months ago

@JibuVarghese please provide an example app that reproduces this issue. Thanks.

gmstyle commented 8 months ago

@JibuVarghese @diegotori I solved creating a StreamController for skip functions into the PlayerHandler class and , into the full screen widget, listening the onSkip stream to call the setState and works fine.

MyPlayerHandler

class MtPlayerHandler extends BaseAudioHandler with QueueHandler, SeekHandler {
//...
  // Stream to notify skip functions are colled
  final StreamController<void> _skipController =
      StreamController<void>.broadcast();
  Stream<void> get onSkip => _skipController.stream;

 @override
  Future<void> skipToNext() async {
  //...
      _skipController.add(null);
    }
  }

  @override
  Future<void> skipToPrevious() async {
    //...
      _skipController.add(null);
    }
  //...
  }

Into the FullScreenWidget , into initState function:

@override
  void initState() {
    super.initState();
    widget.mtPlayerHandler.onSkip.listen((_) {
      // update the ui in fullscreen mode
      setState(() {});
    });
}