iris_camera 1.0.6
iris_camera: ^1.0.6 copied to clipboard
AVFoundation-powered camera toolkit with preview, lens control, and still capture APIs.
iris_camera #
πΈ iOS + Android + Web camera toolkit for Flutter, powered by AVFoundation, CameraX, and browser MediaDevices API. Render the native preview, switch lenses, stream frames, capture photos, record video, tune exposure/white balance/torch/zoom, and listen to lifecycle + orientation + AF/AE state β all from Dart.
Platform coverage: iOS + Android + Web. Other platforms no-op safely.
Highlights #
- π Lens discovery & switching β list every lens (front included by default; exclude with
includeFrontCameras: false) and reconfigure withswitchLens. - πΌοΈ Native preview widget β
IrisCameraPreviewwrapsAVCaptureVideoPreviewLayerwith tap-to-focus + overlay hooks. - πΈ Still capture β
capturePhotowith flash/ISO/exposure overrides. Long exposure is supported; query the device max viagetMaxExposureDuration. - πΈ Burst β
captureBurst(count, options)supports long exposure/ISO overrides, optional file saving (directory,filenamePrefix), and progress events viaburstProgressStream. - ποΈ Pro controls β focus mode/point, exposure mode/point/EV, white balance, frame rate range, torch, zoom, resolution presets.
- π‘ Streams β live BGRA image stream, orientation stream, lifecycle state stream, AF/AE state stream.
- π§ Lifecycle β explicit
initialize/pause/resume/disposeand structured errors viaIrisCameraException. - π₯ Video β start/stop file-based recording (iOS/Android), optional audio.
Install #
Supported platforms #
- Android: minSdk 26+, targetSdk 34 (CameraX 1.3.x)
- iOS: iOS 15.0+
- Web: Modern browsers with MediaDevices API support (Chrome, Firefox, Safari, Edge)
flutter pub add iris_camera
import 'package:iris_camera/iris_camera.dart';
final camera = IrisCamera();
final lenses = await camera.listAvailableLenses(); // includeFrontCameras defaults to true
await camera.switchLens(lenses.first.category);
final photo = await camera.capturePhoto(
options: const PhotoCaptureOptions(flashMode: PhotoFlashMode.auto),
);
Live preview:
final focusController = FocusIndicatorController();
IrisCameraPreview(
aspectRatio: 3 / 2,
enableTapToFocus: true,
showFocusIndicator: true,
onTapFocus: (point) => camera.setFocus(point: point),
focusIndicatorController: focusController,
);
iOS setup #
Add to ios/Runner/Info.plist (both are required or the app will crash when accessing camera/mic):
<key>NSCameraUsageDescription</key>
<string>This app needs the camera to capture photos.</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app needs the microphone for recording video with audio.</string>
Thatβs it. Permissions are requested automatically on first use.
Exclude front cameras by calling
listAvailableLenses(includeFrontCameras: false).
Android setup #
Add the camera permission to your app manifest (the plugin also declares it for you):
<uses-permission android:name="android.permission.CAMERA" />
<!-- Needed for video with audio -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
iris_camera will prompt for runtime permission automatically before accessing the camera. The preview is rendered via a native PreviewView, and tap-to-focus works the same as iOS.
Web setup #
No additional configuration required. The browser will automatically prompt for camera permission when accessing the camera. Ensure your site is served over HTTPS (required for camera access).
Note: Some advanced features have limited support on web:
- Focus/exposure point control is simulated (browser limitation)
- White balance temperature/tint is not available
- Video recording outputs WebM format (blob URL)
- Torch/flash depends on browser and device support
API quick reference #
Key methods:
listAvailableLenses({includeFrontCameras})βList<CameraLensDescriptor>switchLens(CameraLensCategory category)βCameraLensDescriptorcapturePhoto({PhotoCaptureOptions options})βUint8ListcaptureBurst({count, PhotoCaptureOptions options, directory, filenamePrefix})βList<Uint8List>or saved file paths whendirectoryis setburstProgressStreamβBurstProgressEvent(total, completed, status, error?)getMaxExposureDuration()βDuration(use to clamp long exposures)startVideoRecording({filePath, enableAudio})βString pathstopVideoRecording()βString path- Focus:
setFocus(point/lensPosition),setFocusMode,focusExposureStateStream - Exposure:
setExposureMode,setExposurePoint,setExposureOffset,getMin/MaxExposureOffset,getExposureOffsetStepSize - Zoom/torch/WB:
setZoom,setTorch,setWhiteBalance - Frame/format:
setFrameRateRange,setResolutionPreset - Streams:
imageStream,orientationStream,stateStream - Lifecycle:
initialize,pauseSession,resumeSession,disposeSession - Errors:
IrisCameraException(code, message, details)
Data classes:
CameraLensDescriptor(id,name,position,category,supportsFocus, optionalfocalLength,fieldOfView)PhotoCaptureOptions(flashMode,exposureDuration,iso)OrientationEvent,CameraStateEvent,FocusExposureStateEvent,IrisImageFrame
Widget:
IrisCameraPreviewwith tap-to-focus + focus indicator styling/control.
iris_camera vs camera (iOS/Android) #
| Capability | iris_camera | camera |
|---|---|---|
| Still photos | β Shared session JPEG capture | β |
| Live preview widget | β
IrisCameraPreview (iOS/Android/Web) |
β |
| Lens discovery/switching | β Enumerate + switch by category (wide/ultraWide/telephoto/etc.), front opt-in | βͺοΈ List only (no switching API) |
| Tap/manual focus | β Tap/point focus; iOS also supports lensPosition | β |
| Exposure controls | β mode/point/EV/ISO/exposure duration | β (mode/point/offset) |
| White balance override | β iOS: temperature/tint; Android: auto/lock only | βͺοΈ (not exposed) |
| Zoom | β | β |
| Torch | β (torch separate from flash) | β |
| Frame rate range | β min/max FPS | βͺοΈ limited |
| Resolution preset | β | β |
| Live image stream | β BGRA | β |
| Orientation stream | β device/video | β |
| AF/AE state stream | β | βͺοΈ basic focus/exposure mode only |
| Lifecycle controls | β initialize/pause/resume/dispose + state stream | β (controller init/dispose) |
| Video recording | β (iOS/Android/Web) | β |
| Web | β (MediaDevices API) | β |
Example flow #
final lenses = await camera.listAvailableLenses();
final tele = lenses.firstWhere(
(lens) => lens.category == CameraLensCategory.telephoto,
orElse: () => lenses.first,
);
await camera.switchLens(tele.category);
await camera.initialize();
camera.stateStream.listen((event) => debugPrint('state=${event.state}'));
camera.focusExposureStateStream.listen((event) => debugPrint('af/ae=${event.state}'));
await camera.setExposureMode(ExposureMode.locked);
await camera.setFocusMode(FocusMode.locked);
final photo = await camera.capturePhoto();
License #
MIT β see LICENSE.