diff --git a/docs/content/docs/multi-camera.mdx b/docs/content/docs/multi-camera.mdx
index 891037c7ac..e0b2abf273 100644
--- a/docs/content/docs/multi-camera.mdx
+++ b/docs/content/docs/multi-camera.mdx
@@ -5,7 +5,7 @@ description: Using multiple Camera Devices in a single Camera Session
import { Tab, Tabs } from 'fumadocs-ui/components/tabs'
-A [`CameraSession`](/api/react-native-vision-camera/hybrid-objects/CameraSession) allows attaching multiple connections to stream from multiple [`CameraDevice`](/api/react-native-vision-camera/hybrid-objects/CameraDevice)s at the same time - if the system supports it.
+A [`CameraSession`](/api/react-native-vision-camera/hybrid-objects/CameraSession) allows attaching multiple connections to stream from multiple [`CameraDevice`](/api/react-native-vision-camera/hybrid-objects/CameraDevice)s at the same time (e.g. Picture-in-Picture mode via front + back Camera) - if the system supports it.
### Creating a Multi-Camera Session
@@ -19,14 +19,35 @@ if (VisionCamera.supportsMultiCamSessions) {
### Using multiple Connections
-With a multi-cam [`CameraSession`](/api/react-native-vision-camera/hybrid-objects/CameraSession), you can now attach multiple [`CameraSessionConnection`](/api/react-native-vision-camera/interfaces/CameraSessionConnection)s - for example to stream and capture from the Front- and Back-Camera at the same time, attach both devices:
+Due to hardware constraints, not every [`CameraDevice`](/api/react-native-vision-camera/hybrid-objects/CameraDevice) can be paired with every other [`CameraDevice`](/api/react-native-vision-camera/hybrid-objects/CameraDevice) - therefore VisionCamera exposes a fixed array of supported combinations via [`CameraDeviceFactory.supportedMultiCamDeviceCombinations`](/api/react-native-vision-camera/hybrid-objects/CameraDeviceFactory#supportedmulticamdevicecombinations) upfront:
```ts
-const session = ...
-const frontDevice = useCameraDevice('front')
-const backDevice = useCameraDevice('back')
-const frontPreview = usePreviewOutput()
-const backPreview = usePreviewOutput()
+if (!VisionCamera.supportsMultiCamSessions)
+ return
+
+const deviceFactory = await VisionCamera.createDeviceFactory()
+const frontAndBackCombination =
+ deviceFactory.supportedMultiCamDeviceCombinations.find((devices) => {
+ return (
+ devices.some((d) => d.position === 'front') &&
+ devices.some((d) => d.position === 'back')
+ )
+ })
+if (frontAndBackCombination == null)
+ return
+
+const frontDevice = frontAndBackCombination.find((d) => d.position === 'front')
+const backDevice = frontAndBackCombination.find((d) => d.position === 'back')
+```
+
+Then, knowing `frontDevice` and `backDevice` can be used simultaneously in a Multi-Cam session, create the [`CameraSession`](/api/react-native-vision-camera/hybrid-objects/CameraSession), and attach the [`CameraSessionConnection`](/api/react-native-vision-camera/interfaces/CameraSessionConnection)s:
+
+```ts
+const session = await VisionCamera.createCameraSession(true)
+const frontPreviewOutput = VisionCamera.createPreviewOutput()
+const frontPhotoOutput = VisionCamera.createPhotoOutput({})
+const backPreviewOutput = VisionCamera.createPreviewOutput()
+const backPhotoOutput = VisionCamera.createPhotoOutput({})
const [frontController, backController] = await session.configure([
// Front Camera
@@ -51,6 +72,26 @@ const [frontController, backController] = await session.configure([
await session.start()
```
-Then, ensure you display both `frontPreview` and `backPreview` in separate [``](/api/react-native-vision-camera/views/NativePreviewView) views.
+Each returned [`CameraController`](/api/react-native-vision-camera/hybrid-objects/CameraController) correlates to the connection at that index - e.g. `frontController` allows zooming/exposure/focus the `frontDevice`, and vice-versa.
+
+Then, ensure you display both `frontPreviewOutput` and `backPreviewOutput` in separate [``](/api/react-native-vision-camera/views/NativePreviewView) views:
+
+```tsx
+function App() {
+ const frontPreviewOutput = ...
+ const backPreviewOutput = ...
-Each returned [`CameraController`](/api/react-native-vision-camera/hybrid-objects/CameraController) correlates to the connection at that index.
+ return (
+
+
+
+
+ )
+}
+```
diff --git a/packages/react-native-vision-camera/android/src/main/java/com/margelo/nitro/camera/HybridCameraDeviceFactory.kt b/packages/react-native-vision-camera/android/src/main/java/com/margelo/nitro/camera/HybridCameraDeviceFactory.kt
index ce693d37ce..5e700b83ac 100644
--- a/packages/react-native-vision-camera/android/src/main/java/com/margelo/nitro/camera/HybridCameraDeviceFactory.kt
+++ b/packages/react-native-vision-camera/android/src/main/java/com/margelo/nitro/camera/HybridCameraDeviceFactory.kt
@@ -38,6 +38,13 @@ class HybridCameraDeviceFactory(
override val cameraDevices: Array
get() = cameraProvider.availableCameraInfos.mapToArray { HybridCameraDevice(it) }
+ override val supportedMultiCamDeviceCombinations: Array>
+ get() {
+ return cameraProvider.availableConcurrentCameraInfos.mapToArray { devices ->
+ return@mapToArray devices.mapToArray { HybridCameraDevice(it) }
+ }
+ }
+
override var userPreferredCamera: HybridCameraDeviceSpec?
get() {
val preferredCameraId =
diff --git a/packages/react-native-vision-camera/ios/Hybrid Objects/HybridCameraDeviceFactory.swift b/packages/react-native-vision-camera/ios/Hybrid Objects/HybridCameraDeviceFactory.swift
index 37af6deab6..42ef2f8014 100644
--- a/packages/react-native-vision-camera/ios/Hybrid Objects/HybridCameraDeviceFactory.swift
+++ b/packages/react-native-vision-camera/ios/Hybrid Objects/HybridCameraDeviceFactory.swift
@@ -9,11 +9,6 @@ import Foundation
import NitroModules
class HybridCameraDeviceFactory: HybridCameraDeviceFactorySpec {
- let discoverySession: AVCaptureDevice.DiscoverySession
- var cameraDevices: [any HybridCameraDeviceSpec] {
- return discoverySession.devices.map { HybridCameraDevice(device: $0) }
- }
-
override init() {
self.discoverySession = AVCaptureDevice.DiscoverySession(
deviceTypes: AVCaptureDevice.DeviceType.all,
@@ -22,6 +17,17 @@ class HybridCameraDeviceFactory: HybridCameraDeviceFactorySpec {
super.init()
}
+ let discoverySession: AVCaptureDevice.DiscoverySession
+ var cameraDevices: [any HybridCameraDeviceSpec] {
+ return discoverySession.devices.map { HybridCameraDevice(device: $0) }
+ }
+
+ var supportedMultiCamDeviceCombinations: [[any HybridCameraDeviceSpec]] {
+ return discoverySession.supportedMultiCamDeviceSets.map { devices in
+ return devices.map { HybridCameraDevice(device: $0) }
+ }
+ }
+
var userPreferredCamera: (any HybridCameraDeviceSpec)? {
get {
guard #available(iOS 17.0, *) else {
@@ -36,7 +42,7 @@ class HybridCameraDeviceFactory: HybridCameraDeviceFactorySpec {
guard #available(iOS 17.0, *) else {
return
}
- guard let hybridDevice = newValue as? HybridCameraDevice else {
+ guard let hybridDevice = newValue as? any NativeCameraDevice else {
return
}
AVCaptureDevice.userPreferredCamera = hybridDevice.device
diff --git a/packages/react-native-vision-camera/nitrogen/generated/android/c++/JHybridCameraDeviceFactorySpec.cpp b/packages/react-native-vision-camera/nitrogen/generated/android/c++/JHybridCameraDeviceFactorySpec.cpp
index 3f96d33a4d..f0256d7dd8 100644
--- a/packages/react-native-vision-camera/nitrogen/generated/android/c++/JHybridCameraDeviceFactorySpec.cpp
+++ b/packages/react-native-vision-camera/nitrogen/generated/android/c++/JHybridCameraDeviceFactorySpec.cpp
@@ -88,6 +88,29 @@ namespace margelo::nitro::camera {
static const auto method = _javaPart->javaClassStatic()->getMethod /* userPreferredCamera */)>("setUserPreferredCamera");
method(_javaPart, userPreferredCamera.has_value() ? std::dynamic_pointer_cast(userPreferredCamera.value())->getJavaPart() : nullptr);
}
+ std::vector>> JHybridCameraDeviceFactorySpec::getSupportedMultiCamDeviceCombinations() {
+ static const auto method = _javaPart->javaClassStatic()->getMethod>>()>("getSupportedMultiCamDeviceCombinations");
+ auto __result = method(_javaPart);
+ return [&]() {
+ size_t __size = __result->size();
+ std::vector>> __vector;
+ __vector.reserve(__size);
+ for (size_t __i = 0; __i < __size; __i++) {
+ auto __element = __result->getElement(__i);
+ __vector.push_back([&]() {
+ size_t __size = __element->size();
+ std::vector> __vector;
+ __vector.reserve(__size);
+ for (size_t __i = 0; __i < __size; __i++) {
+ auto __element = __element->getElement(__i);
+ __vector.push_back(__element->getJHybridCameraDeviceSpec());
+ }
+ return __vector;
+ }());
+ }
+ return __vector;
+ }();
+ }
// Methods
ListenerSubscription JHybridCameraDeviceFactorySpec::addOnCameraDevicesChangedListener(const std::function>& /* newDevices */)>& listener) {
diff --git a/packages/react-native-vision-camera/nitrogen/generated/android/c++/JHybridCameraDeviceFactorySpec.hpp b/packages/react-native-vision-camera/nitrogen/generated/android/c++/JHybridCameraDeviceFactorySpec.hpp
index df9b7b23c1..19a60bea95 100644
--- a/packages/react-native-vision-camera/nitrogen/generated/android/c++/JHybridCameraDeviceFactorySpec.hpp
+++ b/packages/react-native-vision-camera/nitrogen/generated/android/c++/JHybridCameraDeviceFactorySpec.hpp
@@ -53,6 +53,7 @@ namespace margelo::nitro::camera {
std::vector> getCameraDevices() override;
std::optional> getUserPreferredCamera() override;
void setUserPreferredCamera(const std::optional>& userPreferredCamera) override;
+ std::vector>> getSupportedMultiCamDeviceCombinations() override;
public:
// Methods
diff --git a/packages/react-native-vision-camera/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/HybridCameraDeviceFactorySpec.kt b/packages/react-native-vision-camera/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/HybridCameraDeviceFactorySpec.kt
index f610aeb748..b41306e76c 100644
--- a/packages/react-native-vision-camera/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/HybridCameraDeviceFactorySpec.kt
+++ b/packages/react-native-vision-camera/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/HybridCameraDeviceFactorySpec.kt
@@ -35,6 +35,10 @@ abstract class HybridCameraDeviceFactorySpec: HybridObject() {
@set:DoNotStrip
@set:Keep
abstract var userPreferredCamera: HybridCameraDeviceSpec?
+
+ @get:DoNotStrip
+ @get:Keep
+ abstract val supportedMultiCamDeviceCombinations: Array>
// Methods
abstract fun addOnCameraDevicesChangedListener(listener: (newDevices: Array) -> Unit): ListenerSubscription
diff --git a/packages/react-native-vision-camera/nitrogen/generated/ios/VisionCamera-Swift-Cxx-Bridge.hpp b/packages/react-native-vision-camera/nitrogen/generated/ios/VisionCamera-Swift-Cxx-Bridge.hpp
index 5bde895e9d..5abcd00279 100644
--- a/packages/react-native-vision-camera/nitrogen/generated/ios/VisionCamera-Swift-Cxx-Bridge.hpp
+++ b/packages/react-native-vision-camera/nitrogen/generated/ios/VisionCamera-Swift-Cxx-Bridge.hpp
@@ -1426,6 +1426,17 @@ namespace margelo::nitro::camera::bridge::swift {
return Result::withError(error);
}
+ // pragma MARK: std::vector>>
+ /**
+ * Specialized version of `std::vector>>`.
+ */
+ using std__vector_std__vector_std__shared_ptr_HybridCameraDeviceSpec___ = std::vector>>;
+ inline std::vector>> create_std__vector_std__vector_std__shared_ptr_HybridCameraDeviceSpec___(size_t size) noexcept {
+ std::vector>> vector;
+ vector.reserve(size);
+ return vector;
+ }
+
// pragma MARK: std::function>& /* newDevices */)>
/**
* Specialized version of `std::function>&)>`.
diff --git a/packages/react-native-vision-camera/nitrogen/generated/ios/c++/HybridCameraDeviceFactorySpecSwift.hpp b/packages/react-native-vision-camera/nitrogen/generated/ios/c++/HybridCameraDeviceFactorySpecSwift.hpp
index a13436fca5..f166161e87 100644
--- a/packages/react-native-vision-camera/nitrogen/generated/ios/c++/HybridCameraDeviceFactorySpecSwift.hpp
+++ b/packages/react-native-vision-camera/nitrogen/generated/ios/c++/HybridCameraDeviceFactorySpecSwift.hpp
@@ -89,6 +89,10 @@ namespace margelo::nitro::camera {
inline void setUserPreferredCamera(const std::optional>& userPreferredCamera) noexcept override {
_swiftPart.setUserPreferredCamera(userPreferredCamera);
}
+ inline std::vector>> getSupportedMultiCamDeviceCombinations() noexcept override {
+ auto __result = _swiftPart.getSupportedMultiCamDeviceCombinations();
+ return __result;
+ }
public:
// Methods
diff --git a/packages/react-native-vision-camera/nitrogen/generated/ios/swift/HybridCameraDeviceFactorySpec.swift b/packages/react-native-vision-camera/nitrogen/generated/ios/swift/HybridCameraDeviceFactorySpec.swift
index 62708a1149..ce0ba0d904 100644
--- a/packages/react-native-vision-camera/nitrogen/generated/ios/swift/HybridCameraDeviceFactorySpec.swift
+++ b/packages/react-native-vision-camera/nitrogen/generated/ios/swift/HybridCameraDeviceFactorySpec.swift
@@ -12,6 +12,7 @@ public protocol HybridCameraDeviceFactorySpec_protocol: HybridObject {
// Properties
var cameraDevices: [(any HybridCameraDeviceSpec)] { get }
var userPreferredCamera: (any HybridCameraDeviceSpec)? { get set }
+ var supportedMultiCamDeviceCombinations: [[(any HybridCameraDeviceSpec)]] { get }
// Methods
func addOnCameraDevicesChangedListener(listener: @escaping (_ newDevices: [(any HybridCameraDeviceSpec)]) -> Void) throws -> ListenerSubscription
diff --git a/packages/react-native-vision-camera/nitrogen/generated/ios/swift/HybridCameraDeviceFactorySpec_cxx.swift b/packages/react-native-vision-camera/nitrogen/generated/ios/swift/HybridCameraDeviceFactorySpec_cxx.swift
index 658132f915..ae6fb283ad 100644
--- a/packages/react-native-vision-camera/nitrogen/generated/ios/swift/HybridCameraDeviceFactorySpec_cxx.swift
+++ b/packages/react-native-vision-camera/nitrogen/generated/ios/swift/HybridCameraDeviceFactorySpec_cxx.swift
@@ -167,6 +167,28 @@ open class HybridCameraDeviceFactorySpec_cxx {
}()
}
}
+
+ public final var supportedMultiCamDeviceCombinations: bridge.std__vector_std__vector_std__shared_ptr_HybridCameraDeviceSpec___ {
+ @inline(__always)
+ get {
+ return { () -> bridge.std__vector_std__vector_std__shared_ptr_HybridCameraDeviceSpec___ in
+ var __vector = bridge.create_std__vector_std__vector_std__shared_ptr_HybridCameraDeviceSpec___(self.__implementation.supportedMultiCamDeviceCombinations.count)
+ for __item in self.__implementation.supportedMultiCamDeviceCombinations {
+ __vector.push_back({ () -> bridge.std__vector_std__shared_ptr_HybridCameraDeviceSpec__ in
+ var __vector = bridge.create_std__vector_std__shared_ptr_HybridCameraDeviceSpec__(__item.count)
+ for __item in __item {
+ __vector.push_back({ () -> bridge.std__shared_ptr_HybridCameraDeviceSpec_ in
+ let __cxxWrapped = __item.getCxxWrapper()
+ return __cxxWrapped.getCxxPart()
+ }())
+ }
+ return __vector
+ }())
+ }
+ return __vector
+ }()
+ }
+ }
// Methods
@inline(__always)
diff --git a/packages/react-native-vision-camera/nitrogen/generated/shared/c++/HybridCameraDeviceFactorySpec.cpp b/packages/react-native-vision-camera/nitrogen/generated/shared/c++/HybridCameraDeviceFactorySpec.cpp
index d50c1b5a4f..f0435f7356 100644
--- a/packages/react-native-vision-camera/nitrogen/generated/shared/c++/HybridCameraDeviceFactorySpec.cpp
+++ b/packages/react-native-vision-camera/nitrogen/generated/shared/c++/HybridCameraDeviceFactorySpec.cpp
@@ -17,6 +17,7 @@ namespace margelo::nitro::camera {
prototype.registerHybridGetter("cameraDevices", &HybridCameraDeviceFactorySpec::getCameraDevices);
prototype.registerHybridGetter("userPreferredCamera", &HybridCameraDeviceFactorySpec::getUserPreferredCamera);
prototype.registerHybridSetter("userPreferredCamera", &HybridCameraDeviceFactorySpec::setUserPreferredCamera);
+ prototype.registerHybridGetter("supportedMultiCamDeviceCombinations", &HybridCameraDeviceFactorySpec::getSupportedMultiCamDeviceCombinations);
prototype.registerHybridMethod("addOnCameraDevicesChangedListener", &HybridCameraDeviceFactorySpec::addOnCameraDevicesChangedListener);
prototype.registerHybridMethod("getCameraForId", &HybridCameraDeviceFactorySpec::getCameraForId);
prototype.registerHybridMethod("getSupportedExtensions", &HybridCameraDeviceFactorySpec::getSupportedExtensions);
diff --git a/packages/react-native-vision-camera/nitrogen/generated/shared/c++/HybridCameraDeviceFactorySpec.hpp b/packages/react-native-vision-camera/nitrogen/generated/shared/c++/HybridCameraDeviceFactorySpec.hpp
index 823a998870..cde15be396 100644
--- a/packages/react-native-vision-camera/nitrogen/generated/shared/c++/HybridCameraDeviceFactorySpec.hpp
+++ b/packages/react-native-vision-camera/nitrogen/generated/shared/c++/HybridCameraDeviceFactorySpec.hpp
@@ -63,6 +63,7 @@ namespace margelo::nitro::camera {
virtual std::vector> getCameraDevices() = 0;
virtual std::optional> getUserPreferredCamera() = 0;
virtual void setUserPreferredCamera(const std::optional>& userPreferredCamera) = 0;
+ virtual std::vector>> getSupportedMultiCamDeviceCombinations() = 0;
public:
// Methods
diff --git a/packages/react-native-vision-camera/src/specs/inputs/CameraDeviceFactory.nitro.ts b/packages/react-native-vision-camera/src/specs/inputs/CameraDeviceFactory.nitro.ts
index 0a6f3c0852..6d04537536 100644
--- a/packages/react-native-vision-camera/src/specs/inputs/CameraDeviceFactory.nitro.ts
+++ b/packages/react-native-vision-camera/src/specs/inputs/CameraDeviceFactory.nitro.ts
@@ -1,4 +1,5 @@
import type { HybridObject } from 'react-native-nitro-modules'
+import type { CameraFactory } from '../CameraFactory.nitro'
import type { CameraPosition } from '../common-types/CameraPosition'
import type { ListenerSubscription } from '../common-types/ListenerSubscription'
import type { CameraSession } from '../session/CameraSession.nitro'
@@ -12,8 +13,12 @@ import type { CameraExtension } from './CameraExtension.nitro'
export interface CameraDeviceFactory
extends HybridObject<{ ios: 'swift'; android: 'kotlin' }> {
/**
- * Get a list of all devices.
- * This list may change as camera devices get plugged in/out.
+ * Get a list of all {@linkcode CameraDevice}s on this platform.
+ *
+ * This list may change as {@linkcode CameraDevice}s get plugged in/out (e.g.
+ * {@linkcode CameraPosition | 'external'} Cameras via USB/UVC), devices
+ * become available/unavailable (e.g. continuity Cameras), or Camera positions
+ * change (e.g. on foldable phones).
*/
readonly cameraDevices: CameraDevice[]
/**
@@ -22,6 +27,64 @@ export interface CameraDeviceFactory
*/
userPreferredCamera?: CameraDevice
+ /**
+ * A list of all {@linkcode CameraDevice} combinations that are supported
+ * in Multi-Cam {@linkcode CameraSession}s.
+ *
+ * This list always contains a subset of {@linkcode cameraDevices}, often
+ * less.
+ *
+ * @discussion
+ * For example, on many platforms only a {@linkcode CameraPosition | 'front'}
+ * and a {@linkcode CameraPosition | 'back'} {@linkcode CameraDevice} are
+ * supported to be used in a Multi-Cam {@linkcode CameraSession} - in this case,
+ * the returned 2D Array looks something like this:
+ * ```
+ * [
+ * [{ position: 'back', ... }, { position: 'front', ... }]
+ * ]
+ * ```
+ * Two {@linkcode CameraPosition | 'back'}-, or two {@linkcode CameraPosition | 'front'}
+ * {@linkcode CameraDevice}s are often not supported together in a Multi-Cam
+ * {@linkcode CameraSession}.
+ *
+ * When creating a Multi-Cam {@linkcode CameraSession}, you must ensure
+ * that you are using Device combinations that are actually supported
+ * on the platform, otherwise the session might fail to configure.
+ *
+ * @discussion
+ * If the platform does not support Multi-Cam {@linkcode CameraSession}s,
+ * an empty array (`[]`) will be returned.
+ *
+ *
+ * @example
+ * ```ts
+ * if (VisionCamera.supportsMultiCamSessions) {
+ * const deviceFactory = await VisionCamera.createDeviceFactory()
+ * const deviceCombinations = deviceFactory.supportedMultiCamDeviceCombinations[0]
+ * if (deviceCombinations != null) {
+ * const connections = deviceCombinations.map((device) => {
+ * const previewOutput = VisionCamera.createPreviewOutput()
+ * return {
+ * input: device,
+ * outputs: [
+ * { output: previewOutput, mirrorMode: 'auto' }
+ * ],
+ * constraints: []
+ * } satisfies CameraSessionConnection
+ * })
+ *
+ * const session = await VisionCamera.createCameraSession(true)
+ * const controllers = await session.configure(connections)
+ * await session.start()
+ * }
+ * }
+ * ```
+ *
+ * @see {@linkcode CameraFactory.supportsMultiCamSessions}
+ */
+ readonly supportedMultiCamDeviceCombinations: CameraDevice[][]
+
/**
* Add a listener to be called whenever the
* available {@linkcode cameraDevices} change,
diff --git a/packages/react-native-vision-camera/src/specs/session/CameraSession.nitro.ts b/packages/react-native-vision-camera/src/specs/session/CameraSession.nitro.ts
index 6b19b9ab29..8390dac2b9 100644
--- a/packages/react-native-vision-camera/src/specs/session/CameraSession.nitro.ts
+++ b/packages/react-native-vision-camera/src/specs/session/CameraSession.nitro.ts
@@ -68,6 +68,10 @@ export type InterruptionReason =
* and back-Camera using the imperative API:
* ```ts
* if (VisionCamera.supportsMultiCamSessions) {
+ * const deviceFactory = await VisionCamera.createDeviceFactory()
+ * const deviceCombinations = deviceFactory.supportedMultiCamDeviceCombinations
+ * // ... get `frontDevice` and `backDevice` from one of
+ * // the combinations in `deviceCombinations`.
* const session = await VisionCamera.createCameraSession(true)
* const [frontController, backController] = await session.configure([
* // Front Camera
@@ -110,6 +114,12 @@ export interface CameraSession
* from one {@linkcode CameraDevice} (the _input_) to multiple
* {@linkcode CameraOutput}s (the _outputs_).
*
+ * @note In a Multi-Cam Camera Session, the given {@linkcode connections}' input devices
+ * must be supported to be used together in a Multi-Cam Camera Session, as not every
+ * {@linkcode CameraDevice} can be used with every other {@linkcode CameraDevice}
+ * simultaneously. See {@linkcode CameraDeviceFactory.supportedMultiCamDeviceCombinations}
+ * for a full list of supported combinations.
+ *
* @param connections The list of connections from one _input_ to
* multiple _outputs_. If this {@linkcode CameraSession} was created
* as a multi-cam session (see {@linkcode CameraFactory.createCameraSession | createCameraSession(enableMultiCam)}),
@@ -122,6 +132,9 @@ export interface CameraSession
* @throws If Camera Permission has not been granted - see {@linkcode CameraFactory.cameraPermissionStatus}
* @throws If multiple {@linkcode connections} are added, but the
* {@linkcode CameraSession} was not created as a multi-cam session.
+ * @throws If hardware resources are being exhausted by too large connection graphs.
+ * @throws If this is a Multi-Cam session, but the connection inputs are not supported to
+ * be used together - see {@linkcode CameraDeviceFactory.supportedMultiCamDeviceCombinations}
*
* @example
* Creating a simple Preview + Photo connection:
@@ -162,6 +175,10 @@ export interface CameraSession
* Creating a multi-cam session with front- and back Camera:
* ```ts
* if (VisionCamera.supportsMultiCamSessions) {
+ * const deviceFactory = await VisionCamera.createDeviceFactory()
+ * const deviceCombinations = deviceFactory.supportedMultiCamDeviceCombinations
+ * // ... get `frontDevice` and `backDevice` from one of
+ * // the combinations in `deviceCombinations`.
* const session = await VisionCamera.createCameraSession(true)
* const [frontController, backController] = await session.configure([
* // Front Camera