fingerprint/lib/data/datasources/camera_datasource.dart
Aastha Shrivastava 3132b7e8cd first commit
2026-01-17 12:54:01 +05:30

107 lines
3.3 KiB
Dart

import 'package:camera/camera.dart';
import 'package:flutter/foundation.dart';
import '../../core/utils/file_helper.dart';
abstract class CameraDataSource {
Future<CameraController> getCameraController();
Future<String> captureImage(CameraController controller);
Future<void> disposeCamera(CameraController controller);
Future<void> startImageStream(CameraController controller, Function(CameraImage) onImage);
Future<void> stopImageStream(CameraController controller);
}
class CameraDataSourceImpl implements CameraDataSource {
@override
Future<CameraController> getCameraController() async {
List<CameraDescription> cameras = [];
try {
cameras = await availableCameras();
} catch (e) {
debugPrint("availableCameras() failed: $e");
}
if (cameras.isEmpty) {
if (kIsWeb) {
debugPrint("No cameras found. Attempting Web Fallback with default configuration.");
// Fallback for Web: Create a generic camera description.
// This attempts to bypass enumeration issues caused by browser privacy blocks.
cameras = [
const CameraDescription(
name: 'Default Web Camera',
lensDirection: CameraLensDirection.external, // Use external/front as default safe bet
sensorOrientation: 0,
),
];
} else {
throw Exception('No cameras available. Please ensure camera permission is granted.');
}
}
// Web-safe image format selection
ImageFormatGroup? formatGroup;
if (!kIsWeb) {
formatGroup = defaultTargetPlatform == TargetPlatform.android
? ImageFormatGroup.yuv420
: ImageFormatGroup.bgra8888;
}
// Use medium resolution for better Web compatibility
// 'low' might be even safer for initial connection
final controller = CameraController(
cameras.first,
kIsWeb ? ResolutionPreset.medium : ResolutionPreset.high,
enableAudio: false,
imageFormatGroup: formatGroup,
);
try {
await controller.initialize();
return controller;
} catch (e) {
debugPrint("Controller initialization failed: $e");
throw Exception("Failed to start camera: $e");
}
}
@override
Future<String> captureImage(CameraController controller) async {
final image = await controller.takePicture();
return await FileHelper.saveCapturedImage(image);
}
@override
Future<void> disposeCamera(CameraController controller) async {
await controller.dispose();
}
@override
Future<void> startImageStream(CameraController controller, Function(CameraImage) onImage) async {
// Web: check if streaming is supported to avoid assertion error
if (kIsWeb) {
try {
if (!controller.value.isStreamingImages) {
await controller.startImageStream(onImage);
}
} catch (e) {
debugPrint("Web Image Stream failed (expected on some browsers): $e");
}
return;
}
// Native logic
if (!controller.value.isStreamingImages) {
await controller.startImageStream(onImage);
}
}
@override
Future<void> stopImageStream(CameraController controller) async {
try {
if (controller.value.isStreamingImages) {
await controller.stopImageStream();
}
} catch (e) {
// ignore
}
}
}