ChewiePlayer in flutter disposes the controller after going to full screen mode

1,042

Finally after about a week struggling found the issue, the issue was because in the parent widget's AppBar I was using PreferedSize and giving some padding to the element inside of it, since the player was being rendered on top of it and because of the appBar it was not able to go fullScreen it would have disposed the controller. The fix was to check if the child widget has a VideoPlayer inside ignore the padding and it works great.

Share:
1,042
Javad Moradi
Author by

Javad Moradi

A passionate and creative web and mobile developer with a thirst to learn.

Updated on December 30, 2022

Comments

  • Javad Moradi
    Javad Moradi over 1 year

    I have a ChewiePlayer inside a statefull widget which is being used inside another statefull widget. when I go to full screen mode the dispose function gets called which basically deletes the listeners and I can't get out of full screen mode. I also get this error:

    NoSuchMethodError: The method 'dispose' was called on null. Receiver: null Tried calling: dispose()

    as well as

    A ChewiePlayerController was used after being disposed. Once you have called dispose() on a ChewiePlayerController...

    seems like a common issue, tried almost every solution out there but nothing seems to work.

    Here is my flutter doctor output:

    Doctor summary (to see all details, run flutter doctor -v):
    [✓] Flutter (Channel stable, 1.22.6, on Mac OS X 10.15.7 19H1217 darwin-x64,
        locale en-GB)
    [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
    [✓] Xcode - develop for iOS and macOS (Xcode 12.1)
    [✓] Android Studio (version 4.1)
    [✓] VS Code (version 1.57.0)
    [✓] Connected device (1 available)
    
    • No issues found!
    

    and this is the code inside my statefull widget:

    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    import 'package:flutter_html/flutter_html.dart';
    import 'package:flutter_html/style.dart' as HtmlStyle;
    import 'package:flutter_linkify/flutter_linkify.dart';
    import 'package:flutter_spinkit/flutter_spinkit.dart';
    import 'package:ria/src/models/game_pebble.dart';
    import 'package:ria/src/models/trail.dart';
    import 'package:url_launcher/url_launcher.dart';
    import 'package:video_player/video_player.dart';
    import 'package:chewie/chewie.dart';
    
    class VideoOutputMineral extends StatefulWidget {
      @override
      VideoOutputMineralState createState() => VideoOutputMineralState();
      final Mineral mineral;
      final List<GameStyle> styles;
      final Function onChangeAnswer;
    
      VideoOutputMineral(this.mineral, this.styles, this.onChangeAnswer, {Key key})
          : super(key: key);
    }
    
    class VideoOutputMineralState extends State<VideoOutputMineral>
        with TickerProviderStateMixin {
      VideoPlayerController videoPlayerController;
      ChewieController chewieController;
    
      Color hexToColor(String code) {
        return new Color(int.parse(code.substring(1, 7), radix: 16) + 0xFF000000);
      }
    
      Color getFontColor() {
        if (widget.styles != null &&
            widget.styles.first != null &&
            widget.styles.first.attributes.fontColor != null) {
          return hexToColor(widget.styles.first.attributes.fontColor);
        } else {
          return Colors.black;
        }
      }
    
      Future<void> initializeVideoPlayer() async {
        // the async function which is responsible to get the trail detail, then initialize the video player controller, once done rebuild the widget with new data.
        if (widget.mineral.properties.first.media.url != null &&
            widget.mineral.properties.first.media.url != "") {
          videoPlayerController = VideoPlayerController.network(
              widget.mineral.properties.first.media.url);
          await videoPlayerController.initialize();
          chewieController = ChewieController(
            videoPlayerController: videoPlayerController,
            looping: true,
            aspectRatio: 16 / 9,
            deviceOrientationsAfterFullScreen: [
              DeviceOrientation.portraitUp,
              DeviceOrientation.portraitDown
            ],
            allowFullScreen: true,
            fullScreenByDefault: false,
            autoInitialize: true,
            errorBuilder: (context, errorMessage) {
              return Center(
                child: Text(
                  errorMessage,
                  style: TextStyle(color: Colors.white),
                ),
              );
            },
          );
        }
        setState(() {});
      }
    
      @override
      void initState() {
        this.initializeVideoPlayer();
        super.initState();
      }
    
      @override
      void dispose() {
        super.dispose();
        if (chewieController != null && chewieController.isFullScreen) {
          chewieController?.dispose();
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return Padding(
          padding: const EdgeInsets.only(top: 8, bottom: 8, left: 30, right: 30),
          child: Column(
            children: [
              widget.mineral.properties.first.title != null &&
                      widget.mineral.properties.first.title != ""
                  ? Column(
                      children: [
                        Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            Expanded(
                              child: Linkify(
                                options: LinkifyOptions(
                                    defaultToHttps: true, looseUrl: true),
                                onOpen: (link) async {
                                  if (await canLaunch(link.url)) {
                                    await launch(link.url);
                                  } else {
                                    throw 'Could not launch $link';
                                  }
                                },
                                text:
                                    "${widget.mineral.properties.first.title}${widget.mineral.properties?.first?.rulesInput?.rulesInputRequired == 'required' ? ' *' : ''}",
                                style: TextStyle(
                                  fontSize: 20,
                                  fontWeight: FontWeight.w500,
                                  color: hexToColor(
                                      widget.styles.first.attributes.fontColor),
                                ),
                                linkStyle: TextStyle(
                                  fontSize: 20,
                                  fontWeight: FontWeight.w500,
                                  color: hexToColor(
                                      widget.styles.first.attributes.fontColor),
                                ),
                                textAlign: TextAlign.center,
                              ),
                            ),
                          ],
                        ),
                        SizedBox(
                          height: 12,
                        ),
                      ],
                    )
                  : Container(),
              widget.mineral.properties.first.description != null &&
                      widget.mineral.properties.first.description != ""
                  ? Column(
                      children: [
                        Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            Expanded(
                              child: Linkify(
                                options: LinkifyOptions(
                                    defaultToHttps: true, looseUrl: true),
                                onOpen: (link) async {
                                  if (await canLaunch(link.url)) {
                                    await launch(link.url);
                                  } else {
                                    throw 'Could not launch $link';
                                  }
                                },
                                text:
                                    "${widget.mineral.properties.first.description}",
                                style: TextStyle(
                                  fontSize: 17,
                                  fontWeight: FontWeight.w500,
                                  color: hexToColor(
                                      widget.styles.first.attributes.fontColor),
                                ),
                                linkStyle: TextStyle(
                                  fontSize: 17,
                                  fontWeight: FontWeight.w500,
                                  color: hexToColor(
                                      widget.styles.first.attributes.fontColor),
                                ),
                                textAlign: TextAlign.center,
                              ),
                            ),
                          ],
                        ),
                        SizedBox(
                          height: 12,
                        ),
                      ],
                    )
                  : Container(),
              ClipRRect(
                borderRadius: BorderRadius.circular(16.0),
                child: RotatedBox(
                  quarterTurns: 0,
                  child: Container(
                    height: 200,
                    child: chewieController != null &&
                            chewieController.videoPlayerController.value.initialized
                        ? Chewie(
                            controller: chewieController,
                          )
                        : Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            crossAxisAlignment: CrossAxisAlignment.center,
                            children: [
                              SpinKitFadingCircle(
                                color: Colors.black,
                              ),
                            ],
                          ),
                  ),
                ),
              ),
              widget.mineral.properties.first.caption != null &&
                      widget.mineral.properties.first.caption != ""
                  ? Column(
                      children: [
                        SizedBox(
                          height: 12,
                        ),
                        Text(
                          widget.mineral.properties.first.caption,
                          style: TextStyle(
                            fontSize: 17,
                            fontWeight: FontWeight.w500,
                            color: getFontColor(),
                          ),
                          overflow: TextOverflow.ellipsis,
                          textAlign: TextAlign.center,
                          maxLines: 2,
                        ),
                      ],
                    )
                  : Container(),
              Padding(
                padding: const EdgeInsets.only(top: 10.0),
                child: widget.mineral.properties.first.content != null
                    ? Column(
                        children: [
                          Html(
                              data: widget.mineral.properties.first.content,
                              style: {
                                "html": HtmlStyle.Style(
                                    fontSize: HtmlStyle.FontSize.large,
                                    color: getFontColor()),
                                "p": HtmlStyle.Style(
                                  lineHeight: 1,
                                  display: HtmlStyle.Display.BLOCK,
                                  margin: EdgeInsets.fromLTRB(0, 0, 0, 0),
                                ),
                              }),
                        ],
                      )
                    : Container(),
              )
            ],
          ),
        );
      }
    }
    

    thanks in advance!