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

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'
})

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