I am trying Flutter video_player
with chewie
. I have tried both examples provided in:
Both work fine. Yet, even when the user does not tap on the screen, the video URL is immediately fetched and downloaded.
How can I postpone the video download until the user’s action?
Modifiying the example from the chewie package and putting it inside of a StatefulWidget
, we get:
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
import 'package:chewie/chewie.dart';
class ExampleWidget extends StatefulWidget {
const ExampleWidget({super.key});
@override
State<ExampleWidget> createState() => _ExampleWidgetState();
}
final VideoPlayerController videoPlayerController = VideoPlayerController.networkUrl(
Uri.parse('https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4'));
class _ExampleWidgetState extends State<ExampleWidget> {
late final ChewieController chewieController;
bool _initialized = false;
@override
void initState() {
chewieController = ChewieController(
videoPlayerController: videoPlayerController, autoPlay: false, looping: true, autoInitialize: false);
}
@override
void dispose() {
videoPlayerController.dispose();
chewieController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Expanded(
child: Chewie(controller: chewieController),
),
ElevatedButton(
onPressed: () async {
if (!_initialized) {
await videoPlayerController.initialize();
}
_initialized = true;
await chewieController.play();
},
child: const Text("Play"),
),
],
);
}
}
void main() => runApp(MaterialApp(
home: Scaffold(
backgroundColor: Colors.green,
appBar: AppBar(),
body: Builder(builder: (BuildContext context) => _build(context)))));
Widget _build(BuildContext context) {
return const ExampleWidget();
}
By setting the autoPlay
from the ChewieController
to false, the video will not automatically play and by using the chewieController.play()
, you can then start the video on pressing a button.
To also prevent the controller from preloading the video, only initialize the videoPlayerController
in the callback method once instead of inside of the initState
method.
This will load the video the first time the Play
button is pressed (But remember that in this example clicking inside of the video itself would show the error symbol).
Instead you could also display some kind of loading Widget instead while the initialized
bool is false and only show the Video Player otherwise. Or set the param showControls
to false inside of the ChewieController
.