diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index fae21094cd7..9b6c81857e1 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,5 +1,6 @@ -## NEXT +## 0.11.2+1 +* Implement setDescriptionWhileRecording with android camerax (Fixes flutter/flutter#148013). * Updates minimum supported SDK version to Flutter 3.29/Dart 3.7. * Updates README to reflect that only Android API 24+ is supported. diff --git a/packages/camera/camera/example/integration_test/camera_test.dart b/packages/camera/camera/example/integration_test/camera_test.dart index 172319531de..19909e55a89 100644 --- a/packages/camera/camera/example/integration_test/camera_test.dart +++ b/packages/camera/camera/example/integration_test/camera_test.dart @@ -260,7 +260,9 @@ void main() { return completer.future; } - testWidgets('Set description while recording', (WidgetTester tester) async { + testWidgets('Set description while recording captures full video', ( + WidgetTester tester, + ) async { final List cameras = await availableCameras(); if (cameras.length < 2) { return; @@ -269,7 +271,6 @@ void main() { final CameraController controller = CameraController( cameras[0], ResolutionPreset.low, - enableAudio: false, ); await controller.initialize(); @@ -278,7 +279,27 @@ void main() { await controller.startVideoRecording(); await controller.setDescription(cameras[1]); - expect(controller.description, cameras[1]); + await tester.pumpAndSettle(const Duration(seconds: 4)); + + await controller.setDescription(cameras[0]); + + await tester.pumpAndSettle(const Duration(seconds: 1)); + + final XFile file = await controller.stopVideoRecording(); + + final File videoFile = File(file.path); + final VideoPlayerController videoController = VideoPlayerController.file( + videoFile, + ); + await videoController.initialize(); + final int duration = videoController.value.duration.inMilliseconds; + await videoController.dispose(); + + expect( + duration, + greaterThanOrEqualTo(const Duration(seconds: 4).inMilliseconds), + ); + await controller.dispose(); }); testWidgets('Set description', (WidgetTester tester) async { diff --git a/packages/camera/camera/lib/src/camera_controller.dart b/packages/camera/camera/lib/src/camera_controller.dart index 4ecc6aae971..3c3a803be0e 100644 --- a/packages/camera/camera/lib/src/camera_controller.dart +++ b/packages/camera/camera/lib/src/camera_controller.dart @@ -439,6 +439,10 @@ class CameraController extends ValueNotifier { /// Sets the description of the camera. /// + /// On Android, you must start the recording with [startVideoRecording] + /// with `enablePersistentRecording` set to `true` + /// to avoid cancelling any active recording. + /// /// Throws a [CameraException] if setting the description fails. Future setDescription(CameraDescription description) async { if (value.isRecordingVideo) { @@ -554,8 +558,15 @@ class CameraController extends ValueNotifier { /// /// The video is returned as a [XFile] after calling [stopVideoRecording]. /// Throws a [CameraException] if the capture fails. + /// + /// `enablePersistentRecording` parameter configures the recording to be a persistent recording. + /// A persistent recording can only be stopped by explicitly calling [stopVideoRecording] + /// and will ignore events that would normally cause recording to stop, + /// such as lifecycle events or explicit calls to [setDescription] while recording is in progress. + /// Currently a no-op on platforms other than Android. Future startVideoRecording({ onLatestImageAvailable? onAvailable, + bool enablePersistentRecording = true, }) async { _throwIfNotInitialized('startVideoRecording'); if (value.isRecordingVideo) { @@ -574,7 +585,11 @@ class CameraController extends ValueNotifier { try { await CameraPlatform.instance.startVideoCapturing( - VideoCaptureOptions(_cameraId, streamCallback: streamCallback), + VideoCaptureOptions( + _cameraId, + streamCallback: streamCallback, + enablePersistentRecording: enablePersistentRecording, + ), ); value = value.copyWith( isRecordingVideo: true, diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 073c8019872..1ddf1e1d25c 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -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.11.2+1 environment: sdk: ^3.7.0 @@ -21,9 +21,9 @@ flutter: default_package: camera_web dependencies: - camera_android_camerax: ^0.6.13 + camera_android_camerax: ^0.6.22 camera_avfoundation: ^0.9.18 - camera_platform_interface: ^2.10.0 + camera_platform_interface: ^2.11.0 camera_web: ^0.3.3 flutter: sdk: flutter diff --git a/packages/camera/camera/test/camera_preview_test.dart b/packages/camera/camera/test/camera_preview_test.dart index be672d1bbb2..bafc77831dc 100644 --- a/packages/camera/camera/test/camera_preview_test.dart +++ b/packages/camera/camera/test/camera_preview_test.dart @@ -112,6 +112,7 @@ class FakeController extends ValueNotifier @override Future startVideoRecording({ onLatestImageAvailable? onAvailable, + bool enablePersistentRecording = true, }) async {} @override