From 880e038c59ed80186ac0c0d32f0a40c793936982 Mon Sep 17 00:00:00 2001 From: Adam Harwood Date: Fri, 7 Oct 2022 11:12:19 +1000 Subject: [PATCH 1/6] Add interface method to allow concurrent recording and streaming of video This has been factored out of https://github.com/flutter/plugins/pull/6290 to isolate the interface changes. They are not wired up yet, as per the instructions at https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-platform-interface-method-parameters. I created a separate options object to make the interface easier to work with. I chose `startVideoCapturing` as a more generic method name that can be applied to both recording and streaming. --- .../camera_platform_interface/CHANGELOG.md | 4 ++ .../platform_interface/camera_platform.dart | 12 +++++ .../lib/src/types/video_capture_options.dart | 52 +++++++++++++++++++ .../camera_platform_interface/pubspec.yaml | 2 +- 4 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart diff --git a/packages/camera/camera_platform_interface/CHANGELOG.md b/packages/camera/camera_platform_interface/CHANGELOG.md index d410304970cf..0b1955cbe172 100644 --- a/packages/camera/camera_platform_interface/CHANGELOG.md +++ b/packages/camera/camera_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.3.0 + +* Add new capture method for a camera to allow concurrent streaming and recording. + ## 2.2.2 * Updates code for `no_leading_underscores_for_local_identifiers` lint. diff --git a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart index b086dc87851f..d8f8f9ca4cc9 100644 --- a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart +++ b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart @@ -11,6 +11,7 @@ import 'package:plugin_platform_interface/plugin_platform_interface.dart'; import '../../camera_platform_interface.dart'; import '../method_channel/method_channel_camera.dart'; +import '../types/video_capture_options.dart'; /// The interface that implementations of camera must implement. /// @@ -131,10 +132,21 @@ abstract class CameraPlatform extends PlatformInterface { /// meaning the recording will continue until manually stopped. /// With [maxVideoDuration] set the video is returned in a [VideoRecordedEvent] /// through the [onVideoRecordedEvent] stream when the set duration is reached. + /// + /// This method is deprecated in favour of [startVideoCapturing]. Future startVideoRecording(int cameraId, {Duration? maxVideoDuration}) { throw UnimplementedError('startVideoRecording() is not implemented.'); } + /// Starts a video recording and/or streaming session. + /// + /// Please see [VideoCaptureOptions] for documentation on the + /// configuration options. + Future startVideoCapturing(VideoCaptureOptions options) { + return startVideoRecording(options.cameraId, + maxVideoDuration: options.maxDuration); + } + /// Stops the video recording and returns the file where it was saved. Future stopVideoRecording(int cameraId) { throw UnimplementedError('stopVideoRecording() is not implemented.'); diff --git a/packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart b/packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart new file mode 100644 index 000000000000..b40e7260c5ce --- /dev/null +++ b/packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart @@ -0,0 +1,52 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/foundation.dart'; + +import 'camera_image_data.dart'; + +/// Options wrapper for [CameraPlatform.startVideoCapturing] parameters. +@immutable +class VideoCaptureOptions { + /// Constructs a new instance. + const VideoCaptureOptions( + this.cameraId, { + this.maxDuration, + this.streamCallback, + this.streamOptions, + }); + + /// The ID of the camera to use for capturing. + final int cameraId; + + /// The maximum time to perform capturing for. + /// By default there is no maximum on the capture time. + final Duration? maxDuration; + + /// An optional callback to enable streaming. + /// If set, then each image captured by the camera will be + /// passed to this callback. + final Function(CameraImageData image)? streamCallback; + + /// Configuration options for streaming. + /// Should only be set if a streamCallback is also present. + final CameraImageStreamOptions? streamOptions; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is VideoCaptureOptions && + runtimeType == other.runtimeType && + cameraId == other.cameraId && + maxDuration == other.maxDuration && + streamCallback == other.streamCallback && + streamOptions == other.streamOptions; + + @override + int get hashCode => + cameraId.hashCode ^ + maxDuration.hashCode ^ + streamCallback.hashCode ^ + streamOptions.hashCode; +} diff --git a/packages/camera/camera_platform_interface/pubspec.yaml b/packages/camera/camera_platform_interface/pubspec.yaml index e87679261c5a..7ddc6d561aa4 100644 --- a/packages/camera/camera_platform_interface/pubspec.yaml +++ b/packages/camera/camera_platform_interface/pubspec.yaml @@ -4,7 +4,7 @@ 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 # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.2.2 +version: 2.3.0 environment: sdk: '>=2.12.0 <3.0.0' From b821ff61afd9d2c5e3fa11101d55535c40eb1dec Mon Sep 17 00:00:00 2001 From: adam-harwood <45190361+adam-harwood@users.noreply.github.com> Date: Wed, 19 Oct 2022 15:55:59 +1000 Subject: [PATCH 2/6] Update packages/camera/camera_platform_interface/CHANGELOG.md Change tense of CHANGELOG update Co-authored-by: Maurice Parrish <10687576+bparrishMines@users.noreply.github.com> --- packages/camera/camera_platform_interface/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/camera/camera_platform_interface/CHANGELOG.md b/packages/camera/camera_platform_interface/CHANGELOG.md index 0b1955cbe172..3bfc56f3f6e2 100644 --- a/packages/camera/camera_platform_interface/CHANGELOG.md +++ b/packages/camera/camera_platform_interface/CHANGELOG.md @@ -1,6 +1,6 @@ ## 2.3.0 -* Add new capture method for a camera to allow concurrent streaming and recording. +* Adds new capture method for a camera to allow concurrent streaming and recording. ## 2.2.2 From 68a0d050297d9519393072f28f12258fab5a546c Mon Sep 17 00:00:00 2001 From: Adam Harwood Date: Wed, 19 Oct 2022 15:58:30 +1000 Subject: [PATCH 3/6] A few tweaks from the code review --- .../lib/src/types/video_capture_options.dart | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart b/packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart index b40e7260c5ce..09f42fb8aaa2 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart @@ -21,6 +21,7 @@ class VideoCaptureOptions { final int cameraId; /// The maximum time to perform capturing for. + /// /// By default there is no maximum on the capture time. final Duration? maxDuration; @@ -45,8 +46,5 @@ class VideoCaptureOptions { @override int get hashCode => - cameraId.hashCode ^ - maxDuration.hashCode ^ - streamCallback.hashCode ^ - streamOptions.hashCode; + Object.hash(cameraId, maxDuration, streamCallback, streamOptions); } From 0fd25e756860ce05eb7e6156fa8deb6efb5c3646 Mon Sep 17 00:00:00 2001 From: Adam Harwood Date: Fri, 21 Oct 2022 10:51:56 +1000 Subject: [PATCH 4/6] Add some more newlines and add a check to ensure streamOptions fails if no streamCallback --- .../lib/src/types/video_capture_options.dart | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart b/packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart index 09f42fb8aaa2..e6e0234a3b20 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart @@ -10,12 +10,16 @@ import 'camera_image_data.dart'; @immutable class VideoCaptureOptions { /// Constructs a new instance. - const VideoCaptureOptions( + VideoCaptureOptions( this.cameraId, { this.maxDuration, this.streamCallback, this.streamOptions, - }); + }) { + if (streamOptions != null && streamCallback == null) { + throw ArgumentError('Must specify streamCallback if providing streamOptions'); + } + } /// The ID of the camera to use for capturing. final int cameraId; @@ -26,11 +30,13 @@ class VideoCaptureOptions { final Duration? maxDuration; /// An optional callback to enable streaming. + /// /// If set, then each image captured by the camera will be /// passed to this callback. final Function(CameraImageData image)? streamCallback; /// Configuration options for streaming. + /// /// Should only be set if a streamCallback is also present. final CameraImageStreamOptions? streamOptions; From 1dc2c7749e57b2498ea00b9a26b895ad2409f4a3 Mon Sep 17 00:00:00 2001 From: Adam Harwood Date: Fri, 21 Oct 2022 12:56:01 +1000 Subject: [PATCH 5/6] Run formatter --- .../lib/src/types/video_capture_options.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart b/packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart index e6e0234a3b20..7301d183dc8c 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart @@ -17,7 +17,8 @@ class VideoCaptureOptions { this.streamOptions, }) { if (streamOptions != null && streamCallback == null) { - throw ArgumentError('Must specify streamCallback if providing streamOptions'); + throw ArgumentError( + 'Must specify streamCallback if providing streamOptions'); } } From 9300ddd288268a27ed37510d776b15e997080026 Mon Sep 17 00:00:00 2001 From: Adam Harwood Date: Fri, 28 Oct 2022 10:39:31 +1000 Subject: [PATCH 6/6] Change VideoCaptureOptions to use assert instead of throw --- .../lib/src/types/video_capture_options.dart | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart b/packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart index 7301d183dc8c..9fcb7fa95379 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart @@ -10,17 +10,15 @@ import 'camera_image_data.dart'; @immutable class VideoCaptureOptions { /// Constructs a new instance. - VideoCaptureOptions( + const VideoCaptureOptions( this.cameraId, { this.maxDuration, this.streamCallback, this.streamOptions, - }) { - if (streamOptions != null && streamCallback == null) { - throw ArgumentError( - 'Must specify streamCallback if providing streamOptions'); - } - } + }) : assert( + streamOptions == null || streamCallback != null, + 'Must specify streamCallback if providing streamOptions.', + ); /// The ID of the camera to use for capturing. final int cameraId;