| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| 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(new MyApp()); |
| } |
| |
| class MyApp extends StatelessWidget { |
| @override |
| Widget build(BuildContext context) { |
| return new MaterialApp( |
| title: 'Image Picker Demo', |
| home: new MyHomePage(title: 'Image Picker Example'), |
| ); |
| } |
| } |
| |
| class MyHomePage extends StatefulWidget { |
| MyHomePage({Key key, this.title}) : super(key: key); |
| |
| final String title; |
| |
| @override |
| _MyHomePageState createState() => new _MyHomePageState(); |
| } |
| |
| class _MyHomePageState extends State<MyHomePage> { |
| Future<File> _imageFile; |
| bool isVideo = false; |
| VideoPlayerController _controller; |
| VoidCallback listener; |
| |
| void _onImageButtonPressed(ImageSource source) { |
| setState(() { |
| if (_controller != null) { |
| _controller.setVolume(0.0); |
| _controller.removeListener(listener); |
| } |
| if (isVideo) { |
| ImagePicker.pickVideo(source: source).then((File file) { |
| if (file != null && mounted) { |
| setState(() { |
| _controller = VideoPlayerController.file(file) |
| ..addListener(listener) |
| ..setVolume(1.0) |
| ..initialize() |
| ..setLooping(true) |
| ..play(); |
| }); |
| } |
| }); |
| } else { |
| _imageFile = ImagePicker.pickImage(source: source); |
| } |
| }); |
| } |
| |
| @override |
| void deactivate() { |
| if (_controller != null) { |
| _controller.setVolume(0.0); |
| _controller.removeListener(listener); |
| } |
| super.deactivate(); |
| } |
| |
| @override |
| void dispose() { |
| if (_controller != null) { |
| _controller.dispose(); |
| } |
| super.dispose(); |
| } |
| |
| @override |
| void initState() { |
| super.initState(); |
| listener = () { |
| setState(() {}); |
| }; |
| } |
| |
| Widget _previewVideo(VideoPlayerController controller) { |
| if (controller == null) { |
| return const Text( |
| 'You have not yet picked a video', |
| textAlign: TextAlign.center, |
| ); |
| } else if (controller.value.initialized) { |
| return Padding( |
| padding: const EdgeInsets.all(10.0), |
| child: AspectRatioVideo(controller), |
| ); |
| } else { |
| return const Text( |
| 'Error Loading Video', |
| textAlign: TextAlign.center, |
| ); |
| } |
| } |
| |
| Widget _previewImage() { |
| return FutureBuilder<File>( |
| future: _imageFile, |
| builder: (BuildContext context, AsyncSnapshot<File> snapshot) { |
| if (snapshot.connectionState == ConnectionState.done && |
| snapshot.data != null) { |
| return Image.file(snapshot.data); |
| } else if (snapshot.error != null) { |
| return const Text( |
| 'Error picking image.', |
| textAlign: TextAlign.center, |
| ); |
| } else { |
| return const Text( |
| 'You have not yet picked an image.', |
| textAlign: TextAlign.center, |
| ); |
| } |
| }); |
| } |
| |
| @override |
| Widget build(BuildContext context) { |
| return Scaffold( |
| appBar: AppBar( |
| title: Text(widget.title), |
| ), |
| body: Center( |
| child: isVideo ? _previewVideo(_controller) : _previewImage(), |
| ), |
| floatingActionButton: Column( |
| mainAxisAlignment: MainAxisAlignment.end, |
| children: <Widget>[ |
| FloatingActionButton( |
| onPressed: () { |
| isVideo = false; |
| _onImageButtonPressed(ImageSource.gallery); |
| }, |
| heroTag: 'image0', |
| tooltip: 'Pick Image from gallery', |
| child: const Icon(Icons.photo_library), |
| ), |
| Padding( |
| padding: const EdgeInsets.only(top: 16.0), |
| child: FloatingActionButton( |
| onPressed: () { |
| isVideo = false; |
| _onImageButtonPressed(ImageSource.camera); |
| }, |
| heroTag: 'image1', |
| tooltip: 'Take a Photo', |
| child: const Icon(Icons.camera_alt), |
| ), |
| ), |
| Padding( |
| padding: const EdgeInsets.only(top: 16.0), |
| child: FloatingActionButton( |
| backgroundColor: Colors.red, |
| onPressed: () { |
| isVideo = true; |
| _onImageButtonPressed(ImageSource.gallery); |
| }, |
| heroTag: 'video0', |
| tooltip: 'Pick Video from gallery', |
| child: const Icon(Icons.video_library), |
| ), |
| ), |
| Padding( |
| padding: const EdgeInsets.only(top: 16.0), |
| child: FloatingActionButton( |
| backgroundColor: Colors.red, |
| onPressed: () { |
| isVideo = true; |
| _onImageButtonPressed(ImageSource.camera); |
| }, |
| heroTag: 'video1', |
| tooltip: 'Take a Video', |
| child: const Icon(Icons.videocam), |
| ), |
| ), |
| ], |
| ), |
| ); |
| } |
| } |
| |
| class AspectRatioVideo extends StatefulWidget { |
| final VideoPlayerController controller; |
| |
| AspectRatioVideo(this.controller); |
| |
| @override |
| AspectRatioVideoState createState() => new AspectRatioVideoState(); |
| } |
| |
| class AspectRatioVideoState extends State<AspectRatioVideo> { |
| VideoPlayerController get controller => widget.controller; |
| bool initialized = false; |
| |
| VoidCallback listener; |
| |
| @override |
| void initState() { |
| super.initState(); |
| listener = () { |
| if (!mounted) { |
| return; |
| } |
| if (initialized != controller.value.initialized) { |
| initialized = controller.value.initialized; |
| setState(() {}); |
| } |
| }; |
| controller.addListener(listener); |
| } |
| |
| @override |
| Widget build(BuildContext context) { |
| if (initialized) { |
| final Size size = controller.value.size; |
| return new Center( |
| child: new AspectRatio( |
| aspectRatio: size.width / size.height, |
| child: new VideoPlayer(controller), |
| ), |
| ); |
| } else { |
| return new Container(); |
| } |
| } |
| } |