From f0db572ba60bdbe893dd855bf62f8474118a6500 Mon Sep 17 00:00:00 2001 From: ivan-vanyusho Date: Fri, 22 May 2026 10:10:34 +0300 Subject: [PATCH 1/5] video encoding bitrate support --- .../lib/src/android_camera_camerax.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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, From fe4d2c40fcaed7d19ff73d4693e56a767e3ece8c Mon Sep 17 00:00:00 2001 From: ivan-vanyusho Date: Fri, 22 May 2026 10:19:15 +0300 Subject: [PATCH 2/5] changelog update --- packages/camera/camera_android_camerax/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/camera/camera_android_camerax/CHANGELOG.md b/packages/camera/camera_android_camerax/CHANGELOG.md index 954d384e8c86..1ad62a03e9a4 100644 --- a/packages/camera/camera_android_camerax/CHANGELOG.md +++ b/packages/camera/camera_android_camerax/CHANGELOG.md @@ -2,6 +2,10 @@ * Updates minimum supported SDK version to Flutter 3.38/Dart 3.10. +## 0.7.3 + +* Support video encoding bitrate + ## 0.7.2 * Bumps camerax_version from 1.5.3 to 1.6.0. From 41b64f0c0d8996bcfb63e0d7d063e6eed1b149b6 Mon Sep 17 00:00:00 2001 From: ivan-vanyusho Date: Fri, 22 May 2026 10:19:15 +0300 Subject: [PATCH 3/5] changelog update --- packages/camera/camera_android_camerax/CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/camera/camera_android_camerax/CHANGELOG.md b/packages/camera/camera_android_camerax/CHANGELOG.md index 954d384e8c86..35c001d76365 100644 --- a/packages/camera/camera_android_camerax/CHANGELOG.md +++ b/packages/camera/camera_android_camerax/CHANGELOG.md @@ -1,6 +1,7 @@ -## NEXT +## 0.7.3 * Updates minimum supported SDK version to Flutter 3.38/Dart 3.10. +* Support video encoding bitrate ## 0.7.2 From ecfbce9b1621f940b7424db576cfa3f2fc6839cf Mon Sep 17 00:00:00 2001 From: ivan-vanyusho Date: Mon, 25 May 2026 15:03:02 +0300 Subject: [PATCH 4/5] update CHANGELOG.md --- packages/camera/camera_android_camerax/CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/camera/camera_android_camerax/CHANGELOG.md b/packages/camera/camera_android_camerax/CHANGELOG.md index 8ea1e20683d1..aa91e7ac7f26 100644 --- a/packages/camera/camera_android_camerax/CHANGELOG.md +++ b/packages/camera/camera_android_camerax/CHANGELOG.md @@ -1,7 +1,7 @@ -## NEXT +## 0.7.3 -* Updates minimum supported SDK version to Flutter 3.38/Dart 3.10. * Support video encoding bitrate +* Updates minimum supported SDK version to Flutter 3.38/Dart 3.10. ## 0.7.2 From ea2b1b1c9f6938e0941cee0b86bd1786f3d0d645 Mon Sep 17 00:00:00 2001 From: ivan-vanyusho Date: Mon, 25 May 2026 17:05:01 +0300 Subject: [PATCH 5/5] added tests --- .../test/android_camera_camerax_test.dart | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) 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 {