I have code in the initState
that goes something like this (video_player package):
@override void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
final navBar = Provider.of<NavBar>(context, listen: false);
navBar.urls.forEach((element) {
navBar.videoControllers.add(
VideoPlayerController.network(
navBar.urls[videoCount],
videoPlayerOptions: VideoPlayerOptions(
allowBackgroundPlayback: false,
),
)..initialize().then((value) => navBar.initialized = true)
);
}
navBar.notify(); // This is a method that calls notifyListeners() within the NavBar class (with ChangeNotifier like how a Provider class does).
navBar.videoControllers[0].play();
navBar.notify();
}
}
The behaviour of this code is such that the video starts playing, I can hear the audio as well, but the page has not been loaded as I see no UI elements but a white screen.
Once I just do a hot reload, all the UI elements are there and I can see the video playing as well.
Where am I going wrong here?
CodePudding user response:
Maybe you are having a problem with async methods...
Try to move this block:
navBar.notify(); // This is a method that calls notifyListeners() within the NavBar class (with ChangeNotifier like how a Provider class does).
navBar.videoControllers[0].play();
navBar.notify();
Inside the initialize response, something like this:
..initialize().then((value) {
navBar.initialized = true
navBar.notify(); // This is a method that calls notifyListeners() within the NavBar class (with ChangeNotifier like how a Provider class does).
navBar.videoControllers[0].play();
navBar.notify();
})
In this way you will only start the video after it is added to the videoControllers
and it`s properly initialized.
The final code:
@override void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
final navBar = Provider.of<NavBar>(context, listen: false);
navBar.urls.asMap().forEach((index, element) {
navBar.videoControllers.add(
VideoPlayerController.network(
navBar.urls[videoCount],
videoPlayerOptions: VideoPlayerOptions(
allowBackgroundPlayback: false,
),
)..initialize().then((value) {
navBar.initialized = true)
// To execute this block just when it is the first item.
if (index == 0) {
navBar.notify();
navBar.videoControllers[0].play();
navBar.notify();
}
}
);
}
}
}
CodePudding user response:
The video_player package works as such that it will not display the video correctly if you display the VideoPlayer
before it is initialized in your Widget tree. So just like their tutorial in the flutter packages website (which I sadly overlooked at that part), you need to check for the initialization before displaying it. If you don't, only a hot reload can work.
children:
(navBar.videoControllers[0].value.isInitialized) ?
navBar.scrollingVideos :
[
Container(),
],
Note: scrollingVideos
is a List<Widget>
that contains the video players.