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.