[camera] Interface method to allow concurrent recording and streaming of video (#6550)

diff --git a/packages/camera/camera_platform_interface/CHANGELOG.md b/packages/camera/camera_platform_interface/CHANGELOG.md
index d410304..3bfc56f 100644
--- a/packages/camera/camera_platform_interface/CHANGELOG.md
+++ b/packages/camera/camera_platform_interface/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 2.3.0
+
+* Adds 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 b086dc8..d8f8f9c 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 '../../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 @@
   /// 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<void> 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<void> startVideoCapturing(VideoCaptureOptions options) {
+    return startVideoRecording(options.cameraId,
+        maxVideoDuration: options.maxDuration);
+  }
+
   /// Stops the video recording and returns the file where it was saved.
   Future<XFile> 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 0000000..9fcb7fa
--- /dev/null
+++ b/packages/camera/camera_platform_interface/lib/src/types/video_capture_options.dart
@@ -0,0 +1,55 @@
+// 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,
+  }) : assert(
+          streamOptions == null || streamCallback != null,
+          'Must specify streamCallback if providing 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 =>
+      Object.hash(cameraId, maxDuration, streamCallback, streamOptions);
+}
diff --git a/packages/camera/camera_platform_interface/pubspec.yaml b/packages/camera/camera_platform_interface/pubspec.yaml
index e876792..7ddc6d5 100644
--- a/packages/camera/camera_platform_interface/pubspec.yaml
+++ b/packages/camera/camera_platform_interface/pubspec.yaml
@@ -4,7 +4,7 @@
 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'