Sorry if the question isn't that straight forward I'm just starting out. Every play video example I see through flutter examples uses a floating action button in the same class as the video player. I want to add a video player instance to my home screen and experiment with different ways to play the video (tapping on different elements, etc. I can't seem to gain access to the instance to access the controller. I'm not sure how to actually create a video player instance and then access the video controller from another place.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
class VideoPlayerScreen extends StatefulWidget {
VideoPlayerScreen({Key key}) : super(key: key);
final VideoPlayerScreenState videoState = new VideoPlayerScreenState();
#override
VideoPlayerScreenState createState() => VideoPlayerScreenState();
}
class VideoPlayerScreenState extends State<VideoPlayerScreen> {
VideoPlayerController controller;
Future<void> initializeVideoPlayerFuture;
#override
void initState() {
// Create and store the VideoPlayerController. The VideoPlayerController
// offers several different constructors to play videos from assets, files,
// or the internet.
controller = VideoPlayerController.network('https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4',
);
// Initialize the controller and store the Future for later use
initializeVideoPlayerFuture = controller.initialize();
// Use the controller to loop the video
controller.setLooping(true);
super.initState();
}
#override
void dispose() {
// Ensure you dispose the VideoPlayerController to free up resources
controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Container(
// Use a FutureBuilder to display a loading spinner while you wait for the
// VideoPlayerController to finish initializing.
child: FutureBuilder(
future: initializeVideoPlayerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// If the VideoPlayerController has finished initialization, use
// the data it provides to limit the Aspect Ratio of the Video
return AspectRatio(
aspectRatio: controller.value.aspectRatio,
// Use the VideoPlayer widget to display the video
child: VideoPlayer(controller),
);
} else {
// If the VideoPlayerController is still initializing, show a
// loading spinner
return Center(child: CircularProgressIndicator());
}
},
),
);
}
}
//this is the button I'm calling from the app.dart file
Widget playPauseButton(VideoPlayerScreen videoPlayer){
return IconButton(
alignment: Alignment.center,
onPressed: (){
// Wrap the play or pause in a call to `setState`. This ensures the
// correct icon is shown
setState(() {
// If the video is playing, pause it.
if (videoPlayer.videoState.controller.value.isPlaying) {
videoPlayer.videoState.controller.pause();
} else {
// If the video is paused, play it
videoPlayer.videoState.controller.play();
}
});
},
icon: Icon(videoPlayer.videoState.controller.value.isPlaying ? Icons.pause: Icons.play_arrow),
);
}
you can create a class named VideoProvider and put a VideoPlayer widget inside there.
after that, all you need is create a parameter named controller and pass it to your VideoPlayer widget. controller should be a type of VideoPlayerController;
here is an example :
class MySpecificPage extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _MySpecificPageState();
}
}
class _MySpecificPageState extends State<MySpecificPage> {
VideoPlayerController controller;
VoidCallback listener;
#override
void initState() {
listener = () => setState(() {});
videoHandler();
super.initState();
}
void videoHandler() {
if (controller == null) {
controller = VideoPlayerController.network('https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4')
..addListener(listener)
..setVolume(0.5)
..initialize();
} else {
if (controller.value.isPlaying) {
controller.pause();
} else {
controller.play();
}
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Videop Provider Example'),
),
body:Container(
child: Column(
children: <Widget>[
VideoProvider(controller),
RaisedButton(
child: Text('click here to play & puase the video'),
onPressed: () {
videoHandler();
},
)
],
),
),
);
}
}
class VideoProvider extends StatelessWidget {
final VideoPlayerController controller;
VideoProvider(this.controller);
#override
Widget build(BuildContext context) {
return AspectRatio(
aspectRatio: 16 / 9,
child: VideoPlayer(
controller
),
);
}
}
Related
I was trying to make a videoplayer that can be paused by tapping the screen (like YouTube Short)
but I was having a tough time working with Provider as I'm still new to it I was unable to access methods in VideoPlayerScreen so I decided to make a VideoPlayerProvider class so I can update the URL attribute inside it through other classes but I'm getting the ProviderNotFound Exception
Can someone guide me what am I doing wrong here? Any Resources for learning provider in depth would be helpful too, Thanks in Advance.
Apologies if I was unable to frame my question properly
`
import 'dart:async';
import 'package:provider/provider.dart';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
void main() => runApp(ChangeNotifierProvider(
create: (context) => VideoPlayerProvider(), child: const VideoPlayerApp()));
class VideoPlayerProvider extends ChangeNotifier {
String url =
'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4';
late VideoPlayerController _controller = VideoPlayerController.network(url);
String get getUrl => url;
VideoPlayerController get getController => _controller;
void newVid(String newUrl) {
url = newUrl;
notifyListeners();
}
void pp() {
if (_controller.value.isPlaying) {
_controller.pause();
} else {
_controller.play();
}
notifyListeners();
}
}
class VideoPlayerApp extends StatelessWidget {
const VideoPlayerApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Video Player Demo',
home: Stack(children: [ VideoPlayerScreen()]),
);
}
}
class VideoPlayerScreen extends StatefulWidget{
const VideoPlayerScreen({super.key});
#override
State<VideoPlayerScreen> createState() => _VideoPlayerScreenState();
}
class _VideoPlayerScreenState extends State<VideoPlayerScreen>{
late VideoPlayerController _controller =
context.watch<VideoPlayerProvider>().getController;
late Future<void> _initializeVideoPlayerFuture;
late String _url = context.watch<VideoPlayerProvider>().getUrl;
#override
void initState() {
super.initState();
_controller = VideoPlayerController.network(_url);
_initializeVideoPlayerFuture = _controller.initialize();
_controller.setLooping(true);
_controller.play();
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder(
future: _initializeVideoPlayerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return AspectRatio(
aspectRatio: 9 / 18.45,
child: VideoPlayer(_controller),
);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
},
),
);
}
}
`
I was trying to update the URL of VideoPlayerScreen So I can update it from external methods
Your code contained redundant initialization of variables and improper usage of the Provider. For a better understanding, you are suggested to go back to the documentation and examples of the Provider package.
However, I've removed all the redundancy from the code and tried to present a better usage of the Provider to you.
Revised code has been pasted below. I've tested it with the latest versions of the VideoPlayer and Provider packages and it is working perfectly fine.
I've mentioned step wise detailed comments inside the code for you to understand what changes have been made and why. Some bonus steps have also been added and explained therein.
You would notice that the provider is being fully used to initialize the controller and play, pause and change the video.
Remember, there can be better ways of achieving this; however, for simplicity and relevance, your code has been modified wherever necessary, in order to achieve the required objective.
void main() => runApp(ChangeNotifierProvider(
create: (context) => VideoPlayerProvider(), child: const VideoPlayerApp()));
class VideoPlayerProvider extends ChangeNotifier {
String url =
'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4';
late VideoPlayerController _controller;
/// STEP 1
/// Defined this async method for use in the FutureBuilder. It contains the
/// code required to initialize the controller and play the video.
Future<void> initializeController() async {
_controller = VideoPlayerController.network(url);
await _controller.initialize();
await _controller.setLooping(true);
return _controller.play();
}
String get getUrl => url;
VideoPlayerController get controller => _controller;
/// BONUS STEP 3
/// Removed the unnecessary notifyListeners() method and instead called
/// initializeController() in order to load and play the new video.
void newVid(String newUrl) {
url = newUrl;
initializeController();
// notifyListeners();
}
/// BONUS STEP 2
/// Removed the unnecessary notifyListeners() method.
/// Since we are using the same instance of controller inside the widget, we
/// don't need to define and notify the listeners
void pp() {
if (_controller.value.isPlaying) {
_controller.pause();
} else {
_controller.play();
}
// notifyListeners();
}
}
class VideoPlayerApp extends StatelessWidget {
const VideoPlayerApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Video Player Demo',
home: Stack(children: const [VideoPlayerScreen()]),
);
}
}
class VideoPlayerScreen extends StatefulWidget {
const VideoPlayerScreen({super.key});
#override
State<VideoPlayerScreen> createState() => _VideoPlayerScreenState();
}
class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
late VideoPlayerProvider provider;
/// STEP 4
/// Used the same instance of controller as initialized in the provider
VideoPlayerController get controller => provider.controller;
#override
void initState() {
super.initState();
/// STEP 2
/// Lazy initialized the provider variable, for later use in the app
provider = Provider.of<VideoPlayerProvider>(context, listen: false);
/// STEP 3
/// Removed all redundant code for initializing the controller
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder(
/// STEP 5
/// Used the provider's async method here instead of creating a new
/// redundant one here
future: provider.initializeController(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return AspectRatio(
aspectRatio: 9 / 18.45,
/// BONUS STEP 1
/// Used a GestureDetector widget to listen to screen taps and
/// called the pp() toggle method of the provider.
child: GestureDetector(
onTap: () => provider.pp(),
child: VideoPlayer(controller),
),
);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
},
),
);
}
}
Hope it helps!
I am able to load the video initially but when I setState to change the youtube link on tap it doesn't work, don't know why. what is the approach to changing the video on button press?
I am using the Pod Player plugin.
Just like Load Video Button Functionality in this image
import 'package:flutter/material.dart';
import 'package:pod_player/pod_player.dart';
class VideoPlayer extends StatefulWidget {
const VideoPlayer({Key? key}) : super(key: key);
#override
State<VideoPlayer> createState() => _VideoPlayerState();
}
class _VideoPlayerState extends State<VideoPlayer> {
String YTLink = "https://youtu.be/A3ltMaM6noM";
late final PodPlayerController controller;
#override
void initState() {
controller = PodPlayerController(
playVideoFrom: PlayVideoFrom.youtube(YTLink),
)..initialise();
super.initState();
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: ListView(
children: [
PodVideoPlayer(controller: controller),
OutlinedButton(
onPressed: () {
setState(() {
YTLink =
"https://www.youtube.com/watch?v=Q98aCklzCBE&ab_channel=DWDocumentary";
});
},
child: Text("Play Another Video")),
OutlinedButton(
onPressed: () {
setState(() {
YTLink =
"https://www.youtube.com/watch?v=AnYsa_c4GxU&ab_channel=FreeDocumentary";
});
},
child: Text("Play Another Video 2")),
],
)),
);
}
}
Instead of using setState, use controllers changeVideo method.
Add this to onPressed of Button:
//1
`controller.changeVideo(
playVideoFrom: PlayVideoFrom.youtube(
"https://www.youtube.com/watch?v=Q98aCklzCBE&ab_channel=DWDocumentary"));`
//2
`controller.changeVideo(
playVideoFrom: PlayVideoFrom.youtube(
"https://www.youtube.com/watch?v=AnYsa_c4GxU&ab_channel=FreeDocumentary"));`
I am using the Flutter Video_Player plugin and am noticing some issues when I want to fast forward 10 seconds, so want to check if I am using the correct code.
What I am experiencing is that is takes a long time, to fast forward the play, if this happens then the tendency is to press fast forward again, and If I press it several times then i notice that the sound either is not in sync or can't be heard any longer.
Here is my code:
GestureDetector(
onTap: () async {
print('FORWARD 10 SECS');
await _controller.seekTo(Duration(
seconds:
_controller.value.position.inSeconds + 10));
},
I'd really appreciate it if I can get some help with this as the app I am working on is video focused so these controls do have to work correctly.
Thank you so much for any help with this. If you have any questions please let me know.
You don't need to await seekTo(), here is working code:
Check the complete code, hope it can help :)
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
void main() => runApp(const VideoPlayerApp());
class VideoPlayerApp extends StatelessWidget {
const VideoPlayerApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Video Player Demo',
home: VideoPlayerScreen(),
);
}
}
class VideoPlayerScreen extends StatefulWidget {
const VideoPlayerScreen({Key? key}) : super(key: key);
#override
_VideoPlayerScreenState createState() => _VideoPlayerScreenState();
}
class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
late VideoPlayerController _controller;
late Future<void> _initializeVideoPlayerFuture;
#override
void initState() {
// Create and store the VideoPlayerController. The VideoPlayerController
// offers several different constructors to play videos from assets, files,
// or the internet.
_controller = VideoPlayerController.network(
'https://media.w3.org/2010/05/sintel/trailer.mp4',
);
// Initialize the controller and store the Future for later use.
_initializeVideoPlayerFuture = _controller.initialize();
// Use the controller to loop the video.
_controller.setLooping(true);
super.initState();
_controller.play();
}
#override
void dispose() {
// Ensure disposing of the VideoPlayerController to free up resources.
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Video'),
),
// Use a FutureBuilder to display a loading spinner while waiting for the
// VideoPlayerController to finish initializing.
body: FutureBuilder(
future: _initializeVideoPlayerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// If the VideoPlayerController has finished initialization, use
// the data it provides to limit the aspect ratio of the video.
return AspectRatio(
aspectRatio: _controller.value.aspectRatio,
// Use the VideoPlayer widget to display the video.
child: VideoPlayer(_controller),
);
} else {
// If the VideoPlayerController is still initializing, show a
// loading spinner.
return const Center(
child: CircularProgressIndicator(),
);
}
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Duration currentPosition = _controller.value.position;
Duration targetPosition = currentPosition + const Duration(seconds: 10);
_controller.seekTo(targetPosition);
},
child: const Icon(
Icons.arrow_forward,
),
),
);
}
}
According to this git link. I think you don't need to add await _controller.seekTo(Duration(seconds:_controller.value.position.inSeconds + 10). Instead add this await _controller.seekTo((await _controller.position)! + Duration(seconds: 10));. Not sure if setState is neccesory.
I am getting an exception thrown while using a back button after disposing of my VideoPlayerController.
I have my VideoPlayer and VideoPlayerController set up like this:
String url;
var plan;
_VideoPlayerScreenState(this.url,{this.plan});
Future<Null> OnWillPop(){
_controller.dispose();
if(plan!=null)
Navigator.push(context, MaterialPageRoute(builder: (context)=>
ListSession(plan :plan)));
else
Navigator.push(context, MaterialPageRoute(builder: (context)=>
ListMoves()));
}
VideoPlayerController _controller;
Future<void> _initializeVideoPlayerFuture;
#override
void initState() {
_controller = VideoPlayerController.network(
url,
);
// Initialize the controller and store the Future for later use.
_initializeVideoPlayerFuture = _controller.initialize();
// Use the controller to loop the video.
_controller.setLooping(true);
_controller.play();
super.initState();
}
#override
void dispose() {
print("+++++++++++++++++++++++++++++++++++++++++++");
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return WillPopScope(onWillPop: OnWillPop,child:Scaffold(
// Use a FutureBuilder to display a loading spinner while waiting for the
// VideoPlayerController to finish initializing.
body: FutureBuilder(
future: _initializeVideoPlayerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// If the VideoPlayerController has finished initialization, use
// the data it provides to limit the aspect ratio of the video.
return Center(
child: AspectRatio(
aspectRatio: _controller.value.aspectRatio,
// Use the VideoPlayer widget to display the video.
child: VideoPlayer(_controller),
),
);
} else {
// If the VideoPlayerController is still initializing, show a
// loading spinner.
return Center(child: CircularProgressIndicator());
}
},
),
));
}
but when I press the back button, I get this error:
Another exception was thrown: A VideoPlayerController was used after being disposed.
How do I properly dispose of my VideoPlayerController and be able to incorporate the back button?
You can copy paste run full code below
and mark unmark Navigator.push / Navigator.pushReplacement to check effect
In your case, you do not need to dispose of controller, because controller is local to this page, you can just do _controller.pause()
You use Navigator.push go to next page means you will pop from next page
If you dispose controller and set controller to null successfully, when pop from next page, you will get an error because initState will not be called again, controller will not init again
If you use Navigator.pushReplacement, dispose will be called automatically,
You can see console show _controller.dispose in demo code.
working demo
you can see when back from ListMove page, video still can play
full code
import 'dart:async';
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(
title: 'Video Player Demo',
home: VideoPlayerScreen(),
);
}
}
class VideoPlayerScreen extends StatefulWidget {
VideoPlayerScreen({Key key}) : super(key: key);
#override
_VideoPlayerScreenState createState() => _VideoPlayerScreenState();
}
class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
VideoPlayerController _controller;
VideoPlayerController _oldController;
Future<void> _initializeVideoPlayerFuture;
#override
void initState() {
print("initState");
// Create and store the VideoPlayerController. The VideoPlayerController
// offers several different constructors to play videos from assets, files,
// or the internet.
_controller = VideoPlayerController.network(
'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4',
);
// Initialize the controller and store the Future for later use.
_initializeVideoPlayerFuture = _controller.initialize();
// Use the controller to loop the video.
_controller.setLooping(true);
super.initState();
}
#override
void dispose() {
print("_controller.dispose");
// Ensure disposing of the VideoPlayerController to free up resources.
//_initializeVideoPlayerFuture = null;
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
await _controller.pause();
Navigator.push(
context, MaterialPageRoute(builder: (context) => ListMoves()));
/*Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => ListMoves()));*/
},
child: Scaffold(
appBar: AppBar(
title: Text('Butterfly Video'),
),
// Use a FutureBuilder to display a loading spinner while waiting for the
// VideoPlayerController to finish initializing.
body: FutureBuilder(
future: _initializeVideoPlayerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// If the VideoPlayerController has finished initialization, use
// the data it provides to limit the aspect ratio of the video.
return AspectRatio(
aspectRatio: _controller.value.aspectRatio,
// Use the VideoPlayer widget to display the video.
child: VideoPlayer(_controller),
);
} else {
// If the VideoPlayerController is still initializing, show a
// loading spinner.
return Center(child: CircularProgressIndicator());
}
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// Wrap the play or pause in a call to `setState`. This ensures the
// correct icon is shown.
setState(() {
// If the video is playing, pause it.
if (_controller.value.isPlaying) {
_controller.pause();
} else {
// If the video is paused, play it.
_controller.play();
}
});
},
// Display the correct icon depending on the state of the player.
child: Icon(
_controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
),
), // This trailing comma makes auto-formatting nicer for build methods.
),
);
}
}
class ListMoves extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('List Movies'),
),
body: Center(
child: RaisedButton(
child: Text('Launch screen'),
onPressed: () {},
),
),
);
}
}
I am working on modifying the image_picker plugin for flutter. I have everything working accept when I return the data back to the flutter app I need help to figure out how to display the video back the user similar to how I would using Image.file for a picture. Then they can click to upload and when I retrieve need to play it, looked at the video_player plugin, but really only care to have them use the default platform player, but if I can get it to work then the plugin is fine, but no luck so far even seeing the video. The data returned from the image_picker plugin is a File, I determine that its not a image and go from there.
Any assistance would be great and I can show any code if it helps.
Thanks
Good thing that the image_picker is picking videos now.
If you'll run the sample app this is how it looks:
And here is another example where you can play and pause the video that you've uploaded from your local files using the image_picker and playing it using video_player as recommended in the Flutter documentation.
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:video_player/video_player.dart';
void main() => runApp(VideoPlayerApp());
class VideoPlayerApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Video Player Demo',
home: VideoPlayerScreen(),
);
}
}
class VideoPlayerScreen extends StatefulWidget {
VideoPlayerScreen({Key key}) : super(key: key);
#override
_VideoPlayerScreenState createState() => _VideoPlayerScreenState();
}
class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
VideoPlayerController _controller;
Future<void> _initializeVideoPlayerFuture;
File videoFile;
#override
void initState() {
// Create and store the VideoPlayerController. The VideoPlayerController
// offers several different constructors to play videos from assets, files,
super.initState();
}
#override
void dispose() {
// Ensure disposing of the VideoPlayerController to free up resources.
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Sample Video Player Demo'),
),
// Use a FutureBuilder to display a loading spinner while waiting for the
// VideoPlayerController to finish initializing.
body: Column(
children: <Widget>[
Visibility(
visible: _controller != null,
child: FutureBuilder(
future: _initializeVideoPlayerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// If the VideoPlayerController has finished initialization, use
// the data it provides to limit the aspect ratio of the video.
return AspectRatio(
aspectRatio: _controller.value.aspectRatio,
// Use the VideoPlayer widget to display the video.
child: VideoPlayer(_controller),
);
} else {
// If the VideoPlayerController is still initializing, show a
// loading spinner.
return Center(child: CircularProgressIndicator());
}
},
),
),
Center(
child: MaterialButton(
hoverColor: Colors.blue,
child: Text("Upload Video"),
onPressed: () {
getVideo();
},
),
),
],
),
floatingActionButton: _controller == null
? null
: FloatingActionButton(
onPressed: () {
// Wrap the play or pause in a call to `setState`. This ensures the
// correct icon is shown.
setState(() {
// If the video is playing, pause it.
if (_controller.value.isPlaying) {
_controller.pause();
} else {
// If the video is paused, play it.
_controller.play();
}
});
},
// Display the correct icon depending on the state of the player.
child: Icon(
_controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
Future getVideo() async {
var picker;
Future<File> _videoFile =
ImagePicker.pickVideo(source: ImageSource.gallery);
_videoFile.then((file) async {
setState(() {
videoFile = file;
_controller = VideoPlayerController.file(videoFile);
// Initialize the controller and store the Future for later use.
_initializeVideoPlayerFuture = _controller.initialize();
// Use the controller to loop the video.
_controller.setLooping(true);
});
});
}
}
Actual output: