A widget created to play videos from files in flutter. The width and height of the widget is controlled by the parent. This is used mostly for preview videos that just got captured from the camera or where selected from the gallery.
Dependencies
Add the following packages in the pubspec.yaml first.
- video_player: ^version
and run the pub get command from the terminal.
Usage
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: _recordingState == RecordingState.preview
? PreviewWidget(videoFile, onPreviewDone)
: RecordWidget(widget.question, fileCallback, onExit),
),
);
}
onPreviewDone(path, index) async {
if (path == null) {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('Couldn\'t get video')));
} else {
setState(() {
// upload to backend. Navigate away
});
}
}
Parameters
@videoFile : Mandatory. The video file to be previewed @doneCallback : Mandatory. The callback to call when the user wants to navigate away from the screen
Widget
class PreviewWidget extends StatefulWidget {
PreviewWidget(this.videoFile, this.doneCallback, {Key key, scaffoldKey})
: super(key: key);
final XFile videoFile;
final Function(bool) doneCallback;
@override
_PreviewWidgetState createState() => _PreviewWidgetState();
}
class _PreviewWidgetState extends State<PreviewWidget>
with WidgetsBindingObserver {
VideoPlayerController videoController;
VoidCallback videoPlayerListener;
@override
void initState() {
_startVideoPlayer();
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Stack(
children: [
_buildRecordingPreview(context),
Padding(
padding: const EdgeInsets.all(Dimens.paddingBig),
child: Align(
alignment: Alignment.bottomRight,
child: Padding(
padding: const EdgeInsets.all(Dimens.padding),
child: Align(
alignment: Alignment.bottomCenter,
child: IconButton(
icon: Icon(Icons.navigate_next),
iconSize: 80,
color: Colors.blue,
onPressed: () {
widget.doneCallback(true);
},
),
),
)),
)
],
),
),
);
}
_buildRecordingPreview(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Center(
child: videoController != null
? VideoPlayer(videoController)
: Container(child: Text(Strings.loading)),
));
}
Future<void> _startVideoPlayer() async {
final VideoPlayerController vController =
VideoPlayerController.file(File(widget.videoFile.path));
videoPlayerListener = () {
if (videoController != null && videoController.value.size != null) {
// Refreshing the state to update video player with the correct ratio.
if (mounted) setState(() {});
videoController.removeListener(videoPlayerListener);
}
};
vController.addListener(videoPlayerListener);
await vController.setLooping(true);
await vController.initialize();
final VideoPlayerController oldController = videoController;
if (mounted) {
setState(() {
videoController = vController;
});
}
await vController.play();
await oldController?.dispose();
}
}