|
- import 'dart:io';
-
- import 'package:camera/camera.dart';
- import 'package:farm_tpf/main.dart';
- import 'package:file_picker/file_picker.dart';
- import 'package:flutter/material.dart';
- import 'package:get/get.dart';
- import 'package:thumbnails/thumbnails.dart';
- import 'package:video_player/video_player.dart';
- import 'package:path_provider/path_provider.dart';
-
- class CameraHelper extends StatefulWidget {
- @override
- _CameraHelperState createState() => _CameraHelperState();
- }
-
- /// Returns a suitable camera icon for [direction].
- IconData getCameraLensIcon(CameraLensDirection direction) {
- switch (direction) {
- case CameraLensDirection.back:
- return Icons.camera_rear;
- case CameraLensDirection.front:
- return Icons.camera_front;
- case CameraLensDirection.external:
- return Icons.camera;
- }
- throw ArgumentError('Unknown lens direction');
- }
-
- void logError(String code, String message) =>
- print('Error: $code\nError Message: $message');
-
- class _CameraHelperState extends State<CameraHelper>
- with WidgetsBindingObserver {
- CameraController controller;
- String imagePath;
- String videoPath;
- VideoPlayerController videoController;
- VoidCallback videoPlayerListener;
- bool enableAudio = true;
- int indexCamera = 0;
-
- @override
- void initState() {
- super.initState();
- controller =
- CameraController(cameras[indexCamera], ResolutionPreset.medium);
- controller.initialize().then((_) {
- if (!mounted) {
- return;
- }
- setState(() {});
- });
- WidgetsBinding.instance.addObserver(this);
- }
-
- @override
- void dispose() {
- WidgetsBinding.instance.removeObserver(this);
- super.dispose();
- }
-
- @override
- void didChangeAppLifecycleState(AppLifecycleState state) {
- // App state changed before we got the chance to initialize.
- if (controller == null || !controller.value.isInitialized) {
- return;
- }
- if (state == AppLifecycleState.inactive) {
- controller?.dispose();
- } else if (state == AppLifecycleState.resumed) {
- if (controller != null) {
- onNewCameraSelected(controller.description);
- }
- }
- }
-
- final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
-
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- key: _scaffoldKey,
- body: SafeArea(
- top: false,
- bottom: false,
- child: Column(
- children: <Widget>[
- Expanded(
- child: Container(
- child: Padding(
- padding: const EdgeInsets.all(1.0),
- child: Center(
- child: _cameraPreviewWidget(),
- ),
- ),
- decoration: BoxDecoration(
- color: Colors.black,
- border: Border.all(
- color:
- controller != null && controller.value.isRecordingVideo
- ? Colors.redAccent
- : Colors.grey,
- width:
- controller != null && controller.value.isRecordingVideo
- ? 1.0
- : 0.0,
- ),
- ),
- ),
- ),
- _captureControlRowWidget(),
- ],
- ),
- ),
- );
- }
-
- /// Display the preview from the camera (or a message if the preview is not available).
- Widget _cameraPreviewWidget() {
- if (controller == null || !controller.value.isInitialized) {
- return const Text(
- 'Đang mở camera ....',
- style: TextStyle(
- color: Colors.white,
- fontSize: 18.0,
- fontWeight: FontWeight.w900,
- ),
- );
- } else {
- return AspectRatio(
- aspectRatio: controller.value.aspectRatio,
- child: CameraPreview(controller),
- );
- }
- }
-
- /// Display the control bar with buttons to take pictures and record videos.
- Widget _captureControlRowWidget() {
- return Row(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- mainAxisSize: MainAxisSize.max,
- children: <Widget>[
- IconButton(
- icon: Icon(Icons.arrow_back),
- onPressed: () {
- Get.back();
- }),
- _cameraTogglesRowWidget(),
- IconButton(
- icon: const Icon(
- Icons.camera_alt,
- size: 30,
- ),
- color: Colors.blue,
- onPressed: controller != null &&
- controller.value.isInitialized &&
- !controller.value.isRecordingVideo
- ? onTakePictureButtonPressed
- : null,
- ),
- IconButton(
- icon: const Icon(Icons.videocam, size: 35),
- color: Colors.blue,
- onPressed: controller != null &&
- controller.value.isInitialized &&
- !controller.value.isRecordingVideo
- ? onVideoRecordButtonPressed
- : null,
- ),
- IconButton(
- icon: controller != null && controller.value.isRecordingPaused
- ? Icon(Icons.play_arrow)
- : Icon(Icons.pause),
- color: Colors.blue,
- onPressed: controller != null &&
- controller.value.isInitialized &&
- controller.value.isRecordingVideo
- ? (controller != null && controller.value.isRecordingPaused
- ? onResumeButtonPressed
- : onPauseButtonPressed)
- : null,
- ),
- IconButton(
- icon: const Icon(Icons.stop),
- color: Colors.red,
- onPressed: controller != null &&
- controller.value.isInitialized &&
- controller.value.isRecordingVideo
- ? onStopButtonPressed
- : null,
- )
- ],
- );
- }
-
- /// Display a row of toggle to select the camera (or a message if no camera is available).
- Widget _cameraTogglesRowWidget() {
- if (cameras.isEmpty) {
- return const Text('Không có camera');
- } else {
- bool disableSwitch =
- controller != null && controller.value.isRecordingVideo;
- if (indexCamera == cameras.length - 1) {
- indexCamera = 0;
- } else {
- indexCamera++;
- }
- return IconButton(
- icon: Icon(
- Icons.switch_camera,
- color: Colors.green,
- ),
- onPressed: disableSwitch == true
- ? null
- : () {
- onNewCameraSelected(cameras[indexCamera]);
- });
- }
- }
-
- String timestamp() => DateTime.now().millisecondsSinceEpoch.toString();
-
- void showInSnackBar(String message) {
- _scaffoldKey.currentState.showSnackBar(SnackBar(content: Text(message)));
- }
-
- void onNewCameraSelected(CameraDescription cameraDescription) async {
- if (controller != null) {
- await controller.dispose();
- }
- controller = CameraController(
- cameraDescription,
- ResolutionPreset.medium,
- enableAudio: enableAudio,
- );
-
- // If the controller is updated then update the UI.
- controller.addListener(() {
- if (mounted) setState(() {});
- if (controller.value.hasError) {
- showInSnackBar('Lỗi camera: ${controller.value.errorDescription}');
- }
- });
-
- try {
- await controller.initialize();
- } on CameraException catch (e) {
- _showCameraException(e);
- }
-
- if (mounted) {
- setState(() {});
- }
- }
-
- void onTakePictureButtonPressed() {
- takePicture().then((String filePath) {
- if (mounted) {
- setState(() {
- imagePath = filePath;
- videoController?.dispose();
- videoController = null;
- });
- if (filePath != null) {
- print('Picture saved to $filePath');
- Get.back(result: filePath);
- }
- }
- });
- }
-
- void onVideoRecordButtonPressed() {
- startVideoRecording().then((String filePath) {
- if (mounted) setState(() {});
- if (filePath != null) {
- print('Saving video to $filePath');
- }
- });
- }
-
- void onStopButtonPressed() {
- stopVideoRecording().then((_) {
- if (mounted) setState(() {});
- {
- print('Video recorded to: $videoPath');
- _getImage(videoPath);
- }
- });
- }
-
- _getImage(videoPathUrl) async {
- var appDocDir = await getApplicationDocumentsDirectory();
- final folderPath = appDocDir.path;
- String thumb = await Thumbnails.getThumbnail(
- thumbnailFolder: folderPath,
- videoFile: videoPathUrl,
- imageType:
- ThumbFormat.PNG, //this image will store in created folderpath
- quality: 30);
- print("--thumb--" + thumb);
- Get.back(result: thumb);
- }
-
- void onPauseButtonPressed() {
- pauseVideoRecording().then((_) {
- if (mounted) setState(() {});
- print('Video recording paused');
- });
- }
-
- void onResumeButtonPressed() {
- resumeVideoRecording().then((_) {
- if (mounted) setState(() {});
- print('Video recording resumed');
- });
- }
-
- Future<String> startVideoRecording() async {
- if (!controller.value.isInitialized) {
- showInSnackBar('Vui lòng chọn camera');
- return null;
- }
-
- final Directory extDir = await getApplicationDocumentsDirectory();
- final String dirPath = '${extDir.path}/Movies/tpf';
- await Directory(dirPath).create(recursive: true);
- final String filePath = '$dirPath/${timestamp()}.mp4';
-
- if (controller.value.isRecordingVideo) {
- // A recording is already started, do nothing.
- return null;
- }
-
- try {
- videoPath = filePath;
- await controller.startVideoRecording(filePath);
- } on CameraException catch (e) {
- _showCameraException(e);
- return null;
- }
- return filePath;
- }
-
- Future<void> stopVideoRecording() async {
- if (!controller.value.isRecordingVideo) {
- return null;
- }
-
- try {
- await controller.stopVideoRecording();
- } on CameraException catch (e) {
- _showCameraException(e);
- return null;
- }
- }
-
- Future<void> pauseVideoRecording() async {
- if (!controller.value.isRecordingVideo) {
- return null;
- }
-
- try {
- await controller.pauseVideoRecording();
- } on CameraException catch (e) {
- _showCameraException(e);
- rethrow;
- }
- }
-
- Future<void> resumeVideoRecording() async {
- if (!controller.value.isRecordingVideo) {
- return null;
- }
-
- try {
- await controller.resumeVideoRecording();
- } on CameraException catch (e) {
- _showCameraException(e);
- rethrow;
- }
- }
-
- Future<String> takePicture() async {
- if (!controller.value.isInitialized) {
- showInSnackBar('Vui lòng chọn camera');
- return null;
- }
- final Directory extDir = await getApplicationDocumentsDirectory();
- final String dirPath = '${extDir.path}/Pictures/tpf';
- await Directory(dirPath).create(recursive: true);
- final String filePath = '$dirPath/${timestamp()}.jpg';
-
- if (controller.value.isTakingPicture) {
- // A capture is already pending, do nothing.
- return null;
- }
-
- try {
- await controller.takePicture(filePath);
- } on CameraException catch (e) {
- _showCameraException(e);
- return null;
- }
- return filePath;
- }
-
- void _showCameraException(CameraException e) {
- logError(e.code, e.description);
- showInSnackBar('Lỗi: ${e.code}\n${e.description}');
- }
- }
|