Untitled
unknown
plain_text
8 months ago
9.2 kB
3
Indexable
import 'dart:io'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:camera/camera.dart'; import 'package:path_provider/path_provider.dart'; import 'package:video_compress/video_compress.dart'; import 'package:gal/gal.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:device_info_plus/device_info_plus.dart'; class CameraScreen extends StatefulWidget { @override _CameraScreenState createState() => _CameraScreenState(); } class _CameraScreenState extends State<CameraScreen> { CameraController? _controller; late Future<void> _initializeControllerFuture; bool _isRecording = false; String? _recordedVideoPath; double _compressionProgress = 0.0; late Subscription _subscription; bool _cameraInitialized = false; String? _errorMessage; @override void initState() { super.initState(); _subscription = VideoCompress.compressProgress$.subscribe((progress) { setState(() { _compressionProgress = progress; }); debugPrint('Compression progress: $progress'); }); _initializeControllerFuture = _initializeCamera(); _requestCameraPermission(); } Future<void> _requestCameraPermission() async { final status = await Permission.camera.request(); debugPrint('Camera permission status: ${status.isGranted}'); } Future<void> _initializeCamera() async { try { debugPrint('[DEBUG] Requesting camera permission...'); final cameraPermissionStatus = await Permission.camera.request(); debugPrint('[DEBUG] Camera permission status: ${cameraPermissionStatus.isGranted}'); if (!cameraPermissionStatus.isGranted) { _showPermissionDeniedDialog(context); return; } debugPrint('[DEBUG] Fetching available cameras...'); final cameras = await availableCameras(); debugPrint('[DEBUG] Available cameras: $cameras'); if (cameras.isEmpty) { setState(() { _errorMessage = 'No cameras available'; }); return; } final firstCamera = cameras.first; debugPrint('[DEBUG] Initializing camera controller with: $firstCamera'); _controller = CameraController(firstCamera, ResolutionPreset.high); await _controller?.initialize(); if (!mounted) { return; } setState(() { _cameraInitialized = true; }); debugPrint('[DEBUG] Camera initialized successfully'); } catch (e) { debugPrint('[DEBUG] Failed to initialize camera: $e'); setState(() { _errorMessage = 'Failed to initialize camera: $e'; }); } } void _checkPermissionStatus() async { final status = await Permission.camera.status; debugPrint('[DEBUG] Camera permission status (programmatic check): ${status.isGranted}'); } @override void dispose() { _controller?.dispose(); _subscription.unsubscribe(); super.dispose(); } Future<void> _compressAndSaveVideo(String videoPath) async { print('[DEBUG] Compressing video...'); final info = await VideoCompress.compressVideo( videoPath, quality: VideoQuality.MediumQuality, deleteOrigin: false, // Set to true if you want to delete the original video ); if (info != null && info.file != null) { final compressedVideoPath = info.file!.path; print('[DEBUG] Video compressed to $compressedVideoPath'); await _saveVideoToGallery(compressedVideoPath); } else { print('[DEBUG] Video compression failed'); } } Future<void> _saveVideoToGallery(String videoPath) async { if (await _requestStoragePermission()) { print('[DEBUG] Saving video to gallery...'); final result = await Gal.putVideo(videoPath); print('[DEBUG] Save result'); } else { print('[DEBUG] Storage permission denied'); } } Future<bool> _requestStoragePermission() async { if (Platform.isIOS) { final status = await Permission.photos.request(); debugPrint('[DEBUG] iOS storage permission status: ${status.isGranted}'); return status.isGranted; } else { DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; if (androidInfo.version.sdkInt >= 30) { final status = await Permission.manageExternalStorage.request(); debugPrint('[DEBUG] Android (SDK >= 30) storage permission status: ${status.isGranted}'); return status.isGranted; } else { final status = await Permission.storage.request(); debugPrint('[DEBUG] Android (SDK < 30) storage permission status: ${status.isGranted}'); return status.isGranted; } } } Future<String> _getVideoPath() async { final directory = await getApplicationDocumentsDirectory(); final videoDir = Directory('${directory.path}/video_compress'); if (!await videoDir.exists()) { await videoDir.create(recursive: true); } return videoDir.path; } void _showPermissionDeniedDialog(BuildContext context) { showDialog( context: context, builder: (context) => AlertDialog( title: Text('Permission Denied'), content: Text('Camera permission is required to use this feature. Please enable it in the app settings.'), actions: [ TextButton( onPressed: () { Navigator.of(context).pop(); }, child: Text('Cancel'), ), TextButton( onPressed: () { openAppSettings(); }, child: Text('Open Settings'), ), ], ), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Take Video'), leading: IconButton( icon: const Icon(Icons.arrow_back), onPressed: () { context.go('/home'); // Navigate back }, ), ), body: FutureBuilder<void>( future: _initializeControllerFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.done) { if (_errorMessage != null) { return Center( child: Text(_errorMessage!), ); } return Stack( children: [ _controller == null ? Center(child: Text('Camera not available')) : CameraPreview(_controller!), if (_compressionProgress > 0.0 && _compressionProgress < 100.0) Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ CircularProgressIndicator( value: _compressionProgress, ), const SizedBox(height: 10), Text( '${(_compressionProgress * 100).toStringAsFixed(1)}%', style: const TextStyle(fontSize: 20), ), ], ), ), ], ); } else if (snapshot.hasError) { return Center( child: Text('Error initializing camera: ${snapshot.error}'), ); } else { return Center(child: CircularProgressIndicator()); } }, ), floatingActionButton: FutureBuilder<void>( future: _initializeControllerFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.done && _controller != null && _controller!.value.isInitialized) { return FloatingActionButton( onPressed: () async { if (_controller != null && _controller!.value.isInitialized) { try { if (!_isRecording) { final videoPath = await _getVideoPath(); _recordedVideoPath = '$videoPath/recorded_video.mp4'; await _controller!.startVideoRecording(); setState(() { _isRecording = true; }); print('[DEBUG] Recording started...'); } else { final video = await _controller!.stopVideoRecording(); setState(() { _isRecording = false; }); print('[DEBUG] Recording stopped. Video saved at ${video.path}'); if (_recordedVideoPath != null) { await _compressAndSaveVideo(video.path); } } } catch (e) { print('[DEBUG] Error: $e'); } } }, child: Icon(_isRecording ? Icons.stop : Icons.videocam), ); } else { return Container(); // Or an alternative placeholder } }, ), ); } }
Editor is loading...
Leave a Comment