Camera Outputs

Understanding what Camera Outputs are and how to add them to a Camera Session

A CameraOutput is the base-class for all outputs a CameraDevice can stream to using a CameraSession. VisionCamera provides 5 core outputs:

Connecting a CameraOutput to a CameraSession

To connect a CameraOutput to a CameraSession, simply add it in the output connections array:

function App() {
  const output = ...

  return (
    <Camera
      style={StyleSheet.absoluteFill}
      isActive={true}
      device="back"
      outputs={[output]}
    />
  )
}
function App() {
  const output = ...

  const camera = useCamera({
    isActive: true,
    device: "back",
    outputs: [output],
  })
}
const session = await HybridCameraFactory.createCameraSession(false)
const device = await getDefaultCameraDevice('back')
const output = ...

await session.configure([
  {
    input: device,
    outputs: [
      { output: output, mirrorMode: 'auto' }
    ],
    config: {}
  }
], {})
await session.start()

After the CameraSession has been configured with the output, it becomes usable:

function App() {
  const output = ...

  return (
    <Camera
      style={StyleSheet.absoluteFill}
      isActive={true}
      device="back"
      outputs={[output]}
      onConfigured={() => {
        output.doSomething()
      }}
    />
  )
}
function App() {
  const output = ...

  const camera = useCamera({
    isActive: true,
    device: 'back',
    outputs: [output],
    onConfigured() {
      output.doSomething()
    }
  })
}
const session = await HybridCameraFactory.createCameraSession(false)
const device = await getDefaultCameraDevice('back')
const output = ...

await session.configure([
  {
    input: device,
    outputs: [
      { output: output, mirrorMode: 'auto' }
    ],
    config: {}
  }
], {})
await session.start()
output.doSomething()

Implementing a custom native CameraOutput

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 {
  // ...
}

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(...).