0

Here is the code of my flutter app, I am facing a major issue that even after closing the widget that contains video player, making sure that dispose is being called , the video still keeps playing in the background don't know this issue is related to chewie controller or video player.

Even tried pausing the video on dispose but did not work, and I don't even think pausing is the right option incase i am using this widget multiple times it will increase the load.

Can any one help me with this???

class VideoPlayerApp extends StatefulWidget {
  final String jsonLink;
  final String fileTitle;
  final String userId;
  final String creationTime;
  final bool showOnlyfile;

  const VideoPlayerApp(this.jsonLink, this.fileTitle, this.userId, this.creationTime, this.showOnlyfile, {super.key});
  @override
  State<VideoPlayerApp> createState() => _VideoPlayerAppState();
}

class _VideoPlayerAppState extends State<VideoPlayerApp>
    with AutomaticKeepAliveClientMixin {
  @override
  bool get wantKeepAlive => true;
  String videoRootUrl = "";
  late VideoPlayerController videoPlayerController;
  late  ChewieController chewieController;
  // late VideoPlayerController videoPlayerController;

  Future<String> fetchJsonContent() async {
    final jsonResponse = await http.get(Uri.parse(widget.jsonLink));
    if (jsonResponse.statusCode == 200) {
      var jsonContent = jsonDecode(jsonResponse.body);
      videoRootUrl = jsonContent["meta"]["rootUrl"];
      var files = jsonContent["files"];
      if (files.length > 0) {
        return videoRootUrl + files[0];
      }
      return "";
    } else {
      throw Exception('Failed to load json file of drive');
    }
  }

  @override
  void dispose() {
    print("|||||||||Video Dispose Called|||||||");
    videoPlayerController.dispose();
    chewieController.dispose();
    chewieController.videoPlayerController.pause();
    chewieController.pause();
    videoPlayerController.pause();
    super.dispose();
  }


  @override
  Widget build(BuildContext context) {
    super.build(context);
    return WillPopScope(
      onWillPop: ()async{
        switch(contentUiPreviousPath){
          case "contentList":
            Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context)=>courseContent(creatorName: currentCourseCreator, courseId: currentCourseId, batchId: currentBatchId, batchTitle: currentBatchTitle, discussionChannel: discussionChannel, announcementChannnel: announcementChannnel, tabBarIndex: 1)));
            break;
          default:
            Navigator.of(context).pop();
            break;
        }
        return false;
      },
      child: Scaffold(
          appBar: (widget.showOnlyfile)?null:const CustomAppBar(networkId: 'No-Network',tempNetworkImgUrl: ""),
          drawer: (widget.showOnlyfile)?null:const CustomDrawer(),
          body: bindVideoFiles()),
    );
  }

  bindVideoFiles() {
    return FutureBuilder(
      future: fetchJsonContent(),
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        if (snapshot.hasData) {
          videoPlayerController = VideoPlayerController.networkUrl(Uri.parse(snapshot.data));

          chewieController = ChewieController(
            videoPlayerController: videoPlayerController,
            autoPlay: false,
            autoInitialize: true,
            looping: false,
            showControls: true,
            aspectRatio: 16 / 9,
            materialProgressColors: ChewieProgressColors(
              backgroundColor: const Color.fromARGB(255, 4, 50, 90),
              bufferedColor: const Color.fromARGB(255, 4, 66, 116),
            ),
            errorBuilder: (context, errorMessage) {
              print("Video Player error --- $errorMessage");
              return const Center(
                child: Icon(Icons.error,color: Colors.white,),
              );
            },
          );

          return SingleChildScrollView(
            child: Column(
              children: [
                (widget.showOnlyfile)?const SizedBox():Container(
                        padding: const EdgeInsets.symmetric(
                          vertical: 13,
                        ),
                        width: MediaQuery.of(context).size.width * .9,
                        alignment: Alignment.centerLeft,
                        decoration: const BoxDecoration(
                            border: Border(
                                bottom: BorderSide(
                          width: 2,
                          color: Colors.black54,
                        ))),
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Text(
                              widget.fileTitle,
                              style: const TextStyle(
                                fontSize: 20,
                                fontWeight: FontWeight.bold,
                                color: Colors.black45,
                              ),
                              maxLines: 1,
                              overflow: TextOverflow.ellipsis,
                            ),
                            const SizedBox(
                              height: 3,
                            ),
                            Text(
                              widget.creationTime,
                              style: const TextStyle(
                                fontSize: 12,
                                color: Colors.black45,
                              ),
                              maxLines: 1,
                              textAlign: TextAlign.left,
                              overflow: TextOverflow.ellipsis,
                            ),
                            const SizedBox(
                              height: 3,
                            ),
                          ],
                        ),
                      ),
                Container(
                    height: (MediaQuery.of(context).size.width * 9) / 16,
                    margin: const EdgeInsets.symmetric(vertical: 20),
                    decoration: const BoxDecoration(color: Colors.black),
                    child: Chewie(
                      controller: chewieController,
                    )),
              ],
            ),
          );
        } else {
          return const Center(
            child: CircularProgressIndicator(),
          );
        }
      },
    );
  }
}

I tried disposing and pausing the video , but did not work.

1 Answers1

1

Well I changed some things and now i am able to pause the player and dispose it - following are the things i changed- removed wantkeepAlive, removed future builder, changed dispose a bit and did not create any video player controller directly.

here is my code if anyone need it in future

class VideoPlayerApp extends StatefulWidget {
  final String jsonLink;
  final String fileTitle;
  final String userId;
  final String creationTime;
  final bool showOnlyfile;

  const VideoPlayerApp(this.jsonLink, this.fileTitle, this.userId, this.creationTime, this.showOnlyfile, {super.key});
  @override
  State<VideoPlayerApp> createState() => _VideoPlayerAppState();
}

class _VideoPlayerAppState extends State<VideoPlayerApp> {

  bool keepLoading = true;
  String videoRootUrl = "";
  late  ChewieController chewieController;

  Future<String> fetchJsonContent() async {
    final jsonResponse = await http.get(Uri.parse(widget.jsonLink));
    if (jsonResponse.statusCode == 200) {
      var jsonContent = jsonDecode(jsonResponse.body);
      videoRootUrl = jsonContent["meta"]["rootUrl"];
      var files = jsonContent["files"];
      if (files.length > 0) {
        return videoRootUrl + files[0];
      }
      return "";
    } else {
      throw Exception('Failed to load json file of drive');
    }
  }

  @override
  void dispose() {
    print("|||||||||Video Dispose Called|||||||");
    chewieController.videoPlayerController.pause();
    chewieController.dispose();
    super.dispose();
  }

  void initState(){
    super.initState();
    initailSetup();
  }

  void initailSetup()async{
    String tempUrl = await fetchJsonContent();
    chewieController = ChewieController(
      videoPlayerController: VideoPlayerController.networkUrl(Uri.parse(tempUrl),videoPlayerOptions: VideoPlayerOptions(allowBackgroundPlayback: false),),
      autoPlay: false,
      autoInitialize: true,
      looping: false,
      showControls: true,
      aspectRatio: 16 / 9,
      materialProgressColors: ChewieProgressColors(
        backgroundColor: const Color.fromARGB(255, 4, 50, 90),
        bufferedColor: const Color.fromARGB(255, 4, 66, 116),
      ),
      errorBuilder: (context, errorMessage) {
        print("Video Player error --- $errorMessage");
        return const Center(
          child: Icon(Icons.error,color: Colors.white,),
        );
      },
    );
    print("Chewie controller set ----");
    setState(() {
      keepLoading = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: ()async{
        switch(contentUiPreviousPath){
          case "contentList":
            Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context)=>courseContent(creatorName: currentCourseCreator, courseId: currentCourseId, batchId: currentBatchId, batchTitle: currentBatchTitle, discussionChannel: discussionChannel, announcementChannnel: announcementChannnel, tabBarIndex: 1)));
            break;
          default:
            Navigator.of(context).pop();
            break;
        }
        return false;
      },
      child: Scaffold(
          appBar: (widget.showOnlyfile)?null:CustomAppBar(networkId: 'No-Network',tempNetworkImgUrl: ""),
          drawer: (widget.showOnlyfile)?null:const CustomDrawer(),
          body: (keepLoading)?const Center(child: CircularProgressIndicator(),)
          :Column(
            children: [
              (widget.showOnlyfile)?const SizedBox():Container(
                padding: const EdgeInsets.symmetric(
                  vertical: 13,
                ),
                width: MediaQuery.of(context).size.width * .9,
                alignment: Alignment.centerLeft,
                decoration: const BoxDecoration(
                    border: Border(
                        bottom: BorderSide(
                          width: 2,
                          color: Colors.black54,
                        ))),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      widget.fileTitle,
                      style: const TextStyle(
                        fontSize: 20,
                        fontWeight: FontWeight.bold,
                        color: Colors.black45,
                      ),
                      maxLines: 1,
                      overflow: TextOverflow.ellipsis,
                    ),
                    const SizedBox(height: 3,),
                    Text(
                      widget.creationTime,
                      style: const TextStyle(
                        fontSize: 12,
                        color: Colors.black45,
                      ),
                      maxLines: 1,
                      textAlign: TextAlign.left,
                      overflow: TextOverflow.ellipsis,
                    ),
                    const SizedBox(height: 3,),
                  ],
                ),
              ),
              Container(
                  height: (MediaQuery.of(context).size.width * 9) / 16,
                  margin: const EdgeInsets.symmetric(vertical: 20),
                  decoration: const BoxDecoration(color: Colors.black),
                  child: Chewie(
                    controller: chewieController,
                  )),
            ],
          )),
    );
  }
}