Skip to main content

Recording Videos

Camera Functions

The Camera provides certain functions which are available through a ref object:

function App() {
const camera = useRef<Camera>(null)
// ...

return (
<Camera
ref={camera}
{...cameraProps}
/>
)
}

To use these functions, you need to wait until the onInitialized event has been fired.

Recording Videos

To start a video recording you first have to enable video capture:

<Camera
{...props}
video={true}
audio={true} // <-- optional
/>

Then, simply use the Camera's startRecording(...) function:

camera.current.startRecording({
onRecordingFinished: (video) => console.log(video),
onRecordingError: (error) => console.error(error)
})

You can customize capture options such as video codec, video bit-rate, file type, enable flash and more using the RecordVideoOptions parameter.

For any error that occured while recording the video, the onRecordingError callback will be invoked with a CaptureError and the recording is therefore cancelled.

To stop the video recording, you can call stopRecording(...):

await camera.current.stopRecording()

Once a recording has been stopped, the onRecordingFinished callback passed to the stopRecording(...) function will be invoked with a VideoFile which you can then use to display in a <Video> component, uploaded to a backend, or saved to the Camera Roll using react-native-cameraroll.

Pause/Resume

To pause/resume the recordings, you can use pauseRecording() and resumeRecording():

await camera.current.pauseRecording()
...
await camera.current.resumeRecording()

Cancel

To cancel the recording, you can use cancelRecording(), which will stop the recording, delete the temporary video file and call the startRecording's onRecordingError callback with a capture/recording-canceled error.

await camera.current.cancelRecording()

Flash

The startRecording(...) function can be configured to enable the flash while recording, which natively just enables the torch under the hood:

camera.current.startRecording({
flash: 'on',
...
})

Note that flash is only available on camera devices where hasTorch is true; for example most front cameras don't have a torch.

Video Codec

By default, videos are recorded in the H.264 video codec which is a widely adopted video codec.

VisionCamera also supports H.265 (HEVC), which is much more efficient in encoding performance and can be up to 50% smaller in file size. If you can handle H.265 on your backend, configure the video recorder to encode in H.265:

camera.current.startRecording({
...props,
videoCodec: 'h265'
})
tip

If the device does not support h265, VisionCamera will automatically fall-back to a supported codec like h264 instead.

Video Bit Rate

Videos are recorded with a target bit-rate, which the encoder aims to match as closely as possible. A lower bit-rate means less quality (and less file size), a higher bit-rate means higher quality (and larger file size) since it can assign more bits to moving pixels.

To simply record videos with higher quality, use a videoBitRate of 'high', which effectively increases the bit-rate by 20%:

camera.current.startRecording({
...props,
videoBitRate: 'high'
})

To use a lower bit-rate for lower quality and lower file-size, use a videoBitRate of 'low', which effectively decreases the bit-rate by 20%:

camera.current.startRecording({
...props,
videoBitRate: 'low'
})

Custom Bit Rate

If you want to use a custom bit-rate, you first need to understand how bit-rate is calculated.

The bit-rate is a product of multiple factors such as resolution, FPS, pixel-format (HDR or non HDR), and video codec. As a good starting point, those are the recommended base bit-rates for their respective resolutions:

  • 480p: 2 Mbps
  • 720p: 5 Mbps
  • 1080p: 10 Mbps
  • 4K: 30 Mbps
  • 8K: 100 Mbps

These bit-rates assume a frame rate of 30 FPS, a non-HDR pixel-format, and a H.264 video codec.

To calculate your target bit-rate, you can use this formula:

let bitRate = baseBitRate
bitRate = bitRate / 30 * fps // FPS
if (videoHdr === true) bitRate *= 1.2 // 10-Bit Video HDR
if (codec === 'h265') bitRate *= 0.8 // H.265
bitRate *= yourCustomFactor // e.g. 0.5x for half the bit-rate

And then pass it to the startRecording(...) function (in Mbps):

camera.current.startRecording({
...props,
videoBitRate: bitRate // Mbps
})

Saving the Video to the Camera Roll

Since the Video is stored as a temporary file, you need save it to the Camera Roll to permanentely store it. You can use react-native-cameraroll for this:

camera.current.startRecording({
...props,
onRecordingFinished: (video) => {
const path = video.path
await CameraRoll.save(`file://${path}`, {
type: 'video',
})
},
})

🚀 Next section: QR/Barcode Scanning