Unable to display video in flutter without overflow using video_player package - flutter

I'm having a hard time displaying a video using the video_player package. I'm new to flutter and am trying to create a simple website with a title, some text, and a local video displayed in the center of the screen with a title. The video is local and is in an assets folder, and I have also added the video_player and video location to the pubspec.yaml file. Any advice or suggestions are appreciated, I would like to improve at this language. Below is the code I have put together so far. Thanks!
import 'package:video_player/video_player.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Center(
child: Text(
"My Website",
textScaleFactor: 2,
style: TextStyle(color: Colors.white),
),
),
),
body: Column(
children: [
MyHomePage(),
],
),
),
);
}
}
MyHomePage class:
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
#override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(32),
child: Row(
children: [
Expanded(
/*1*/
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
/*2*/
Container(
padding: const EdgeInsets.only(bottom: 8),
child: Center(
child: Text(
'More photos & videos coming soon',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
),
Container(
padding: const EdgeInsets.only(bottom: 8),
child: Center(child: BackgroundVideo()),
),
],
),
),
],
),
);
}
}
Stateful video player that I would like to embed in the home page:
//need to ensure this video fits on the screen and doesn't overflow the bottom.
class BackgroundVideo extends StatefulWidget {
const BackgroundVideo({super.key});
#override
_BackgroundVideoState createState() => _BackgroundVideoState();
}
class _BackgroundVideoState extends State<BackgroundVideo> {
late VideoPlayerController _controller;
late Future<void> _initializeBackgroundVideoFuture;
#override
void initState() {
super.initState();
//Create and store the BackgroundVideoController.
_controller = VideoPlayerController.asset(
"build\assets\welcomescreen.mp4",
);
_initializeBackgroundVideoFuture = _controller.initialize();
_controller.setLooping(true);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('First Video'),
),
// Use a FutureBuilder to display a loading spinner while waiting for the
// VideoPlayerController to finish initializing.
body: FutureBuilder(
future: _initializeBackgroundVideoFuture,
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: () {
// 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,
),
),
);
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
}

Related

StreamBuilder stuck in connectionState.waiting in Flutter

I am trying to create a todo list application, i used Streambuilder to show list of Streams.
it is a simple application there is a button to add new task it is a floatingActionButton and a StreamController to manage the data, and have a TabBar with two tabs first and second so the StreamBuilder is in the first tab and other tab just contain a string in the center for now.
I can add tasks to the StreamController perfectly, but there is two issues:
1- when the program runs StreamBuilder stuck in ConnectionSatate.waiting if the Stream is null.
2- when i click second tab and came back to first tab the it also stuck in ConnectionSatate.waiting even my stream has data in it, and when i click add button to add new data it shows the data and the new one again.
here is my whole code:
import 'dart:async';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final StreamController<List<String>> streamController =
StreamController<List<String>>.broadcast();
List<String> list = [];
#override
void initState() {
super.initState();
}
#override
void dispose() {
streamController.close();
super.dispose();
}
int i = 0;
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
bottom: PreferredSize(
preferredSize: Size.fromHeight(0),
child: Container(
height: 30,
width: MediaQuery.of(context).size.width,
child: TabBar(
labelColor: Theme.of(context).iconTheme.color,
indicatorColor: Colors.green.shade600,
tabs: [
Tab(text: 'first'),
Tab(text: 'second'),
]),
),
),
),
body: TabBarView(children: [
tasks(),
Center(
child: Text('SECOND TAB'),
)
]),
floatingActionButton: TextButton(
onPressed: () {
list.add('data ${++i}');
streamController.sink.add(list);
},
child: Icon(
Icons.add,
)),
),
);
}
Padding tasks() {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 13, vertical: 5),
child: Column(
children: [
Expanded(
child: StreamBuilder(
stream: streamController.stream,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
}
if (!snapshot.hasData) {
return const Center(
child: Text('There is no data'),
);
}
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, index) => Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
snapshot.data![index],
style: const TextStyle(
fontSize: 25,
),
),
));
})),
],
),
);
}
}
here is a video of my problem
I tried without StreamController but when i came back to first tab it shows the error that i can't listen to a Stream multiple times.
here is the answer, you need to use AutomaticKeepAliveClientMixin
I wrote a demo code sample for you https://dartpad.dartlang.org/?id=52e8e2ef8bad97f21dc91fa420dcec0e

Flutter Web on Safari: Videos behave inconsistent (some start playing even when paused, some don't)

When trying to play two (or more) videos in Safari, the first video requires user interaction to play, so I added a play button. Then, when the next video widget appears, the video will start automatically even if the video controller was paused. Now the button shows the play icon but the video is already playing... How can I fix this?
Also it looks like the controller of the second video didn't add the listener since no print statement is executed (until the button is pressed).
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
void main() => runApp(const VideoDemo());
class VideoDemo extends StatelessWidget {
const VideoDemo({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
bottom: const TabBar(
tabs: [
Tab(icon: Icon(Icons.first_page)),
Tab(icon: Icon(Icons.last_page)),
],
),
title: const Text('Video Demo'),
),
body: const TabBarView(
children: [
VideoWidget(),
VideoWidget(),
],
),
),
),
);
}
}
class VideoWidget extends StatefulWidget {
const VideoWidget({Key? key}) : super(key: key);
#override
_VideoWidgetState createState() => _VideoWidgetState();
}
class _VideoWidgetState extends State<VideoWidget> {
late VideoPlayerController _controller;
bool hasLoaded = false;
#override
void initState() {
super.initState();
_controller = VideoPlayerController.network(
'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4')
..setLooping(true)
..addListener(videoListener)
..initialize().then((_) {
setState(() {
hasLoaded = true;
});
})
..pause(); // <-- PAUSE the video
}
#override
Widget build(BuildContext context) => Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.red,
child: Stack(
alignment: Alignment.center,
children: [
_controller.value.isInitialized
? VideoPlayer(_controller)
: const Center(child: CircularProgressIndicator()),
SizedBox(
height: 50,
width: 130,
child: ElevatedButton(
onPressed: () {
setState(() {
_controller.value.isPlaying
? _controller.pause()
: _controller.play();
});
},
child: Icon(
_controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
),
)),
],
));
void videoListener() { // <-- Listener does not fire on second video until play button is pressed
if (hasLoaded) {
print("isPlaying: ${_controller.value.isPlaying}");
}
}
#override
void dispose() {
super.dispose();
_controller.dispose();
}
}

Watch YouTube video with youtube_player_iframe Flutter

I would like to know how to open a YouTube video and showing it on my Flutter app with a video player that allow the user to stop the video, moving forward, backward just dragging the finger on the bottom line of the video.
I was thinking to use youtube_player_iframe since I read on the internet that this is the only widget that allows to open YouTube videos (for iOS, youtube_player for Android) so I installed it and copy-pasted the example from docs and fixed some errors.
If anyone could help me to understand why it doesn't work I'll be very glad.
To install, from terminal run : flutter pub add youtube_player_iframe
Or just add the dependence : youtube_player_iframe: ^2.0.0
This is the code, just copy-paste and it can be run :
import 'dart:developer';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:youtube_player_iframe/youtube_player_iframe.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(YoutubeApp());
}
///
class YoutubeApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Youtube Player IFrame Demo',
theme: ThemeData(
primarySwatch: Colors.deepPurple,
iconTheme: const IconThemeData(color: Colors.deepPurpleAccent),
),
debugShowCheckedModeBanner: false,
home: YoutubeAppDemo(),
);
}
}
///
class YoutubeAppDemo extends StatefulWidget {
#override
_YoutubeAppDemoState createState() => _YoutubeAppDemoState();
}
class _YoutubeAppDemoState extends State<YoutubeAppDemo> {
late YoutubePlayerController _controller;
String urlVideoFromYouTube = 'v0RWej7Sqg4'; //this is the last part of the YouTube url https://www.youtube.com/watch?v=v0RWej7Sqg4 copy-pasted by me
#override
void initState() {
super.initState();
_controller = YoutubePlayerController(
initialVideoId: urlVideoFromYouTube,
params: const YoutubePlayerParams(
playlist: [
'nPt8bK2gbaU',//Default playlist
'K18cpp_-gP8',
'iLnmTe5Q2Qw',
'_WoCV4c6XOE',
'KmzdUe0RSJo',
'6jZDSSZZxjQ',
'p2lYr3vM_1w',
'7QUtEmBT_-w',
'34_PXCzGw1M',
],
startAt: const Duration(minutes: 1, seconds: 36),
showControls: true,
showFullscreenButton: true,
desktopMode: true,
privacyEnhanced: true,
useHybridComposition: true,
),
);
_controller.onEnterFullscreen = () {
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight,
]);
log('Entered Fullscreen');
};
_controller.onExitFullscreen = () {
log('Exited Fullscreen');
};
}
#override
Widget build(BuildContext context) {
const player = YoutubePlayerIFrame();
return YoutubePlayerControllerProvider(
// Passing controller to widgets below.
controller: _controller,
child: Scaffold(
appBar: AppBar(
title: const Text('Youtube Player IFrame'),
),
body: LayoutBuilder(
builder: (context, constraints) {
if (kIsWeb && constraints.maxWidth > 800) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Expanded(child: player),
const SizedBox(
width: 500,
child: SingleChildScrollView(
child: Controls(),
),
),
],
);
}
return ListView(
children: [
player,
const Controls(),
],
);
},
),
),
);
}
#override
void dispose() {
_controller.close();
super.dispose();
}
}
///
class Controls extends StatelessWidget {
///
const Controls();
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// _space,
// MetaDataSection(),
// _space,
// SourceInputSection(),
// _space,
// PlayPauseButtonBar(),
// _space,
// VolumeSlider(),
// _space,
// PlayerStateSection(),
],
),
);
}
Widget get _space => const SizedBox(height: 10);
}
Here's the link to that repository: https://pub.dev/packages/youtube_player_iframe, download it fully and run it's main.dart file using VS code or android studio, You can't run just a main.dart file without the other files for this plugin to work.Doing this, will give you an idea of how to run this plugin.

Change size/position of Text relative to other Widget

Can anyone help?
Currently, the Text that I am displaying over a video has a fixed size and position.
I'm wondering how I can change this dynamically/responsively to match the size of its parent widget (the Video).
I tried a method using a GlobalKey but got an error, I think it's because the video hadn't loaded..
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
drawer: ResponsiveLayout.isSmallScreen(context) ? NavDrawer() : null,
body: Container(
child: SingleChildScrollView(
child: Column(
children: <Widget>[
NavBar(),
Body(),
Footer(),
],
),
),
),
);
}
}
class Body extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ResponsiveLayout(
largeScreen: LargeScreen(),
mediumScreen: LargeScreen(),
smallScreen: LargeScreen(),
);
}
}
class LargeScreen extends StatefulWidget {
#override
_LargeScreenState createState() => _LargeScreenState();
}
class _LargeScreenState extends State<LargeScreen> {
VideoPlayerController _videoPlayerController;
Future<void> _initializeVideoPlayerFuture;
#override
void initState() {
_videoPlayerController = VideoPlayerController.asset(
'assets/videos/video.mp4',
);
_initializeVideoPlayerFuture = _videoPlayerController.initialize();
super.initState();
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 40),
child: Column(
children: <Widget>[
FutureBuilder(
future: _initializeVideoPlayerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
!_videoPlayerController.value.isBuffering) {
// If the VideoPlayerController has finished initialization, use
// the data it provides to limit the aspect ratio of the VideoPlayer.
return AspectRatio(
aspectRatio: _videoPlayerController.value.aspectRatio,
// Use the VideoPlayer widget to display the video.
child: Stack(
children: <Widget>[
VideoPlayer(_videoPlayerController),
Positioned(
bottom: 20,
left: 20,
child: FittedBox(
child: Text(
'Text over\na video',
style: TextStyle(
color: Colors.white,
fontSize:50),
),
),
)
],
),
);
} else {
// If the VideoPlayerController is still initializing, show a
// loading spinner.
return Center(child: CircularProgressIndicator());
}
},
),
],
),
);
}
#override
void dispose() {
super.dispose();
_videoPlayerController.dispose();
}
}
LayoutBuilder can provide you with width and height properties which corresponds to the currently available space. Check this documentation here. It provides the builder with a BoxConstraints instance as in here. You can use this information to size your text.
Check the Align widget. It can place the child on specific location within the parent widget's coordinate system. In your case it will be on the coordinates of the Stack widget.
I would try something like the following.
Wrap the Text widget inside a Align widget and use FractionalOffset to place align the widget. You can directly use the Alignment instance also. The origin will vary vary for both the approach. Check the docs here
Then Wrap my Align widget inside a LayoutBuilder widget to get the available size and decide my font size based on it. Something like fontSize: constraints.maxWidth / 25
Below is sample working code.
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
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',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
// drawer: ResponsiveLayout.isSmallScreen(context) ? NavDrawer() : null,
body: Container(
child: SingleChildScrollView(
child: Column(
children: <Widget>[
// NavBar(),
Body(),
// Footer(),
],
),
),
),
);
}
}
class Body extends StatelessWidget {
#override
Widget build(BuildContext context) {
// return ResponsiveLayout(
// largeScreen: LargeScreen(),
// mediumScreen: LargeScreen(),
// smallScreen: LargeScreen(),
// );
return LargeScreen();
}
}
class LargeScreen extends StatefulWidget {
#override
_LargeScreenState createState() => _LargeScreenState();
}
class _LargeScreenState extends State<LargeScreen> {
VideoPlayerController _videoPlayerController;
Future<void> _initializeVideoPlayerFuture;
#override
void initState() {
_videoPlayerController = VideoPlayerController.network(
'http://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4',
);
_initializeVideoPlayerFuture =
_videoPlayerController.initialize().then((onValue) {
setState(() {});
});
super.initState();
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 40),
child: Column(
children: <Widget>[
FutureBuilder(
future: _initializeVideoPlayerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
!_videoPlayerController.value.isBuffering) {
// If the VideoPlayerController has finished initialization, use
// the data it provides to limit the aspect ratio of the VideoPlayer.
return AspectRatio(
aspectRatio: _videoPlayerController.value.aspectRatio,
// Use the VideoPlayer widget to display the video.
child: Stack(
children: <Widget>[
VideoPlayer(_videoPlayerController),
LayoutBuilder(
builder: (context, constraints) {
return Align(
// this decides the position of the text.
alignment: FractionalOffset(0.05, 0.95),
child: FittedBox(
child: Text(
'Text over\na video',
style: TextStyle(
color: Colors.white,
// here font size is ratio of the maxwidth available for this widget.
fontSize: constraints.maxWidth / 25,
),
),
),
);
},
)
],
),
);
} else {
// If the VideoPlayerController is still initializing, show a
// loading spinner.
return Center(child: CircularProgressIndicator());
}
},
),
FloatingActionButton(
onPressed: () {
setState(() {
_videoPlayerController.value.isPlaying
? _videoPlayerController.pause()
: _videoPlayerController.play();
});
},
child: Icon(
_videoPlayerController.value.isPlaying
? Icons.pause
: Icons.play_arrow,
),
),
],
),
);
}
#override
void dispose() {
super.dispose();
_videoPlayerController.dispose();
}
}
It's easily accessible via MediaQuery.of(context).size (Documentation).
Remember that you have to call inside your build method since it demands the context

How to upload a video from gallery in flutter

I am building an app when a user clicks the button, it goes to gallery and select any of the video in gallery and then returns back to the main screen in app and plays the video automatically. Below is code i have tried.
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Image App Demo',
theme: ThemeData(
primaryColor: Color(0xff476cfb),
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
File _imageFile;
Future getVideo() async{
File image;
image=await ImagePicker.pickVideo(source: ImageSource.gallery);
setState(() {
_imageFile=image;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Image Upload"),
),
body: ListView(
children: <Widget>[
Center(
child: Column(
children: <Widget>[
SizedBox(height: 10.0,),
RaisedButton(
child: Text("Video"),
onPressed: (){
getVideo();
},
),
],
),
)
],
}
Display video using video player
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('Butterfly Video'),
),
// 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());
}
},
),
),
RaisedButton(
child: Text("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 {
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);
});
});
}
}
you can use this widget from image_picker
answer based n image_picker example
Widget _previewVideo() {
final Text retrieveError = _getRetrieveErrorWidget();
if (retrieveError != null) {
return retrieveError;
}
if (_controller == null) {
return const Text(
'You have not yet picked a video',
textAlign: TextAlign.center,
);
}
return Padding(
padding: const EdgeInsets.all(10.0),
child: AspectRatioVideo(_controller),
);
}
//how to pass video to preview
Center(
child: Platform.isAndroid
? FutureBuilder<void>(
future: retrieveLostData(),
builder: (BuildContext context, AsyncSnapshot<void> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
case ConnectionState.waiting:
return const Text(
'You have not yet picked an image.',
textAlign: TextAlign.center,
);
case ConnectionState.done:
return isVideo ? _previewVideo() : _previewImage();
default:
if (snapshot.hasError) {
return Text(
'Pick image/video error: ${snapshot.error}}',
textAlign: TextAlign.center,
);
} else {
return const Text(
'You have not yet picked an image.',
textAlign: TextAlign.center,
);
}
}
},
)
: (isVideo ? _previewVideo() : _previewImage()),
),