Flutter Video Player Example – The Flutter Video Player widget allows for video playback. The VideoPlayer widget allows for the playing of videos from multiple locations and mediums, such as local files, network streams, and asset bundles. The VideoPlayer widget offers numerous features and methods that allow you to modify the player’s appearance.
We have a list on how to use videos in Flutter
- Video player from url
- Video player from assets
- Video player full screen
- Control video
- Video thumbnail video player in listview
To play a video in Flutter, The VideoPlayer widget is located within the video player package, which must be imported before proceeding. Then, load the video you wish to watch by providing its URL or file path to the Flutter Video Player widget.
Video player from url
import 'package:flutter/material.dart'; import 'package:video_player/video_player.dart'; void main() => runApp(VideoPlayerApp()); class VideoPlayerApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'Video Player Demo', home: VideoPlayerScreen(), ); } } class VideoPlayerScreen extends StatefulWidget { @override _VideoPlayerScreenState createState() => _VideoPlayerScreenState(); } class _VideoPlayerScreenState extends State { late VideoPlayerController _controller; late Future _initializeVideoPlayerFuture; @override void initState() { super.initState(); _controller = VideoPlayerController.network( 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4'); _initializeVideoPlayerFuture = _controller.initialize(); _controller.setLooping(true); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Row(children: [ Image.asset( 'assets/logo.png', height: 30, ), Text('flutterflux.com') ]), ), body: FutureBuilder( future: _initializeVideoPlayerFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.done) { return AspectRatio( aspectRatio: _controller.value.aspectRatio, child: VideoPlayer(_controller), ); } else { return Center( child: CircularProgressIndicator(), ); } }, ), floatingActionButton: FloatingActionButton( onPressed: () { setState(() { if (_controller.value.isPlaying) { _controller.pause(); } else { _controller.play(); } }); }, child: Icon( _controller.value.isPlaying ? Icons.pause : Icons.play_arrow, ), ), ); } }
Note: Don’t forget to dispose the VideoPlayerController
when it’s no longer needed to avoid memory leaks. You can do this by calling controller.dispose()
in the dispose
method of your Stateful/Stateless widget.
Video player from Assets
import 'package:flutter/material.dart'; import 'package:video_player/video_player.dart'; void main() => runApp(VideoPlayerApp()); class VideoPlayerApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'Video Player Demo', home: VideoPlayerScreen(), ); } } class VideoPlayerScreen extends StatefulWidget { @override _VideoPlayerScreenState createState() => _VideoPlayerScreenState(); } class _VideoPlayerScreenState extends State { late VideoPlayerController _controller; @override void initState() { super.initState(); _controller = VideoPlayerController.asset('assets/BigBuckBunny.mp4') ..initialize().then((_) { // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed. setState(() {}); }); } @override void dispose() { super.dispose(); _controller.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('My Video'), ), body: Center( child: _controller.value.isInitialized ? AspectRatio( aspectRatio: _controller.value.aspectRatio, child: VideoPlayer(_controller), ) : Container(), ), floatingActionButton: FloatingActionButton( onPressed: () { setState(() { _controller.value.isPlaying ? _controller.pause() : _controller.play(); }); }, child: Icon( _controller.value.isPlaying ? Icons.pause : Icons.play_arrow, ), ), ); } }
As seen in the preceding code snippet, the asset ‘assets/BigBuckBunny.mp4’ is being played via the VideoPlayerScreen
widget. Inside the app’s main loop, we load the movie into memory, initialize the VideoPlayerController
object, and then show it using the Flutter Video Player widget.
We also have a floatingActionButton
that starts and pauses the video playback when pressed.
Make sure to dispose the controller when the widget is no longer used to free up resources.
How to make video player full screen
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:video_player/video_player.dart'; void main() => runApp(VideoPlayerApp()); class VideoPlayerApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'Video Player Demo', home: MyVideoPlayer(), ); } } class FullScreenVideo extends StatefulWidget { final VideoPlayerController videoPlayerController; FullScreenVideo({required this.videoPlayerController}); @override _FullScreenVideoState createState() => _FullScreenVideoState(); } class _FullScreenVideoState extends State { @override Widget build(BuildContext context) { SystemChrome.setPreferredOrientations([ DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight, ]); return Scaffold( body: Center( child: AspectRatio( aspectRatio: widget.videoPlayerController.value.aspectRatio, child: VideoPlayer(widget.videoPlayerController), ), ), floatingActionButton: FloatingActionButton( onPressed: () { Navigator.pop(context); }, child: Icon(Icons.close), ), ); } } class MyVideoPlayer extends StatefulWidget { @override _MyVideoPlayerState createState() => _MyVideoPlayerState(); } class _MyVideoPlayerState extends State { late VideoPlayerController _controller; @override void initState() { super.initState(); _controller = VideoPlayerController.asset('assets/BigBuckBunny.mp4') ..initialize().then((_) { // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed. setState(() {}); }); } @override void dispose() { super.dispose(); _controller.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('My Video'), ), body: Center( child: _controller.value.isInitialized ? GestureDetector( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => FullScreenVideo( videoPlayerController: _controller, ), ), ); }, child: AspectRatio( aspectRatio: _controller.value.aspectRatio, child: VideoPlayer(_controller), ), ) : Container(), ), floatingActionButton: FloatingActionButton( onPressed: () { setState(() { SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitDown, DeviceOrientation.portraitUp, ]); _controller.value.isPlaying ? _controller.pause() : _controller.play(); }); }, child: Icon( _controller.value.isPlaying ? Icons.pause : Icons.play_arrow, ), ), ); } }
Your Flutter project will require a new page and the MyVideoPlayer widget added in order to use this code. Both the video file and the Flutter Video Player package would need to be imported into your app’s assets folder.
How to control video player
To control a Flutter Video Player, you can use the VideoPlayerController class from the video_player package. The VideoPlayerController provides methods to play, pause, seek, and control the volume of a video. Eexample of how to control a video in Flutter:
import 'package:flutter/material.dart'; import 'package:video_player/video_player.dart'; void main() => runApp(VideoPlayerApp()); class VideoPlayerApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'Video Player Demo', home: VideoPlayerScreen(), ); } } class VideoPlayerScreen extends StatefulWidget { @override _VideoPlayerScreenState createState() => _VideoPlayerScreenState(); } class _VideoPlayerScreenState extends State { late VideoPlayerController _controller; late Future _initializeVideoPlayerFuture; @override void initState() { super.initState(); _controller = VideoPlayerController.network( 'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4'); _initializeVideoPlayerFuture = _controller.initialize(); _controller.setLooping(true); } @override void dispose() { _controller.dispose(); super.dispose(); } void _play() { setState(() { _controller.play(); }); } void _pause() { setState(() { _controller.pause(); }); } void _seekTo(Duration position) { setState(() { _controller.seekTo(position); }); } void _setVolume(double volume) { setState(() { _controller.setVolume(volume); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Video Player Demo'), ), body: FutureBuilder( future: _initializeVideoPlayerFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.done) { return AspectRatio( aspectRatio: _controller.value.aspectRatio, child: VideoPlayer(_controller), ); } else { return Center( child: CircularProgressIndicator(), ); } }, ), floatingActionButton: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ FloatingActionButton( onPressed: _play, child: Icon(Icons.play_arrow), ), SizedBox(width: 10), FloatingActionButton( onPressed: _pause, child: Icon(Icons.pause), ), SizedBox(width: 10), FloatingActionButton( onPressed: () => _seekTo(Duration(seconds: 10)), child: Icon(Icons.forward_10), ), SizedBox(width: 10), FloatingActionButton( onPressed: () => _setVolume(0.5), child: Icon(Icons.volume_up), ), ], ), ); } }
Four methods have been included to manage the Flutter Video Player: _play
, _pause
, _seekTo
, and _setVolume
. The _play method utilizes the play method of the controller object to initiate video playback. On the other hand, the _pause method utilizes the pause method of the controller object to stop video playback. The _seekTo
method takes a Duration object as input and leverages the seekTo method of the controller object to move the video to the specified position. Finally, the _setVolume
method accepts a double value ranging between 0 and 1 and calls the setVolume method of the controller object to adjust the video’s volume. The corresponding onPressed properties of the FloatingActionButton widgets utilize these methods.
Video Player thumbnail
Example code in Flutter Video Player to generate a thumbnail from a video:
import 'dart:io'; import 'dart:typed_data'; import 'package:path_provider/path_provider.dart'; import 'package:flutter/material.dart'; import 'package:video_thumbnail/video_thumbnail.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Video Thumbnail Example', home: HomePage(), ); } } class HomePage extends StatefulWidget { @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State { String? _thumbnail; @override void initState() { super.initState(); _generateThumbnail(); } Future _generateThumbnail() async { final fileName = await VideoThumbnail.thumbnailFile( video: "https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4", thumbnailPath: (await getTemporaryDirectory()).path, imageFormat: ImageFormat.WEBP, maxHeight: 150, // specify the height of the thumbnail, let the width auto-scaled to keep the source aspect ratio quality: 75, ); setState(() { _thumbnail = fileName; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Row(children: [ Image.asset( 'assets/logo.png', height: 30, ), Text('flutterflux.com') ]), ), body: Center( child: _thumbnail != null ? Image.file(File(_thumbnail!)) : CircularProgressIndicator(), ), ); } }
Example code uses the video_player package to play the selected video and FlutterFFmpeg package to generate a thumbnail from the video. The video can be selected from the gallery using the ImagePicker package. Once the video is selected, it is displayed on the screen using the VideoPlayer widget. The _generateThumbnail method utilizes the FlutterFFmpeg package to generate a thumbnail from the video at a specific time and stores it in the temporary directory. Finally, the thumbnail is displayed on the screen using the Image widget.
Video player in listview
To add a Flutter Video Player in a ListView, you can follow these steps:
- First, import the necessary packages. You will need the video_player package to play the video and the chewie package to display the video player UI.
import 'package:video_player/video_player.dart'; import 'package:chewie/chewie.dart';
- Create a ListView with a list of video URLs.
List videoUrls = [ 'https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4', 'https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_2mb.mp4', 'https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_5mb.mp4', ]; ListView.builder( itemCount: videoUrls.length, itemBuilder: (BuildContext context, int index) { return VideoItem(url: videoUrls[index]); }, );
- Create a stateful widget called
VideoItem
that contains aVideoPlayerController
and aChewieController
.
class VideoItem extends StatefulWidget { final String url; VideoItem({required this.url}); @override _VideoItemState createState() => _VideoItemState(); } class _VideoItemState extends State { late VideoPlayerController _videoPlayerController; late ChewieController _chewieController; @override void initState() { super.initState(); _videoPlayerController = VideoPlayerController.network(widget.url); _chewieController = ChewieController( videoPlayerController: _videoPlayerController, autoPlay: false, looping: false, allowMuting: true, showControls: true, ); } @override Widget build(BuildContext context) { return Container( height: 200, child: Chewie( controller: _chewieController, ), ); } @override void dispose() { _videoPlayerController.dispose(); _chewieController.dispose(); super.dispose(); } }
- In the
initState
method, create aVideoPlayerController
with the video URL, and create aChewieController
with theVideoPlayerController
. Set the necessary properties, such asautoPlay
,looping
, andshowControls
. - In the
build
method, return aContainer
with a fixed height, and aChewie
widget that takes theChewieController
. - In the
dispose
method, dispose theVideoPlayerController
and theChewieController
.
With these steps, you should be able to add a video player in a ListView in Flutter.
Complete code
import 'package:flutter/material.dart'; import 'package:video_player/video_player.dart'; import 'package:chewie/chewie.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Video Player in ListView', home: VideoListView(), ); } } class VideoListView extends StatelessWidget { final List videoUrls = [ 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4', 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4', 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4', 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4', 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4', 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4', ]; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Video Player in ListView'), ), body: ListView.builder( itemCount: videoUrls.length, itemBuilder: (BuildContext context, int index) { return VideoItem(url: videoUrls[index]); }, ), ); } } class VideoItem extends StatefulWidget { final String url; VideoItem({required this.url}); @override _VideoItemState createState() => _VideoItemState(); } class _VideoItemState extends State { late VideoPlayerController _videoPlayerController; late ChewieController _chewieController; @override void initState() { super.initState(); _videoPlayerController = VideoPlayerController.network(widget.url); _chewieController = ChewieController( aspectRatio: 4.5 / 3, videoPlayerController: _videoPlayerController, autoPlay: false, looping: false, allowMuting: true, showControls: true, ); } @override Widget build(BuildContext context) { return Container( height: 200, child: Chewie( controller: _chewieController, ), ); } @override void dispose() { _videoPlayerController.dispose(); _chewieController.dispose(); super.dispose(); } }
Conclusion
For developers interested in creating video-centric apps, Flutter Video Player is a must-have component. The Flutter video player plugin is an easy and quick way to play videos on mobile devices running Android and iOS. Video controls, aspect ratio, and autoplay are just a few of the numerous customizable features of Flutter’s video player plugin. In the latest version of Flutter, 3.7, the video player plugin has been improved and now supports both web and desktop platforms. Flutter’s video player plugin is highly recommended for anyone creating video-centric apps that prioritize simplicity and clarity of design.