9
votes

I'm playing video and there is no problem but when navigating to another page, console says this.
I tried everything that I came up with like check if mounted but none of them worked.
What am I missing? Does anyone know how to fix?

flutter: The following assertion was thrown while dispatching notifications for VideoPlayerController:
flutter: setState() or markNeedsBuild() called during build.
flutter: This VideoProgressIndicator widget cannot be marked as needing to build because the framework is
flutter: already in the process of building widgets. A widget can be marked as needing to be built during the
flutter: build phase only if one of its ancestors is currently building. This exception is allowed because
flutter: the framework builds parent widgets before children, which means a dirty descendant will always be
flutter: built. Otherwise, the framework might not visit this widget during this build phase.
flutter: The widget on which setState() or markNeedsBuild() was called was:
flutter: VideoProgressIndicator(state: _VideoProgressIndicatorState#09ac7)

Code:

class _VideoScreenState extends State<VideoScreen> {
      VideoPlayerController _controller;
      FadeAnimation imageFadeAnim =
          new FadeAnimation(child: const Icon(Icons.play_arrow, size: 100.0));
      VoidCallback listener;
      bool _isPlaying = false;
      List<String> videos = [
        'http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_20mb.mp4',
      ];

      _VideoScreenState() {
        listener = () {
          if (mounted) setState(() {});
        };
      }

      Future _videoOnTap() async {
        if (!_controller.value.initialized) {
          return;
        }
        if (_controller.value.isPlaying) {
          imageFadeAnim = new FadeAnimation(
              child: Icon(Icons.pause,
                  color: Colors.white.withOpacity(0.3), size: 75.0));
          await _controller.pause();
        } else {
          imageFadeAnim = new FadeAnimation(
              child: Icon(Icons.play_arrow,
                  color: Colors.white.withOpacity(0.3), size: 75.0));
          await _controller.play();
        }
      }

      Future _startVideoPlayer(int index) async {
        if (_controller != null) {
          await _controller.dispose();
        }
        _controller = VideoPlayerController.network(videos[index])
          ..addListener(() {
            final bool isPlaying = _controller.value.isPlaying;
            if (isPlaying != _isPlaying) {
              if (mounted)
                setState(() {
                  _isPlaying = isPlaying;
                });
            }
          })
          ..initialize().then((_) async {
            await _controller.play();
            if (mounted) setState(() {});
          });
      }

      @override
      void initState() {
        SystemChrome.setEnabledSystemUIOverlays([]);
        _startVideoPlayer(0);
        super.initState();
      }

      @override
      void deactivate() {
        _controller?.setVolume(0.0);
        _controller?.removeListener(listener);
        super.deactivate();
      }

      @override
      void dispose() {
        _controller?.dispose();
        super.dispose();
      }

      @override
      Widget build(BuildContext context) {
         final List<Widget> children = <Widget>[
      new GestureDetector(
        child: new Center(
          child: _controller.value.initialized
              ? new AspectRatio(
                  aspectRatio: _controller.value.aspectRatio,
                  child: new VideoPlayer(_controller))
              : new Container(),
        ),
        onTap: _videoOnTap,
      ),
      new Align(
        alignment: Alignment.topCenter,
        child: new VideoProgressIndicator(
          _controller,
          allowScrubbing: false,
          colors: VideoProgressColors(
              backgroundColor: Colors.black.withOpacity(0.5),
              playedColor: Colors.white),
        ),
      ),
      new Center(child: imageFadeAnim),
    ];

        return new Scaffold(
          backgroundColor: Colors.black,
          body: new SafeArea(
            top: true,
            left: false,
            right: false,
            bottom: false,
            child: new Stack(
              fit: StackFit.passthrough,
              children: children,
            ),
          ),
        );
      }
    }

    class FadeAnimation extends StatefulWidget {
      final Widget child;
      final Duration duration;

      FadeAnimation({this.child, this.duration: const Duration(milliseconds: 300)});

      @override
      _FadeAnimationState createState() => new _FadeAnimationState();
    }

    class _FadeAnimationState extends State<FadeAnimation>
        with SingleTickerProviderStateMixin {
      AnimationController animationController;

      @override
      void initState() {
        super.initState();
        animationController =
            new AnimationController(duration: widget.duration, vsync: this);
        animationController.addListener(() {
          if (mounted) {
            setState(() {});
          }
        });
        animationController.forward(from: 0.0);
      }

      @override
      void deactivate() {
        animationController.stop();
        super.deactivate();
      }

      @override
      void didUpdateWidget(FadeAnimation oldWidget) {
        super.didUpdateWidget(oldWidget);
        if (oldWidget.child != widget.child) {
          animationController.forward(from: 0.0);
        }
      }

      @override
      void dispose() {
        animationController.dispose();
        super.dispose();
      }

      @override
      Widget build(BuildContext context) {
        return animationController.isAnimating
            ? new Container(
                width: 75.0,
                height: 75.0,
                decoration: new BoxDecoration(
                  color: Colors.black.withOpacity(0.01),
                  shape: BoxShape.circle,
                ),
                child: widget.child,
              )
            : new Container();
      }
    }
1
I have same problem. Any soluiton?Esen Mehmet
What was the fix?dazza5000
same here, did anyone ever come up with a fix?user3249281
it definitely has to do with _controller?.setVolume(0.0) in deactivate(). haven't had a chance to look into it in more detail. but i'm guessing somewhere in that code it might call setState itself.user3249281

1 Answers

0
votes

Initialize your animationController in initState and add listener to didchangeDependencies

 @override
      void initState() {
        super.initState();
        animationController =
            new AnimationController(duration: widget.duration, vsync: this);
        
      }

@override
void didChangeDependencies(
{
super.didChangeDependencies();
animationController.addListener(() {
          if (mounted) {
            setState(() {});
          }
        });
        animationController.forward(from: 0.0);
})