Home > database >  Flutter: Stop playing video in list view when another video is started
Flutter: Stop playing video in list view when another video is started

Time:12-03

i am using Better Player (https://pub.dev/packages/better_player) to create several video players in list view.

ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
addAutomaticKeepAlives: true,
itemCount: awaitedContents!.length,
itemBuilder: (context, index) {
  Content content = awaitedContents[index];
 ...
  } else if (content.type == 'VIDEO') {
    return SizedBox(
      height: MediaQuery.of(context).size.width * 9 / 16,
      child: VideoContent(content.value, content.image,
          content.videoSubtitle, subtitlesEnabled),
    );
  }

How can I stop one Video player from playing when users starts another one?

CodePudding user response:

I guess you could use AutomaticKeepAliveClientMixin and the KeepAlive widgets:

ListView.builder(
  shrinkWrap: true,
  physics: const NeverScrollableScrollPhysics(),
  itemCount: awaitedContents!.length,
  itemBuilder: (context, index) {
    Content content = awaitedContents[index];
    ...
    if (content.type == 'VIDEO') {
      return KeepAlive(
        child: VideoContent(content.value, content.image,
            content.videoSubtitle, subtitlesEnabled),
      );
    }
  }
)

KeepAlive widget is used to wrap the VideoContent widget for each video in the list. This will cause the VideoContent widget to be kept alive and its children to be retained when the list view is scrolled. When a new video is started, the KeepAlive widget will dispose of the previous VideoContent widget and its children, stopping any videos that were playing.

CodePudding user response:

To stop one video player from playing when the user starts another one, you can use the dispose method of the BetterPlayerController class. This method will stop the video player and release any resources it is using.

Here's an example of how you might update your code to use the dispose method:

import 'package:better_player/better_player.dart';

ListView.builder(
  shrinkWrap: true,
  physics: const NeverScrollableScrollPhysics(),
  addAutomaticKeepAlives: true,
  itemCount: awaitedContents!.length,
  itemBuilder: (context, index) {
    Content content = awaitedContents[index];
    if (content.type == 'VIDEO') {
      // Create a new BetterPlayerController instance
      BetterPlayerController playerController = BetterPlayerController();

      return SizedBox(
        height: MediaQuery.of(context).size.width * 9 / 16,
        child: VideoContent(content.value, content.image,
            content.videoSubtitle, subtitlesEnabled, playerController),
      );
    }
  }
)

class VideoContent extends StatefulWidget {
  final String videoUrl;
  final String videoSubtitle;
  final bool subtitlesEnabled;
  final BetterPlayerController playerController;

  const VideoContent(this.videoUrl, this.videoImage, this.videoSubtitle,
      this.subtitlesEnabled, this.playerController);

  @override
  _VideoContentState createState() => _VideoContentState();
}

class _VideoContentState extends State<VideoContent> {
  @override
  Widget build(BuildContext context) {
    return BetterPlayer(
      widget.playerController,
      src: widget.videoUrl,
      autoplay: false,
      aspectRatio: 16 / 9,
      fit: BoxFit.contain,
      placeholder: Container(
        child: Center(
          child: CircularProgressIndicator(),
        ),
      ),
      onVideoStart: () {
        // Stop the previous video player and release its resources when the user starts a new video
        widget.playerController.dispose();
      },
    );
  }
}

In this example, when the user starts a new video, the onVideoStart callback is triggered, and the dispose method is called on the previous BetterPlayerController instance. This will stop the previous video player and release its resources.

  • Related