Other versions of this page
Multicam
Multi-camera support in the Camera SDK refers to the ability to use multiple cameras, for example one from the back and one from the front, at the same time. The SDK is able to:
- detect which cameras can be streamed at the same time
- configure them with proper resolution and frame rate
- compose the two streams on screen, using a layout arrangement of your choice
- let you take picture and videos
Concurrent cameras are available starting from API level 30.
Concurrent cameras are only available on devices running iOS 14+ with a A12 Bionic chip or later.
Device sets
The SDK abstracts the multi-camera complexity away with the CameraDeviceSet
class. Device sets work just like regular
CameraDevice
s: you can take pictures, snapshots and use them as a source for video recording. The only difference
is that you have dedicated APIs in CameraManager
.
Choosing a device set
To choose between regular devices, as explained in the devices documentation, you'd use
the property CameraManager.devices
. For device sets, simply use CameraManager.deviceSets
instead:
kotlinval manager: CameraManager = ...
val multicams: List<CameraDeviceSet> = manager.deviceSets
swiftlet manager: CameraManager = ...
let multicams: [CameraDeviceSet] = manager.deviceSets
If the returned list is empty, the current device does not support multi-camera captures.
Opening a device set
To open regular devices, as explained in the devices documentation, you'd use
the CameraManager.openDevice
function. For device sets, simply use CameraManager.openDeviceSet
instead:
kotlinsuspend fun openDeviceSet(id: String? = null): CameraDeviceSet = ...
swiftfunc openDeviceSet(id: String? = nil) async throws -> CameraDeviceSet { ... }
If no id
is provided, the engine will simply open the first available set.
Observing the current device set
To observe regular devices, as explained in the devices documentation, you'd use
the CameraManager.currentDevice
property. For device sets, simply use CameraManager.currentDeviceSet
instead:
kotlinval current: CameraDeviceSet? = manager.currentDeviceSet.value
val flow: StateFlow<CameraDeviceSet?> = manager.currentDeviceSet
swiftlet current: CameraDeviceSet? = manager.currentDeviceSet
let publisher: AnyPublisher<CameraDeviceSet?, Never> = manager.currentDeviceSetPublisher
Arrangement
With device sets, you have the option to choose how they will be composed on all the target surfaces: on screen, on picture and snapshot targets and on video outputs.
To do so, use the CameraDeviceSet.arrange()
function and pass one of the arrangement options above:
arrange(Arrangement.SplitVertically)
arrange(.splitVertically)
: screen is vertically split in half.arrange(Arrangement.SplitHorizontally)
arrange(.splitHorizontally)
: screen is horizontally split in half.arrange(Arrangement.Overlay(Shape.Oval, 1F))
arrange(.overlay(shape: .oval, aspectRatio: 1))
: one of the streams is fullscreen; the other is overlaid on top with the given shape and aspect ratio.
Flip
In some cases, especially when using Arrangement.Overlay
Arrangement.overlay
,
you may want to swap the streams (so that, for example, fullscreen stream becomes the small overlay). This can be done with the flip()
API:
kotlinmanager.currentDeviceSet?.flip()
swiftmanager.currentDeviceSet?.flip()
Unlike toggling between regular cameras, this operation is extremely fast.
Configuring constituent devices
By design, a CameraDeviceSet
has no notion of things like zoom or white balance,
because each sensor has different capabilities and constraints. However, you can access and configure the devices that
constitute a device set by using CameraDeviceSet.children
:
kotlinval (primary, secondary) = deviceSet.children
primary.configure { ... }
secondary.configure { ... }
swiftdeviceSet.children[0].configure { ... }
deviceSet.children[1].configure { ... }
Capturing media
Capturing media with CameraDeviceSet
is identical to CameraDevice
. Please check the regular documentation for
pictures and videos as it applies to device sets too. The only difference is that functions
must be invoked directly on the set:
- For pictures, use
CameraDeviceSet.takePicture(encoding: Picture.Encoding, meterIfNeeded: Boolean = true)
CameraDeviceSet.takePicture(encoding: Picture.Encoding, meterIfNeeded: Bool = true)
- For snapshots, use
CameraDeviceSet.takeSnapshot(encoding: Snapshot.Encoding)
- For videos, the
CameraRecorder
will automatically record from the current device set, if any of them is open