Implementing a custom native CameraOutput

Custom Swift/Kotlin CameraOutputs can be implemented in third-party code, and added to a CameraSession like any other output

Third-party libraries can implement the CameraOutput class in native code to build a custom camera output that can be connected to the Camera just like any other output. This is achieved using Nitro Modules Hybrid Object inheritance - simply implement the native HybridCameraOutputSpec, and conform to the NativeCameraOutput interface/protocol:

import AVFoundation
import VisionCamera

class MyCustomOutput: HybridCameraOutputSpec, NativeCameraOutput {
  // ...
}
import com.margelo.nitro.camera.HybridOutputSpec
import com.margelo.nitro.camera.public.NativeCameraOutput

class MyCustomOutput: HybridCameraOutputSpec(), NativeCameraOutput {
  // ...
}

Note

The NativeCameraOutput interface/protocol requires you to implement methods and properties that expose the actual native AVCaptureOutput/UseCase, which will get used by the CameraSession. Additionally, you can participate in resolution negotiations, and input/format requirements via these.

Then, create a Nitro Modules HybridObject that returns a CameraOutput:

import type { CameraOutput } from 'react-native-vision-camera'

export interface MyCustomOutputFactory {
  createMyCustomOutput(): CameraOutput
}

And finally, implement the createMyCustomOutput() method:

import AVFoundation
import VisionCamera

class MyCustomOutputFactory: HybridMyCustomOutputFactorySpec {
  func createMyCustomOutput() -> any HybridCameraOutputSpec {
    return MyCustomOutput()
  }
}
import com.margelo.nitro.camera.HybridOutputSpec
import com.margelo.nitro.camera.public.NativeCameraOutput

class MyCustomOutputFactory: HybridMyCustomOutputFactorySpec() {
  fun createMyCustomOutput(): HybridCameraOutputSpec {
    return MyCustomOutput()
  }
}

Now, if you create an instance of this output in JS, you can attach it to the Camera Session.

Note

This is how the VisionCamera Barcode Scanner (react-native-vision-camera-barcode-scanner) output is implemented - see: createBarcodeScannerOutput(...).