Skip to content

[camera] Change default Android implementation from camera_android to camera_android_camerax #6629

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from 16 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
6 changes: 6 additions & 0 deletions packages/camera/camera/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 0.11.0

* **Breaking Change** Changes the Android implementation of the camera plugin from `camera_android`
to `camera_android_camerax`, which has full feature parity with `camera_android` except for all
of the limitations listed in `README.md`. To continue using `camera_android`, use `camera <0.11.0`.

## 0.10.6

* Adds support to control video fps and bitrate. See `CameraController` constructor.
Expand Down
9 changes: 8 additions & 1 deletion packages/camera/camera/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ Change the minimum Android sdk version to 21 (or higher) in your `android/app/bu
minSdkVersion 21
```

It's important to note that the `MediaRecorder` class is not working properly on emulators, as stated in the documentation: https://developer.android.com/reference/android/media/MediaRecorder. Specifically, when recording a video with sound enabled and trying to play it back, the duration won't be correct and you will only see the first frame.
It's important to note that the endorsed [`camera_android_camerax`][2] implementation of the camera plugin
built with CameraX has several limitations; please see this list of all of [the list of limitations][3]
for more details. If you wish to use the [`camera_android`][4] implementation of the camera plugin built
with Camera2 that lacks these limitations, please follow [these instructions][5].

### Web integration

Expand Down Expand Up @@ -167,3 +170,7 @@ class _CameraAppState extends State<CameraApp> {
For a more elaborate usage example see [here](https://github.com/flutter/packages/tree/main/packages/camera/camera/example).

[1]: https://pub.dev/packages/camera_web#limitations-on-the-web-platform
[2]: https://pub.dev/packages/camera_android_camerax
[3]: https://pub.dev/packages/camera_android_camerax#limitations
[4]: https://pub.dev/packages/camera_android
[5]: https://pub.dev/packages/camera_android#usage
57 changes: 43 additions & 14 deletions packages/camera/camera/example/integration_test/camera_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,40 @@ void main() {
skip: true,
);

testWidgets('Video capture records valid video', (WidgetTester tester) async {
final List<CameraDescription> cameras = await availableCameras();
if (cameras.isEmpty) {
return;
}

final CameraController controller = CameraController(
cameras[0],
ResolutionPreset.low,
enableAudio: false,
);
await controller.initialize();
await controller.prepareForVideoRecording();

await controller.startVideoRecording();
final int recordingStart = DateTime.now().millisecondsSinceEpoch;

sleep(const Duration(seconds: 2));

final XFile file = await controller.stopVideoRecording();
final int recordingTime =
DateTime.now().millisecondsSinceEpoch - recordingStart;

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, lessThan(recordingTime));
});

testWidgets('Pause and resume video recording', (WidgetTester tester) async {
final List<CameraDescription> cameras = await availableCameras();
if (cameras.isEmpty) {
Expand All @@ -162,26 +196,21 @@ void main() {

int startPause;
int timePaused = 0;
const int pauseIterations = 2;

await controller.startVideoRecording();
final int recordingStart = DateTime.now().millisecondsSinceEpoch;
sleep(const Duration(milliseconds: 500));

await controller.pauseVideoRecording();
startPause = DateTime.now().millisecondsSinceEpoch;
sleep(const Duration(milliseconds: 500));
await controller.resumeVideoRecording();
timePaused += DateTime.now().millisecondsSinceEpoch - startPause;

sleep(const Duration(milliseconds: 500));

await controller.pauseVideoRecording();
startPause = DateTime.now().millisecondsSinceEpoch;
sleep(const Duration(milliseconds: 500));
await controller.resumeVideoRecording();
timePaused += DateTime.now().millisecondsSinceEpoch - startPause;
for (int i = 0; i < pauseIterations; i++) {
await controller.pauseVideoRecording();
startPause = DateTime.now().millisecondsSinceEpoch;
sleep(const Duration(milliseconds: 500));
await controller.resumeVideoRecording();
timePaused += DateTime.now().millisecondsSinceEpoch - startPause;

sleep(const Duration(milliseconds: 500));
sleep(const Duration(milliseconds: 500));
}

final XFile file = await controller.stopVideoRecording();
final int recordingTime =
Expand Down
6 changes: 3 additions & 3 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.10.6
version: 0.11.0

environment:
sdk: ^3.2.3
Expand All @@ -14,14 +14,14 @@ flutter:
plugin:
platforms:
android:
default_package: camera_android
default_package: camera_android_camerax
ios:
default_package: camera_avfoundation
web:
default_package: camera_web

dependencies:
camera_android: ^0.10.9
camera_android_camerax: ^0.6.5
camera_avfoundation: ^0.9.15
camera_platform_interface: ^2.6.0
camera_web: ^0.3.3
Expand Down
5 changes: 5 additions & 0 deletions packages/camera/camera_android/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.10.9+2

* Updates `README.md` to reflect the fact that the `camera_android_camerax` camera plugin implementation
is the endorsed Android implementation for `camera: ^0.11.0`.

## 0.10.9+1

* Changes the visibility of a number of fields to `@VisibleForTesting` in order simplify testing.
Expand Down
30 changes: 16 additions & 14 deletions packages/camera/camera_android/README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
# camera\_android

The Android implementation of [`camera`][1].

*Note*: [`camera_android_camerax`][3] will become the default implementation of
`camera` on Android by May 2024, so **we strongly encourage you to opt into it**
by using [these instructions][4]. If any [limitations][5] of `camera_android_camerax`
prevent you from using it or if you run into any problems, please report these
issues under [`flutter/flutter`][5] with `[camerax]` in the title.
An Android implementation of [`camera`][1] built with the [Camera2 library][4].

## Usage

This package is [endorsed][2], which means you can simply use `camera`
normally. This package will be automatically included in your app when you do,
so you do not need to add it to your `pubspec.yaml`.
As of `camera: ^0.11.0`, to use this plugin instead of [`camera_android_camerax`][3],
run

```sh
$ flutter pub add camera_android
```

If using `camera: <0.11.0` and wish to use this plugin instead of [`camera_android_camerax`][3],
you can simply use `camera` normally because it is [endorsed][2]. This package will automatically
be included in your app when you do so, so you do not need to add it to your `pubspec.yaml`.

However, if you `import` this package with a version lower than `0.11.0`, to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual.

However, if you `import` this package to use any of its APIs directly, you
should add it to your `pubspec.yaml` as usual.
## Limitation of testing video recording on emulators
It's important to note that the `MediaRecorder` class is not working properly on emulators, as stated in the documentation: https://developer.android.com/reference/android/media/MediaRecorder. Specifically, when recording a video with sound enabled and trying to play it back, the duration won't be correct and you will only see the first frame.

[1]: https://pub.dev/packages/camera
[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin
[3]: https://pub.dev/packages/camera_android_camerax
[4]: https://pub.dev/packages/camera_android_camerax#usage
[5]: https://pub.dev/packages/camera_android_camerax#limitations
[4]: https://developer.android.com/media/camera/camera2
2 changes: 1 addition & 1 deletion packages/camera/camera_android/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description: Android implementation of the camera plugin.
repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_android
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22

version: 0.10.9+1
version: 0.10.9+2

environment:
sdk: ^3.1.0
Expand Down
5 changes: 5 additions & 0 deletions packages/camera/camera_android_camerax/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.6.4+2

* Updates `README.md` to reflect the fact that the `camera_android_camerax` camera plugin implementation
is the endorsed Android implementation for `camera: ^0.11.0`.

## 0.6.4+1

* Adds empty implementation for `prepareForVideoRecording` since this optimization is not used on Android.
Expand Down
38 changes: 17 additions & 21 deletions packages/camera/camera_android_camerax/README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
# camera\_android\_camerax

An Android implementation of [`camera`][1] that uses the [CameraX library][2].
The Android implementation of [`camera`][1] built with the [CameraX library][2].

*Note*: This implementation will become the default implementation of `camera`
on Android by May 2024, so **we strongly encourage you to opt into it**
by using [the instructions](#usage) below. If any of [the limitations](#limitations)
prevent you from using `camera_android_camerax` or if you run into any problems,
please report these issues under [`flutter/flutter`][5] with `[camerax]` in
the title.
*Note*: If any of [the limitations](#limitations) prevent you from using
using `camera_android_camerax` or if you run into any problems, please report
report these issues under [`flutter/flutter`][5] with `[camerax]` in the title.
You may also opt back into the [`camera_android`][6] implementation if you need.

## Usage

To use this plugin instead of [`camera_android`][4], run
As of `camera: ^0.11.0`, this package is [endorsed][3], which means you can
simply use `camera` normally. This package will be automatically be included
in your app when you do, so you do not need to add it to your `pubspec.yaml`.

However, if you `import` this package to use any of its APIs directly, you
should add it to your `pubspec.yaml` as usual.

If using `camera: <0.11.0` and wish to use this plugin instead of [`camera_android`][4],
run

```sh
$ flutter pub add camera_android_camerax
Expand Down Expand Up @@ -40,7 +46,7 @@ use cases, the plugin behaves according to the following:
### 240p resolution configuration for video recording

240p resolution configuration for video recording is unsupported by CameraX,
and thus, the plugin will fall back to 480p if configured with a
and thus, the plugin will fall back to target 480p if configured with a
`ResolutionPreset`.

### Setting maximum duration and stream options for video capture
Expand All @@ -58,17 +64,7 @@ For more information on contributing to this plugin, see [`CONTRIBUTING.md`](CON

[1]: https://pub.dev/packages/camera
[2]: https://developer.android.com/training/camerax
[3]: https://docs.flutter.dev/packages-and-plugins/developing-packages#non-endorsed-federated-plugin
[3]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin
[4]: https://pub.dev/packages/camera_android
[5]: https://github.com/flutter/flutter/issues/new/choose
[6]: https://developer.android.com/media/camera/camerax/architecture#combine-use-cases
[7]: https://developer.android.com/reference/android/hardware/camera2/CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_3
[8]: https://developer.android.com/reference/android/hardware/camera2/CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED
[120462]: https://github.com/flutter/flutter/issues/120462
[125915]: https://github.com/flutter/flutter/issues/125915
[120715]: https://github.com/flutter/flutter/issues/120715
[120468]: https://github.com/flutter/flutter/issues/120468
[120467]: https://github.com/flutter/flutter/issues/120467
[125371]: https://github.com/flutter/flutter/issues/125371
[126477]: https://github.com/flutter/flutter/issues/126477
[127896]: https://github.com/flutter/flutter/issues/127896
[6]: https://pub.dev/packages/camera_android#usage
2 changes: 1 addition & 1 deletion packages/camera/camera_android_camerax/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: camera_android_camerax
description: Android implementation of the camera plugin using the CameraX library.
repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_android_camerax
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
version: 0.6.4+1
version: 0.6.5+1

environment:
sdk: ^3.1.0
Expand Down