Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/camera/camera/AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,4 @@ Aleksandr Yurkovskiy <sanekyy@gmail.com>
Anton Borries <mail@antonborri.es>
Alex Li <google@alexv525.com>
Rahul Raj <64.rahulraj@gmail.com>
Rui Craveiro <ruicraveiro@squarealfa.com>
4 changes: 4 additions & 0 deletions packages/camera/camera/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
* Updates minimum supported SDK version to Flutter 3.29/Dart 3.7.
* Updates README to reflect that only Android API 24+ is supported.

## 0.12.0

* Adds support for video stabilization.

## 0.11.2

* Fixes overflowed toggles in the camera example.
Expand Down
5 changes: 5 additions & 0 deletions packages/camera/camera/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,8 @@ dev_dependencies:

flutter:
uses-material-design: true

# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE.
# See https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#changing-federated-plugins
dependency_overrides:
{camera: {path: ../../../camera/camera}, camera_android_camerax: {path: ../../../camera/camera_android_camerax}, camera_avfoundation: {path: ../../../camera/camera_avfoundation}, camera_platform_interface: {path: ../../../camera/camera_platform_interface}, camera_web: {path: ../../../camera/camera_web}}
1 change: 1 addition & 0 deletions packages/camera/camera/lib/camera.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export 'package:camera_platform_interface/camera_platform_interface.dart'
FocusMode,
ImageFormatGroup,
ResolutionPreset,
VideoStabilizationMode,
XFile;

export 'src/camera_controller.dart';
Expand Down
97 changes: 97 additions & 0 deletions packages/camera/camera/lib/src/camera_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class CameraValue {
this.recordingOrientation,
this.isPreviewPaused = false,
this.previewPauseOrientation,
this.videoStabilizationMode = VideoStabilizationMode.off,
}) : _isRecordingPaused = isRecordingPaused;

/// Creates a new camera controller state for an uninitialized controller.
Expand All @@ -72,6 +73,7 @@ class CameraValue {
deviceOrientation: DeviceOrientation.portraitUp,
isPreviewPaused: false,
description: description,
videoStabilizationMode: VideoStabilizationMode.off,
);

/// True after [CameraController.initialize] has completed successfully.
Expand Down Expand Up @@ -148,6 +150,9 @@ class CameraValue {
/// The properties of the camera device controlled by this controller.
final CameraDescription description;

/// The video stabilization mode in
final VideoStabilizationMode videoStabilizationMode;

/// Creates a modified copy of the object.
///
/// Explicitly specified fields get the specified value, all other fields get
Expand All @@ -171,6 +176,7 @@ class CameraValue {
bool? isPreviewPaused,
CameraDescription? description,
Optional<DeviceOrientation>? previewPauseOrientation,
VideoStabilizationMode? videoStabilizationMode,
}) {
return CameraValue(
isInitialized: isInitialized ?? this.isInitialized,
Expand Down Expand Up @@ -201,6 +207,8 @@ class CameraValue {
previewPauseOrientation == null
? this.previewPauseOrientation
: previewPauseOrientation.orNull,
videoStabilizationMode:
videoStabilizationMode ?? this.videoStabilizationMode,
);
}

Expand All @@ -222,6 +230,7 @@ class CameraValue {
'recordingOrientation: $recordingOrientation, '
'isPreviewPaused: $isPreviewPaused, '
'previewPausedOrientation: $previewPauseOrientation, '
'videoStabilizationMode: $videoStabilizationMode, '
'description: $description)';
}
}
Expand Down Expand Up @@ -701,6 +710,94 @@ class CameraController extends ValueNotifier<CameraValue> {
}
}

/// Set the video stabilization mode for the selected camera.
///
/// When [allowFallback] is true (default) the camera will be set to the best
/// video stabilization mode up to, and including, [mode].
///
/// When [allowFallback] is false and if [mode] is not one of the supported
/// modes (see [getSupportedVideoStabilizationModes]), then it throws an
/// [ArgumentError].
///
/// This feature is only available if [getSupportedVideoStabilizationModes]
/// returns at least one value other than [VideoStabilizationMode.off].
Future<void> setVideoStabilizationMode(
VideoStabilizationMode mode, {
bool allowFallback = true,
}) async {
_throwIfNotInitialized('setVideoStabilizationMode');
try {
final VideoStabilizationMode? modeToSet =
await _getVideoStabilizationModeToSet(mode, allowFallback);

// When _getVideoStabilizationModeToSet returns null
// it means that the device doesn't support any
// video stabilization mode and that doing nothing
// is valid because allowFallback is true or [mode]
// is [VideoStabilizationMode.off], so this results
// in a no-op.
if (modeToSet == null) {
return;
}
await CameraPlatform.instance.setVideoStabilizationMode(
_cameraId,
modeToSet,
);
value = value.copyWith(videoStabilizationMode: modeToSet);
} on PlatformException catch (e) {
throw CameraException(e.code, e.message);
}
}

Future<VideoStabilizationMode?> _getVideoStabilizationModeToSet(
VideoStabilizationMode requestedMode,
bool allowFallback,
) async {
final Iterable<VideoStabilizationMode> supportedModes = await CameraPlatform
.instance
.getSupportedVideoStabilizationModes(_cameraId);

// If it can't fallback and the specific
// requested mode isn't available, then...
if (!allowFallback && !supportedModes.contains(requestedMode)) {
// if the request is off, it is a no-op
if (requestedMode == VideoStabilizationMode.off) {
return null;
}
// otherwise, it throws.
throw ArgumentError('Unavailable video stabilization mode.', 'mode');
}

VideoStabilizationMode? fallbackMode = requestedMode;
while (fallbackMode != null && !supportedModes.contains(fallbackMode)) {
fallbackMode = CameraPlatform.getFallbackVideoStabilizationMode(
fallbackMode,
);
}

return fallbackMode;
}

/// Gets a list of video stabilization modes that are supported
/// for the selected camera.
///
/// [VideoStabilizationMode.off] will always be listed.
Future<Iterable<VideoStabilizationMode>>
getSupportedVideoStabilizationModes() async {
_throwIfNotInitialized('isVideoStabilizationModeSupported');
try {
final Set<VideoStabilizationMode> modes = <VideoStabilizationMode>{
VideoStabilizationMode.off,
...await CameraPlatform.instance.getSupportedVideoStabilizationModes(
_cameraId,
),
};
return modes;
} on PlatformException catch (e) {
throw CameraException(e.code, e.message);
}
}

/// Sets the flash mode for taking pictures.
Future<void> setFlashMode(FlashMode mode) async {
try {
Expand Down
13 changes: 9 additions & 4 deletions packages/camera/camera/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: A Flutter plugin for controlling the camera. Supports previewing
Dart.
repository: https://github.com/flutter/packages/tree/main/packages/camera/camera
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
version: 0.11.2
version: 0.12.0

environment:
sdk: ^3.7.0
Expand All @@ -21,9 +21,9 @@ flutter:
default_package: camera_web

dependencies:
camera_android_camerax: ^0.6.13
camera_avfoundation: ^0.9.18
camera_platform_interface: ^2.10.0
camera_android_camerax: ^0.7.0
camera_avfoundation: ^0.10.0
camera_platform_interface: ^2.12.0
camera_web: ^0.3.3
flutter:
sdk: flutter
Expand All @@ -38,3 +38,8 @@ dev_dependencies:

topics:
- camera

# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE.
# See https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#changing-federated-plugins
dependency_overrides:
{camera_android_camerax: {path: ../../camera/camera_android_camerax}, camera_avfoundation: {path: ../../camera/camera_avfoundation}, camera_platform_interface: {path: ../../camera/camera_platform_interface}, camera_web: {path: ../../camera/camera_web}}
10 changes: 10 additions & 0 deletions packages/camera/camera/test/camera_preview_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,16 @@ class FakeController extends ValueNotifier<CameraValue>
@override
CameraDescription get description => value.description;

@override
Future<void> setVideoStabilizationMode(
VideoStabilizationMode mode, {
bool allowFallback = true,
}) async {}

@override
Future<Iterable<VideoStabilizationMode>>
getSupportedVideoStabilizationModes() async => <VideoStabilizationMode>[];

@override
bool supportsImageStreaming() => true;
}
Expand Down
Loading