diff --git a/packages/camera/camera_android_camerax/CHANGELOG.md b/packages/camera/camera_android_camerax/CHANGELOG.md index 954d384e8c86..aa91e7ac7f26 100644 --- a/packages/camera/camera_android_camerax/CHANGELOG.md +++ b/packages/camera/camera_android_camerax/CHANGELOG.md @@ -1,5 +1,6 @@ -## NEXT +## 0.7.3 +* Support video encoding bitrate * Updates minimum supported SDK version to Flutter 3.38/Dart 3.10. ## 0.7.2 diff --git a/packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart b/packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart index e52e4bd09cf1..026b4e45ab92 100644 --- a/packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart +++ b/packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart @@ -427,7 +427,10 @@ class AndroidCameraCameraX extends CameraPlatform { ); // Configure VideoCapture and Recorder instances. - recorder = Recorder(qualitySelector: presetQualitySelector); + recorder = Recorder( + qualitySelector: presetQualitySelector, + targetVideoEncodingBitRate: mediaSettings?.videoBitrate, + ); videoCapture = VideoCapture.withOutput( videoOutput: recorder!, targetFpsRange: _targetFpsRange, diff --git a/packages/camera/camera_android_camerax/test/android_camera_camerax_test.dart b/packages/camera/camera_android_camerax/test/android_camera_camerax_test.dart index 71ed3d58ccde..71468d12c42e 100644 --- a/packages/camera/camera_android_camerax/test/android_camera_camerax_test.dart +++ b/packages/camera/camera_android_camerax/test/android_camera_camerax_test.dart @@ -6579,6 +6579,108 @@ void main() { verifyNoMoreInteractions(camera.camera); }, ); + + test( + 'createCameraWithSettings passes video bitrate to Recorder', + () async { + final camera = AndroidCameraCameraX(); + const CameraLensDirection testLensDirection = CameraLensDirection.back; + const testSensorOrientation = 90; + const testCameraDescription = CameraDescription( + name: 'cameraName', + lensDirection: testLensDirection, + sensorOrientation: testSensorOrientation, + ); + const testVideoBitrate = 5000000; + + int? capturedVideoBitrate; + + final mockProcessCameraProvider = MockProcessCameraProvider(); + final mockCamera = MockCamera(); + final mockCameraInfo = MockCameraInfo(); + + when(mockProcessCameraProvider.bindToLifecycle(any, any)) + .thenAnswer((_) async => mockCamera); + when(mockCamera.getCameraInfo()).thenAnswer((_) async => mockCameraInfo); + when(mockCameraInfo.getCameraState()) + .thenAnswer((_) async => MockLiveCameraState()); + + setUpOverridesForTestingUseCaseConfiguration(mockProcessCameraProvider); + + PigeonOverrides.recorder_new = ({ + int? aspectRatio, + int? targetVideoEncodingBitRate, + QualitySelector? qualitySelector, + }) { + capturedVideoBitrate = targetVideoEncodingBitRate; + final mockRecorder = MockRecorder(); + when(mockRecorder.getQualitySelector()) + .thenAnswer((_) async => qualitySelector ?? MockQualitySelector()); + return mockRecorder; + }; + + camera.processCameraProvider = mockProcessCameraProvider; + + await camera.createCameraWithSettings( + testCameraDescription, + const MediaSettings( + videoBitrate: testVideoBitrate, + enableAudio: true, + ), + ); + + expect(capturedVideoBitrate, equals(testVideoBitrate)); + }, + ); + + test( + 'createCameraWithSettings passes null video bitrate when not specified', + () async { + final camera = AndroidCameraCameraX(); + const CameraLensDirection testLensDirection = CameraLensDirection.back; + const testSensorOrientation = 90; + const testCameraDescription = CameraDescription( + name: 'cameraName', + lensDirection: testLensDirection, + sensorOrientation: testSensorOrientation, + ); + + int? capturedVideoBitrate; + + final mockProcessCameraProvider = MockProcessCameraProvider(); + final mockCamera = MockCamera(); + final mockCameraInfo = MockCameraInfo(); + + when(mockProcessCameraProvider.bindToLifecycle(any, any)) + .thenAnswer((_) async => mockCamera); + when(mockCamera.getCameraInfo()).thenAnswer((_) async => mockCameraInfo); + when(mockCameraInfo.getCameraState()) + .thenAnswer((_) async => MockLiveCameraState()); + + setUpOverridesForTestingUseCaseConfiguration(mockProcessCameraProvider); + + PigeonOverrides.recorder_new = ({ + int? aspectRatio, + int? targetVideoEncodingBitRate, + QualitySelector? qualitySelector, + }) { + capturedVideoBitrate = targetVideoEncodingBitRate; + final mockRecorder = MockRecorder(); + when(mockRecorder.getQualitySelector()) + .thenAnswer((_) async => qualitySelector ?? MockQualitySelector()); + return mockRecorder; + }; + + camera.processCameraProvider = mockProcessCameraProvider; + + await camera.createCameraWithSettings( + testCameraDescription, + const MediaSettings(enableAudio: true), + ); + + expect(capturedVideoBitrate, isNull); + }, + ); } class TestMeteringPoint extends MeteringPoint {