Flutter Video Player :Implementing video functionality from scratch would be a burdensome task. But there are few plugins available to make developer life easy. The video player plugin is one of the best plugins available for Flutter to fulfill that requirement.
In this article, you will learn how to apply the video player plugin along with controlling the different functionalities of the video player.
Creating a new video player
Before using the video player plugin, you should add it to your pubspec.yaml
file. When you open the pubspec.yaml
file, you can see some configurations and dependencies required to run your app. Our video player plugin should be added under the dependencies
block:
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
video_player: 2.1.15 //video player
The current version of the plugin is 2.1.15
, but you can add the latest version in here by checking the plugin page. If you are in VS Code when you save the file, it will download the plugin automatically. If not, open the terminal and write flutter pub get
to download the plugin.
Go to the file where you want to add the plugin and import the video_player.dart
file:
import 'package:video_player/video_player.dart';
Now you can use the video player plugin in your project.
There are few ways to load video. Let’s load our example from the assets. Create an assets/video folder at the root level of the project and add a video inside that folder. Then in pubspec.yaml
, under the assets
section, specify the file path as below:
assets:
- assets/video/video.mp4
Let’s create a separate stateful widget called VideoPlayerWidget
to insert our video player–related implementation.
You can initialize the video player inside the initState
method like below. Also, don’t forget to dispose
the video player to do cleanup work:
class _VideoPlayerState extends State<VideoPlayerWidget> {
late VideoPlayerController _videoPlayerController;
@override
void initState() {
super.initState();
_videoPlayerController = VideoPlayerController.asset(
'assets/video/video.mp4')
..initialize().then((_) {
setState(() {});
_videoPlayerController.play();
});
}
@override
void dispose() {
_videoPlayerController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Center(
child: VideoPlayer(_videoPlayerController),
);
}
}
VideoPlayerController
must specify with the late
keyword because we are still not a defined video player controller in that line and we are going to do that later. Inside the initState
, videoPlayerController
has been initialized along with the path of the asset.
When the initialization is completed, it changes the state and rebuilds the widget. You can start playing the video after initialization.
Instead of assets
, you can use the video URL. To access the network, you should add Internet permission configurations to both Android and iOS.
From the root, go to ios/Runner
and open the info.plist
file. Then, add the following config to that file:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Next, go to android/app/src/main
and open AndroidManifest.xml
. Then, add the following code to it:
<uses-permission android:name="android.permission.INTERNET"/>
Now you can change asset
to network
and add the video URL there:
@override
void initState() {
super.initState();
_videoPlayerController =
VideoPlayerController.network('video_url_here')
..initialize().then((_) {
setState(() {});
_videoPlayerController.play();
});
}
Even though initialization has been done, there should be a way to show the player in the UI. The VideoPlayer
widget can be used to do that. To make it work, you should pass the controller as a first argument to the VideoPlayer
widget.
It’s better to check whether the initialization is a success before showing the VideoPlayer
widget:
@override
Widget build(BuildContext context) {
return Center(
child: _videoPlayerController.value.isInitialized ? VideoPlayer(_videoPlayerController) : Container(),
);
}
Now you can see the video on the screen. But there is a small issue: it’s not in a proper aspect ratio. That can be fixed by using the AspectRatio
widget. The video player provides a proper aspect ratio of the video, and you can use that value to set to an AspectRatio
widget:
@override
Widget build(BuildContext context) {
return Center(
child: _videoPlayerController.value.isInitialized ? AspectRatio(aspectRatio:
_videoPlayerController.value.aspectRatio,
child: VideoPlayer(_videoPlayerController)
) : Container(),
);
}
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
import 'package:videocall/vcaption.dart';
class VideoPlayer extends StatefulWidget {
const VideoPlayer(VideoPlayerController videoPlayerController, {super.key});
@override
State<VideoPlayer> createState() => _VideoPlayerState();
}
class _VideoPlayerState extends State<VideoPlayer> {
late VideoPlayerController _videoPlayerController;
String? selectedCaption = "";
Map<int, String> captions = {5: "First subtitle", 20: "Second subtitle"};
@override
void initState() {
super.initState();
_videoPlayerController =
VideoPlayerController.asset('assets/videos/nature.mp4')
..addListener(() {
if (_videoPlayerController.value.isPlaying) {
setState(() {
if (captions.containsKey(
_videoPlayerController.value.position.inSeconds)) {
selectedCaption =
captions[_videoPlayerController.value.position.inSeconds];
}
});
}
})
..initialize().then((_) {
setState(() {});
_videoPlayerController.play();
});
}
@override
void dispose() {
_videoPlayerController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Stack(children: [
_videoPlayerController.value.isInitialized
? AspectRatio(
aspectRatio: _videoPlayerController.value.aspectRatio,
child: VideoPlayer(_videoPlayerController))
: Container(),
Positioned(
bottom: 2,
width: MediaQuery.of(context).size.width,
child: _videoPlayerController.value.isInitialized
? VCaption(_videoPlayerController)
: Container(),
),
Positioned(
bottom: 0,
width: MediaQuery.of(context).size.width,
child: VideoProgressIndicator(
_videoPlayerController,
allowScrubbing: false,
colors: VideoProgressColors(
backgroundColor: Colors.blueGrey,
bufferedColor: Colors.blueGrey,
playedColor: Colors.blueAccent),
))
]),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(Colors.blue),
fixedSize: MaterialStateProperty.all(Size(70, 70)),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100)))),
onPressed: () {
_videoPlayerController.seekTo(Duration(
seconds: _videoPlayerController.value.position.inSeconds -
10));
},
child: Icon(Icons.skip_previous)),
ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(Colors.blue),
fixedSize: MaterialStateProperty.all(Size(70, 70)),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100)))),
onPressed: () {
_videoPlayerController.pause();
},
child: Icon(Icons.pause)),
Padding(padding: EdgeInsets.all(2)),
ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(Colors.redAccent),
fixedSize: MaterialStateProperty.all<Size>(Size(80, 80)),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100)))),
onPressed: () {
_videoPlayerController.play();
},
child: Icon(Icons.play_arrow)),
ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(Colors.blue),
fixedSize: MaterialStateProperty.all(Size(70, 70)),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100)))),
onPressed: () {
_videoPlayerController.seekTo(Duration(
seconds: _videoPlayerController.value.position.inSeconds +
10));
},
child: Icon(Icons.fast_forward))
],
)
],
);
}
}
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
class VCaption extends StatefulWidget {
const VCaption(
this.videoPlayerController,
);
final VideoPlayerController videoPlayerController;
@override
_VCaptionState createState() => _VCaptionState();
}
class _VCaptionState extends State<VCaption> {
String? selectedCaption = "";
Map<int, String> captions = {
5: "Nature Love",
20: "Some people love the ocean Some people fear it I love it, hate it, fear it, respect it, cherish it, loathe it, and frequently curse it"
};
@override
void initState() {
widget.videoPlayerController.addListener(() {
if (widget.videoPlayerController.value.isPlaying) {
print("Time ${widget.videoPlayerController.value.position.inSeconds}");
setState(() {
if (captions.containsKey(
widget.videoPlayerController.value.position.inSeconds)) {
selectedCaption =
captions[widget.videoPlayerController.value.position.inSeconds];
}
});
}
});
super.initState();
}
@override
Widget build(BuildContext context) {
return ClosedCaption(
text: selectedCaption,
textStyle: TextStyle(fontSize: 15, color: Colors.white),
);
}
}
For More: To know about videocall in flutter
Leave a Reply