Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

[camera] flip/change camera while recording #6478

Closed
wants to merge 120 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
120 commits
Select commit Hold shift + click to select a range
dcf5051
setDescription in Camera platform interface
BradenBagbyWavv Sep 21, 2022
6ebbf8f
Merge remote-tracking branch 'upstream/main' into feature/switch-camera
BradenBagbyWavv Sep 21, 2022
ffd30f0
example app setup to change description mid recording
BradenBagbyWavv Sep 21, 2022
bc9e8b9
AVFoundationCamera method call to setDescription
BradenBagbyWavv Sep 21, 2022
89accd6
FLTCam setup to setDescription
BradenBagbyWavv Sep 21, 2022
e31ba2a
captureSession split into video and audio so we will be able to switc…
BradenBagbyWavv Sep 21, 2022
ac2c249
renamed setDescription to setDescriptionWhileRecording since it can o…
BradenBagbyWavv Sep 21, 2022
1516e0d
integration tests fixed
BradenBagbyWavv Sep 21, 2022
34b9b03
set description while recording integration test
BradenBagbyWavv Sep 21, 2022
97f9733
throws error if device not recording and setDescriptionWhileRecording…
BradenBagbyWavv Sep 21, 2022
bca93e2
set description while recording test
BradenBagbyWavv Sep 21, 2022
b999be1
example project setup
BradenBagbyWavv Sep 22, 2022
568af7d
camera preview can be changed while recording
BradenBagbyWavv Sep 22, 2022
ef4f96b
camera switches and keeps surface pointed to mediarecorder
BradenBagbyWavv Sep 22, 2022
f36004d
small change to set autofocus when switching while recording
BradenBagbyWavv Sep 22, 2022
a0301c2
android video record goes through VideoRenderer to apply matrix after…
BradenBagbyWavv Sep 22, 2022
e929814
switch camera uses VideoRenderer
BradenBagbyWavv Sep 23, 2022
156f78a
dont use video renderer until user switches camera while recording
BradenBagbyWavv Sep 23, 2022
61468a9
rotate based on initial recording direction
BradenBagbyWavv Sep 23, 2022
aea9067
VideoRenderer cleanup
BradenBagbyWavv Sep 23, 2022
fdf5738
flutter results for setDescriptionWhileRecording
BradenBagbyWavv Sep 23, 2022
d9862f3
error if you setDescriptionWhileRecording while device is not recording
BradenBagbyWavv Sep 23, 2022
a20e5d3
android tests
BradenBagbyWavv Sep 23, 2022
5044d94
integration tests
BradenBagbyWavv Sep 23, 2022
667c803
method channel test
BradenBagbyWavv Sep 23, 2022
3b45ff5
main package tests
BradenBagbyWavv Sep 23, 2022
5d96ffd
setDescriptionWhileRecording called while no video was recording test
BradenBagbyWavv Sep 23, 2022
aa1d070
integration tests
BradenBagbyWavv Sep 23, 2022
858ce2e
dependency overrides
BradenBagbyWavv Sep 23, 2022
58bdcf6
update readme and version
BradenBagbyWavv Sep 23, 2022
c29ed5d
removed old TODO
BradenBagbyWavv Sep 23, 2022
156ad27
removed accidental dev team ID commit
BradenBagbyWavv Sep 26, 2022
2dbaccb
renamed local variables
BradenBagbyWavv Sep 26, 2022
c17f133
use captureSessionQueue
BradenBagbyWavv Sep 26, 2022
bfbdc48
fixed local variable name
BradenBagbyWavv Sep 26, 2022
dad170f
setupCaptureVideoOutput function
BradenBagbyWavv Sep 26, 2022
4017924
createConnectionWithInput
BradenBagbyWavv Sep 26, 2022
6d4c5a3
simplified configureConnection function to re-use code on switching c…
BradenBagbyWavv Sep 26, 2022
0ab3548
formatting
BradenBagbyWavv Sep 26, 2022
28c89f8
example project dependency overrides
BradenBagbyWavv Sep 27, 2022
9aa5289
fixed versioning
BradenBagbyWavv Sep 27, 2022
57f5f77
formatting
BradenBagbyWavv Sep 27, 2022
ccf9e63
fixed some ios native tests
BradenBagbyWavv Sep 27, 2022
9041121
fixed small bug
BradenBagbyWavv Sep 27, 2022
b03a4a5
dont emit initialized when switching camera
BradenBagbyWavv Sep 27, 2022
cfe8e20
ios formatting
BradenBagbyWavv Sep 27, 2022
7e338e4
dependency overrides for camera/example
BradenBagbyWavv Sep 27, 2022
ce6950c
android formatting
BradenBagbyWavv Sep 27, 2022
563329e
ios test formatted
BradenBagbyWavv Sep 27, 2022
9a32c1a
android tests formatted
BradenBagbyWavv Sep 27, 2022
eb47113
android format that I missed
BradenBagbyWavv Sep 27, 2022
f01f63f
other android formatting
BradenBagbyWavv Sep 27, 2022
4bdac9d
final formatting with flutter tool
BradenBagbyWavv Sep 27, 2022
68d8c8f
formatted android again
BradenBagbyWavv Sep 27, 2022
a001e02
android license in new file
BradenBagbyWavv Sep 27, 2022
322bdf5
update-excerpts ran
BradenBagbyWavv Sep 28, 2022
e62d860
Merge branch 'main' into feature/switch-camera
BradenBagby Sep 28, 2022
d9aaba0
fixed changelog
BradenBagbyWavv Sep 29, 2022
a9bb9f8
removed development team
BradenBagbyWavv Sep 29, 2022
9e40600
renames configureConnection to createConnection
BradenBagbyWavv Sep 29, 2022
4753c00
Merge branch 'main' into feature/switch-camera
BradenBagby Sep 29, 2022
5a55b7a
renames unimplemented error message
BradenBagbyWavv Oct 3, 2022
ad5d62f
renames setDescriptionWhileRecording error to match android and the o…
BradenBagbyWavv Oct 3, 2022
cb36849
fixes formatting
BradenBagbyWavv Oct 3, 2022
94c0be3
removes override dependencies from camera_web and camera_windows
BradenBagbyWavv Oct 3, 2022
f8824ed
removes camera_web override dependency in camera package
BradenBagbyWavv Oct 3, 2022
5d3bc8a
Update packages/camera/camera_android/android/src/main/java/io/flutte…
BradenBagby Oct 20, 2022
54e062d
Update packages/camera/camera_android/android/src/main/java/io/flutte…
BradenBagby Oct 21, 2022
ca2880f
Update packages/camera/camera_android/android/src/main/java/io/flutte…
BradenBagby Oct 21, 2022
f2e1569
Update packages/camera/camera_android/android/src/main/java/io/flutte…
BradenBagby Oct 21, 2022
5b7327e
Merge branch 'main' into feature/switch-camera
BradenBagby Oct 21, 2022
89b7c2f
reformats camera.java
BradenBagbyWavv Oct 21, 2022
619773d
VideoRenderer uses surface texture timestamp instead of current syste…
BradenBagbyWavv Oct 21, 2022
5e36473
formats VideoRenderer.java
BradenBagbyWavv Oct 21, 2022
973b1f8
fixes comments in VideoRenderer.java
BradenBagbyWavv Oct 21, 2022
8bd178e
Update packages/camera/camera_platform_interface/lib/src/platform_int…
BradenBagby Oct 28, 2022
08e158b
Update packages/camera/camera/lib/src/camera_controller.dart
BradenBagby Oct 28, 2022
1f2635e
renames error typo
BradenBagbyWavv Oct 31, 2022
70da5ef
frees shaders after program linking
BradenBagbyWavv Nov 1, 2022
aec423d
handles eglSwapBuffers errors
BradenBagbyWavv Nov 1, 2022
53d3e1d
extension check guards eglPresentationTimeANDROID
BradenBagbyWavv Nov 1, 2022
98969d1
cleans openGL resources
BradenBagbyWavv Nov 7, 2022
f2c4876
reverted timestamp to use uptimeMillis()
BradenBagbyWavv Nov 14, 2022
7b958ee
Merge branch 'main' into feature/switch-camera
BradenBagby Nov 22, 2022
8145162
Tests for startPreviewWithVideoRendererStream
BradenBagbyWavv Nov 28, 2022
a8e0a72
fixes exception not being caught
BradenBagbyWavv Nov 28, 2022
ea28413
tests for correct rotation to be set
BradenBagbyWavv Nov 29, 2022
a12e3f4
fixes versioning
BradenBagbyWavv Dec 4, 2022
98a493b
tests method channel setDescriptionWhileRecording
BradenBagbyWavv Dec 4, 2022
9f3fc49
adds forwarding getter on CameraController to its value's description
BradenBagbyWavv Dec 5, 2022
2c5e38f
dummy commit to fix github test's not finding commit hash
BradenBagbyWavv Dec 5, 2022
3a8fd89
adds override description for FakeController in camera tests
BradenBagbyWavv Dec 5, 2022
e52dfcc
fixes versioning for avfoundation and android
BradenBagbyWavv Dec 5, 2022
269260f
Merge branch 'main' into feature/switch-camera
BradenBagby Dec 5, 2022
e6bd484
Merge branch 'master' into feature/switch-camera
BradenBagbyWavv Dec 6, 2022
0c70970
fixes versioning
BradenBagbyWavv Dec 6, 2022
247bacb
Merge branch 'master' into feature/switch-camera
BradenBagbyWavv Dec 6, 2022
f831e4e
Merge branch 'master' into feature/switch-camera
BradenBagbyWavv Dec 9, 2022
d49dcf7
fixes pubspec versions
BradenBagbyWavv Dec 9, 2022
3d8fa3a
Merge branch 'main' into feature/switch-camera
BradenBagby Dec 16, 2022
14004fd
Merge branch 'master' into feature/switch-camera
BradenBagbyWavv Dec 22, 2022
2d154b5
Merge branch 'main' into feature/switch-camera
BradenBagby Jan 10, 2023
e95eea9
ios setDescription
BradenBagbyWavv Jan 11, 2023
e0a5fbb
setDescription
BradenBagbyWavv Jan 11, 2023
9fdba25
android setDescription
BradenBagbyWavv Jan 11, 2023
ff17835
formatting
BradenBagbyWavv Jan 11, 2023
02b847a
revert
BradenBagbyWavv Jan 11, 2023
8330cc9
nits and reverts
BradenBagbyWavv Jan 11, 2023
fbf2a23
nits
BradenBagbyWavv Jan 11, 2023
fa33e4f
fixes README
BradenBagbyWavv Jan 11, 2023
998a366
fixes other comments
BradenBagbyWavv Jan 11, 2023
1eeaacc
fixes setDescription override in camera_preview_test
BradenBagbyWavv Jan 11, 2023
a380c4d
set description test
BradenBagbyWavv Jan 12, 2023
cb72a67
Merge branch 'main' into feature/switch-camera
BradenBagby Jan 23, 2023
f6f8775
Merge branch 'master' into feature/switch-camera
BradenBagby Jan 30, 2023
2fe0024
versions
BradenBagby Jan 30, 2023
d1a2a94
removes changes on platform_interface_changes
BradenBagby Feb 6, 2023
e74c2af
points all packages to platform interface version 2.4
BradenBagby Feb 6, 2023
49e91c2
points to the new platform interface
BradenBagby Feb 6, 2023
be29466
Merge branch 'main' into feature/switch-camera
BradenBagby Feb 6, 2023
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
4 changes: 4 additions & 0 deletions packages/camera/camera/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.10.4

* Allows camera to be switched while video recording.

## 0.10.3

* Adds back use of Optional type.
Expand Down
2 changes: 1 addition & 1 deletion packages/camera/camera/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.inactive) {
cameraController.dispose();
} else if (state == AppLifecycleState.resumed) {
onNewCameraSelected(cameraController.description);
_initializeCameraController(cameraController.description);
}
}
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,49 @@ void main() {
return completer.future;
}

testWidgets('Set description while recording', (WidgetTester tester) async {
final List<CameraDescription> cameras = await availableCameras();
if (cameras.length < 2) {
return;
}

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

await controller.initialize();
await controller.prepareForVideoRecording();

await controller.startVideoRecording();
sleep(const Duration(milliseconds: 500));
await controller.setDescription(cameras[1]);
sleep(const Duration(milliseconds: 500));

expect(controller.description, cameras[1]);
});

testWidgets('Set description', (WidgetTester tester) async {
final List<CameraDescription> cameras = await availableCameras();
if (cameras.length < 2) {
return;
}

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

await controller.initialize();
sleep(const Duration(milliseconds: 500));
await controller.setDescription(cameras[1]);
sleep(const Duration(milliseconds: 500));

expect(controller.description, cameras[1]);
});

testWidgets(
'iOS image streaming with imageFormatGroup',
(WidgetTester tester) async {
Expand Down
23 changes: 9 additions & 14 deletions packages/camera/camera/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
if (state == AppLifecycleState.inactive) {
cameraController.dispose();
} else if (state == AppLifecycleState.resumed) {
onNewCameraSelected(cameraController.description);
_initializeCameraController(cameraController.description);
}
}
// #enddocregion AppLifecycle
Expand Down Expand Up @@ -597,10 +597,7 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
title: Icon(getCameraLensIcon(cameraDescription.lensDirection)),
groupValue: controller?.description,
value: cameraDescription,
onChanged:
controller != null && controller!.value.isRecordingVideo
? null
: onChanged,
onChanged: onChanged,
),
),
);
Expand Down Expand Up @@ -633,17 +630,15 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
}

Future<void> onNewCameraSelected(CameraDescription cameraDescription) async {
final CameraController? oldController = controller;
if (oldController != null) {
// `controller` needs to be set to null before getting disposed,
// to avoid a race condition when we use the controller that is being
// disposed. This happens when camera permission dialog shows up,
// which triggers `didChangeAppLifecycleState`, which disposes and
// re-creates the controller.
controller = null;
await oldController.dispose();
if (controller != null) {
return controller!.setDescription(cameraDescription);
} else {
return _initializeCameraController(cameraDescription);
}
}

Future<void> _initializeCameraController(
CameraDescription cameraDescription) async {
final CameraController cameraController = CameraController(
cameraDescription,
kIsWeb ? ResolutionPreset.max : ResolutionPreset.medium,
Expand Down
38 changes: 32 additions & 6 deletions packages/camera/camera/lib/src/camera_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,15 @@ class CameraValue {
required this.exposurePointSupported,
required this.focusPointSupported,
required this.deviceOrientation,
required this.description,
this.lockedCaptureOrientation,
this.recordingOrientation,
this.isPreviewPaused = false,
this.previewPauseOrientation,
}) : _isRecordingPaused = isRecordingPaused;

/// Creates a new camera controller state for an uninitialized controller.
const CameraValue.uninitialized()
const CameraValue.uninitialized(CameraDescription description)
: this(
isInitialized: false,
isRecordingVideo: false,
Expand All @@ -70,6 +71,7 @@ class CameraValue {
focusPointSupported: false,
deviceOrientation: DeviceOrientation.portraitUp,
isPreviewPaused: false,
description: description,
);

/// True after [CameraController.initialize] has completed successfully.
Expand Down Expand Up @@ -143,6 +145,9 @@ class CameraValue {
/// The orientation of the currently running video recording.
final DeviceOrientation? recordingOrientation;

/// The properties of the camera device controlled by this controller.
final CameraDescription description;

/// Creates a modified copy of the object.
///
/// Explicitly specified fields get the specified value, all other fields get
Expand All @@ -164,6 +169,7 @@ class CameraValue {
Optional<DeviceOrientation>? lockedCaptureOrientation,
Optional<DeviceOrientation>? recordingOrientation,
bool? isPreviewPaused,
CameraDescription? description,
Optional<DeviceOrientation>? previewPauseOrientation,
}) {
return CameraValue(
Expand All @@ -188,6 +194,7 @@ class CameraValue {
? this.recordingOrientation
: recordingOrientation.orNull,
isPreviewPaused: isPreviewPaused ?? this.isPreviewPaused,
description: description ?? this.description,
previewPauseOrientation: previewPauseOrientation == null
? this.previewPauseOrientation
: previewPauseOrientation.orNull,
Expand All @@ -211,7 +218,8 @@ class CameraValue {
'lockedCaptureOrientation: $lockedCaptureOrientation, '
'recordingOrientation: $recordingOrientation, '
'isPreviewPaused: $isPreviewPaused, '
'previewPausedOrientation: $previewPauseOrientation)';
'previewPausedOrientation: $previewPauseOrientation, '
'description: $description)';
}
}

Expand All @@ -225,14 +233,14 @@ class CameraValue {
class CameraController extends ValueNotifier<CameraValue> {
/// Creates a new camera controller in an uninitialized state.
CameraController(
this.description,
CameraDescription description,
this.resolutionPreset, {
this.enableAudio = true,
this.imageFormatGroup,
}) : super(const CameraValue.uninitialized());
}) : super(CameraValue.uninitialized(description));

/// The properties of the camera device controlled by this controller.
final CameraDescription description;
CameraDescription get description => value.description;

/// The resolution this controller is targeting.
///
Expand Down Expand Up @@ -274,7 +282,12 @@ class CameraController extends ValueNotifier<CameraValue> {
/// Initializes the camera on the device.
///
/// Throws a [CameraException] if the initialization fails.
Future<void> initialize() async {
Future<void> initialize() => _initializeWithDescription(description);

/// Initializes the camera on the device with the specified description.
///
/// Throws a [CameraException] if the initialization fails.
Future<void> _initializeWithDescription(CameraDescription description) async {
if (_isDisposed) {
throw CameraException(
'Disposed CameraController',
Expand Down Expand Up @@ -313,6 +326,7 @@ class CameraController extends ValueNotifier<CameraValue> {

value = value.copyWith(
isInitialized: true,
description: description,
previewSize: await initializeCompleter.future
.then((CameraInitializedEvent event) => Size(
event.previewWidth,
Expand Down Expand Up @@ -380,6 +394,18 @@ class CameraController extends ValueNotifier<CameraValue> {
}
}

/// Sets the description of the camera.
///
/// Throws a [CameraException] if setting the description fails.
Future<void> setDescription(CameraDescription description) async {
if (value.isRecordingVideo) {
await CameraPlatform.instance.setDescriptionWhileRecording(description);
value = value.copyWith(description: description);
} else {
await _initializeWithDescription(description);
}
}

/// Captures an image and returns the file where it was saved.
///
/// Throws a [CameraException] if the capture fails.
Expand Down
12 changes: 10 additions & 2 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/plugins/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.3
version: 0.10.4

environment:
sdk: ">=2.14.0 <3.0.0"
Expand All @@ -23,7 +23,7 @@ flutter:
dependencies:
camera_android: ^0.10.1
camera_avfoundation: ^0.9.9
camera_platform_interface: ^2.3.2
camera_platform_interface: ^2.4.0
camera_web: ^0.3.1
flutter:
sdk: flutter
Expand All @@ -38,3 +38,11 @@ dev_dependencies:
mockito: ^5.0.0
plugin_platform_interface: ^2.0.0
video_player: ^2.0.0


# FOR TESTING ONLY. DO NOT MERGE.
dependency_overrides:
camera_android:
path: ../../camera/camera_android
camera_avfoundation:
path: ../../camera/camera_avfoundation
15 changes: 10 additions & 5 deletions packages/camera/camera/test/camera_preview_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ import 'package:flutter_test/flutter_test.dart';

class FakeController extends ValueNotifier<CameraValue>
implements CameraController {
FakeController() : super(const CameraValue.uninitialized());
FakeController() : super(const CameraValue.uninitialized(fakeDescription));

static const CameraDescription fakeDescription = CameraDescription(
name: '', lensDirection: CameraLensDirection.back, sensorOrientation: 0);

@override
Future<void> dispose() async {
Expand All @@ -29,10 +32,6 @@ class FakeController extends ValueNotifier<CameraValue>
@override
void debugCheckIsDisposed() {}

@override
CameraDescription get description => const CameraDescription(
name: '', lensDirection: CameraLensDirection.back, sensorOrientation: 0);

@override
bool get enableAudio => false;

Expand Down Expand Up @@ -117,6 +116,12 @@ class FakeController extends ValueNotifier<CameraValue>

@override
Future<void> resumePreview() async {}

@override
Future<void> setDescription(CameraDescription description) async {}

@override
CameraDescription get description => value.description;
}

void main() {
Expand Down
Loading