Describe the bug
The video is playing and when calling dispose
and setting the controller to null
, the video keeps playing (in logs).
To Reproduce
Steps to reproduce the behavior:
- Build the sample app
- see that the video is playing
- scroll to bottom until you don't see the video in the screen anymore
- see the logs telling "disposed"
- see the logs of the
MediaCoder
that keeps decoding / building frames
*Example code
import 'package:better_player/better_player.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:visibility_detector/visibility_detector.dart';
void main() => runApp(const VideoPlayerApp());
class VideoPlayerApp extends StatelessWidget {
const VideoPlayerApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Video Player Demo',
home: VideoPlayerScreen(),
);
}
}
class VideoPlayerScreen extends StatefulWidget {
const VideoPlayerScreen({Key? key}) : super(key: key);
@override
_VideoPlayerScreenState createState() => _VideoPlayerScreenState();
}
class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: 10,
itemBuilder: (context, index) {
return index == 1 ? VideoItem() : Container(margin: EdgeInsets.all(20), width: 200, height: 200, color: Colors.red);
})
);
}
}
class VideoItem extends StatefulWidget {
@override
_VideoItemState createState() => _VideoItemState();
}
class _VideoItemState extends State<VideoItem> {
BetterPlayerController? controller;
final SimpleProvider simpleProvider = SimpleProvider();
void initPlayer() {
controller = BetterPlayerController(
BetterPlayerConfiguration(
aspectRatio: 16/9,
looping: true,
autoPlay: true,
autoDispose: false,
handleLifecycle: false,
controlsConfiguration: BetterPlayerControlsConfiguration(showControls: false)
),
betterPlayerDataSource: BetterPlayerDataSource(
BetterPlayerDataSourceType.network,
'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4',
)
);
}
void onVisibilityChanged(double fraction) {
print("Fraction is : $fraction");
if (fraction == 0) {
if (controller != null) {
controller!.dispose();
controller = null;
simpleProvider.notify();
print("Controller is disposed.");
}
} else {
if (controller == null) {
initPlayer();
print("Controller is a new one.");
simpleProvider.notify();
}
/*
if (fraction >= 0.8 && controller!.isVideoInitialized() != null && controller!.isVideoInitialized()!) {
if (controller!.isPlaying() != null && controller!.isPlaying()!) {
controller!.pause();
}
else {
controller!.play();
}
}
*/
}
}
@override
void initState() {
super.initState();
initPlayer();
}
@override
void dispose() {
if (controller != null) {
controller!.dispose();
controller = null;
print("Disposed controller from Framework.");
}
super.dispose();
}
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider.value(value: simpleProvider,
child: VisibilityDetector(key: GlobalKey(),
child: Consumer<SimpleProvider>(
builder: (context, model, child) {
return controller != null ? BetterPlayer(controller: controller!) : Container(width: 200, height: 200, color: Colors.blue);
},
),
onVisibilityChanged: (info) {
onVisibilityChanged(info.visibleFraction);
}),
);
}
}
class SimpleProvider extends ChangeNotifier {
void notify() {
notifyListeners();
}
}
Expected behavior
I expect the player to be released when we call controller.dispose()
, meaning that the MediaCodec
should be closed, as well as the AudioCodec
and stop seeing logs of frames => video not playing ?
Flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.2.3, on macOS 11.5.2 20G95 darwin-x64, locale fr-FR)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[✓] Xcode - develop for iOS and macOS
[✓] Chrome - develop for the web
[!] Android Studio (version 2020.3)
✗ Unable to find bundled Java version.
[✓] Connected device (3 available)
! Doctor found issues in 1 category.
Better Player version
Smartphone (please complete the following information):
- Device: OPPO, Iphone XS Max
- OS: Android / IOS
Additional context
I am simply trying to do a "reusable" controller
so that i can play multiple videos in ListView
with only one playing at the same time and the same controller for every video to avoid OOM errors.
That's why i am using such implementation, probably not optimal though.
I have checked your sample code about ReusableVideoList
widgets, but i simply need to do this with a single controller so i have tried to simply the code.
The problem is that with such configuration (and this error) i have another error if i have several videos that tells this.
Thank you for your time
info required