Videos are everywhere - they can convey information more quickly than any other format. From YouTube and Instagram stories to app development courses, playing videos directly inside your app is becoming more and more needed.
How can play videos in Flutter? There is a library directly from the Flutter team simply called video_player. This library, however, is completely bare-bones. While it can play videos, it's up to you to add video playback controls and to style it. There is a better option which comes bundled with the UI as you'd expect both on Android and iOS - Chewie.
Project setup
Aside from importing the library itself, playing videos requires additional setup for iOS.
Importing packages
pubspec.yaml
dependencies:
flutter:
sdk: flutter
chewie: ^0.9.7
iOS setup
To be able to play network videos, you need to tell iOS about your intentions of loading network data. Similar setup is also required for Android, but when you create a new app through the flutter create command, all the needed permissions are done for you.
Open <your_project>/ios/Runner/Info.plist and add the following code.
Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
...
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
</dict>
</plist>
Playing videos
Chewie (and video_player for that matter) can play videos from 3 sources - assets, files and network. The beauty of it is that you don't need to write a lot of code to change the data source. Switching from an asset to a network video is a matter of just a few keystrokes. Let's first take a look at assets.
Asset videos setup
Assets are simply files which are readily available for your app to use. They come bundled together with your app file after you build it for release.
To set up assets, simply create a folder in the root of your project and call it, for example, videos. Then drag your desired video file in there.
To let Flutter know about all the available assets, you have to specify them in the pubspec file.
pubspec.yaml
flutter:
uses-material-design: true
assets:
- videos/IntroVideo.mp4
Using the Chewie widget
Now comes the time to start playing videos. For that Chewie provides its own widget which is, as I've already mentioned, only a wrapper on top of the VideoPlayer which comes directly from the Flutter team.
Because we want to play multiple videos displayed in a ListView, it's going to be the best to put all of the video-playing related things into it's own widget. Also, because video player resources need to be released, you need to create a StatefulWidget to get hold of the dispose() method.
chewie_list_item.dart
import 'package:chewie/chewie.dart';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
class ChewieListItem extends StatefulWidget {
// This will contain the URL/asset path which we want to play
final VideoPlayerController videoPlayerController;
final bool looping;
ChewieListItem({
@required this.videoPlayerController,
this.looping,
Key key,
}) : super(key: key);
@override
_ChewieListItemState createState() => _ChewieListItemState();
}
class _ChewieListItemState extends State<ChewieListItem> {
ChewieController _chewieController;
@override
void initState() {
super.initState();
// Wrapper on top of the videoPlayerController
_chewieController = ChewieController(
videoPlayerController: widget.videoPlayerController,
aspectRatio: 16 / 9,
// Prepare the video to be played and display the first frame
autoInitialize: true,
looping: widget.looping,
// Errors can occur for example when trying to play a video
// from a non-existent URL
errorBuilder: (context, errorMessage) {
return Center(
child: Text(
errorMessage,
style: TextStyle(color: Colors.white),
),
);
},
);
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Chewie(
controller: _chewieController,
),
);
}
@override
void dispose() {
super.dispose();
// IMPORTANT to dispose of all the used resources
widget.videoPlayerController.dispose();
_chewieController.dispose();
}
}
To play the videos inside a ListView, we don't need to do a lot of additional work. With all of the chewie stuff in its own separate widget, let's create a MyHomePage StatelessWidget.
main.dart
import 'package:chewie_prep/chewie_list_item.dart';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Video Player'),
),
body: ListView(
children: <Widget>[
ChewieListItem(
videoPlayerController: VideoPlayerController.asset(
'videos/IntroVideo.mp4',
),
looping: true,
),
ChewieListItem(
videoPlayerController: VideoPlayerController.network(
'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
),
),
ChewieListItem(
// This URL doesn't exist - will display an error
videoPlayerController: VideoPlayerController.network(
'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/error.mp4',
),
),
],
),
);
}
}
Conclusion
Chewie is a Flutter package aimed at simplifying the process of playing videos. Instead of you having to deal with start, stop, and pause buttons, doing the overlay to display the progress of the video, Chewie does these things for you.
Be sure to check out the video tutorial for a more hands-on perspective of building this app.
Good job on explaining it, after trying it i have a bit of problem, the player still playing the video sound after i hit back button, does dispose(); didn’t stop the video and i need to pause it manually?
I cannot open the video from openload link.. why? Please leave a comment to me..
full screen button on viewer not working properly
i want to play the video in a small container but the play controls doesn’t fit the small container i have alwayse overflowed error.
please help!
Great walk through of this! In my implementation I am having trouble with using the dispose how you have implemented it here. anytime the list scrolls off the list item gets disposed and the video player throws an error – “A VideoPlayerController was used after being disposed”. Did you have the same problem here?
Hello everybody,
I have a problem anytime the list scrolls off the list item gets disposed and the video player throws an error – “A VideoPlayerController was used after being disposed”.
Did you solve this problem?
Hi,
The video view does not respect the screen orientation.
If I rotate the device it does not play in fullscreen.
Anyone achieved it?
Hi Reso,
I have list view and player on top. Like YouTube. I wanted to play next video when user click list item. How should I be able to re use Chewie controller for this use case?
Do i have to dispose it and re initialize it?
Caused by: com.google.android.exoplayer2.upstream.HttpDataSource$HttpDataSourceException: Unable to connect
Hi, Reso, this tutorial is older, you need update right now the version chewie 1.2.2 and flutter used null-safety, many people have problem with this tutorial,
cheers
Great code!
I am facing the below issue
PlatformException(VideoError, Video player had error c.d.a.c.j0: MediaCodecVideoRenderer error, index=0, format=Format(1, null, null, video/avc, null, -1, null, [1920, 1080, 25.0], [-1, -1]), format_supported=YES, null, null)
After playing 3-4 videos continuously. Please give me a solution.
rumah murah sidoarjo perumahan murah yang terletak di sidoarjo, letaknya sangat strategis