Skip to main content

Camera Capturer

The CameraCapturer class provides camera video capture functionality for iOS, macOS, tvOS, and visionOS platforms. It handles device selection, format selection, camera switching, and multitasking camera access.

Creating a Camera Track

The simplest way to create a camera track is using the convenience method:
let cameraTrack = LocalVideoTrack.createCameraTrack()
With custom options:
let options = CameraCaptureOptions(
    position: .front,
    dimensions: .h720_169,
    fps: 30
)
let cameraTrack = LocalVideoTrack.createCameraTrack(
    name: "camera",
    options: options
)

Camera Capture Options

CameraCaptureOptions

Configure camera capture behavior with the following properties:
PropertyTypeDefaultDescription
deviceTypeAVCaptureDevice.DeviceType?nilPreferred device type (not available on visionOS)
deviceAVCaptureDevice?nilExact device to use (overrides other selection)
positionAVCaptureDevice.Position.unspecifiedCamera position (.front, .back, .unspecified)
preferredFormatAVCaptureDevice.Format?nilExact capture format to use
dimensionsDimensions.h720_169Preferred capture dimensions
fpsInt30Preferred frames per second
let options = CameraCaptureOptions(
    deviceType: .builtInWideAngleCamera,
    position: .back,
    dimensions: .h1080_169,
    fps: 60
)

Device Management

Listing Available Cameras

let devices = try await CameraCapturer.captureDevices()
for device in devices {
    print("Device: \(device.localizedName), Position: \(device.position)")
}

Checking Camera Switching Support

let canSwitch = try await CameraCapturer.canSwitchPosition()
if canSwitch {
    print("Both front and back cameras available")
}

Switching Cameras

Toggle Between Front and Back

try await cameraCapturer.switchCameraPosition()

Set Specific Camera Position

try await cameraCapturer.set(cameraPosition: .front)

Update Options at Runtime

let newOptions = options.copyWith(
    dimensions: .value(.h1080_169),
    fps: .value(60)
)
try await cameraCapturer.set(options: newOptions)

Camera Properties

Current Device

Access the currently active camera device:
if let device = cameraCapturer.device {
    print("Using: \(device.localizedName)")
    print("Position: \(cameraCapturer.position)")
}

Capture Session

Access the underlying AVCaptureSession:
let session = cameraCapturer.captureSession

Multitasking Camera Access (iOS 16+)

On iOS 16 and later, you can enable multitasking camera access to continue capturing when your app is in the background:
if cameraCapturer.isMultitaskingAccessSupported {
    cameraCapturer.isMultitaskingAccessEnabled = true
}

Format Selection

The SDK automatically selects the best capture format based on your options. The selection process:
  1. If preferredFormat is specified, it’s used directly
  2. Otherwise, formats are filtered and ranked by:
    • Multi-cam support (if using multi-cam session)
    • Aspect ratio match
    • FPS support
    • Manhattan distance to target dimensions
  3. The closest matching format is selected
  4. FPS is clamped to the supported range if needed

Custom Format Selection

import AVFoundation

let device = try await CameraCapturer.captureDevices().first!
let formats = device.formats

// Find a specific format
let format = formats.first { format in
    let dimensions = CMVideoFormatDescriptionGetDimensions(format.formatDescription)
    return dimensions.width == 1920 && dimensions.height == 1080
}

let options = CameraCaptureOptions(
    device: device,
    preferredFormat: format
)

Multi-Camera Support (iOS/tvOS)

On devices that support multi-camera capture, the SDK can coordinate multiple camera capturers:
// The SDK automatically handles multi-cam compatibility
// when multiple camera tracks are active
let frontCamera = LocalVideoTrack.createCameraTrack(
    options: CameraCaptureOptions(position: .front)
)
let backCamera = LocalVideoTrack.createCameraTrack(
    options: CameraCaptureOptions(position: .back)
)

Video Processing

Apply custom video processing to camera frames:
class CustomProcessor: VideoProcessor {
    func process(frame: VideoFrame) -> VideoFrame? {
        // Apply custom processing
        return frame
    }
}

let processor = CustomProcessor()
let track = LocalVideoTrack.createCameraTrack(
    processor: processor
)

Platform Availability

  • iOS 13.0+
  • macOS 10.15+
  • tvOS 13.0+
  • visionOS 1.0+

See Also

Build docs developers (and LLMs) love