Custom Video Sources - React Native
Use a custom video track to control the quality of the video you send to the live stream.
This page uses the following asynchronous methods. Refer to their API reference for the errors each Promise may reject with, and handle these rejections appropriately based on your use case.
Custom Video Track
In a livestream, your camera feed plays a central role. With custom video tracks, you can:
- Define the resolution using encoder settings
- Choose the front or the back camera
- Send multiple resolutions, so each viewer gets the best quality their network allows
- Balance video quality against bandwidth, and choose the video codec
How to Create a Custom Video Track ?
- You can create a Custom Video Track using
createCameraVideoTrack()method of@videosdk.live/react-native-sdk. - This method enables the creation of a video track with various encoding parameters and camera facing modes, ultimately returning a
CustomStreamTrack. - The camera opens when you call this method, so you can preview the track before you go live. The method does not ask the user for camera access. Call
requestPermission()ofuseMediaDevice()first, or the Promise rejects withERROR_CAMERA_ACCESS_DENIED_OR_DISMISSED(3017). - If you don't pass the track to the live stream, call
stop()on it to close the camera.
Example
import { createCameraVideoTrack } from "@videosdk.live/react-native-sdk";
let customTrack = await createCameraVideoTrack({
// It will be the id of the camera from which the video should be captured.
cameraId:"camera-id", // OPTIONAL
// This will accept the resolution (height x width) of video you want to capture.
encoderConfig: "h480p_w640p", // "h540p_w960p" | "h720p_w1280p" ... // Default : "h720p_w1280p"
// For Mobile devices It will specify whether to use front or back camera for the video track.
facingMode: "back", // "front", Default : "front"
// This parameter will be discussed in the next step.
multiStream:true // false, Default : true
});
createCameraVideoTrack() also takes bitrateMode, maxLayer and codec. See Custom Tracks for every parameter and encoderConfig value.
The behavior of custom track configurations is influenced by the capabilities of the device. For example, if you set the encoder configuration to 1080p but the camera only supports 720p:
- On Android, the encoder configuration will automatically adjust to the highest resolution that the device can handle, which in this case is 720p.
- On iOS, VideoSDK captures at the highest resolution the camera supports and scales it up. The video is sent at 1080p, but it is not sharper than what the camera captured.
What is multiStream?
- By enabling multiStream, your livestream will broadcast multiple resolutions (e.g., 720p, 360p, 180p), allowing viewers to receive the best stream quality based on their network.
The
multiStream : trueconfiguration indicates that VideoSDK sends multiple resolution video streams to the server. For example, a1280x720track sends streams in1280x720,640x360and320x180resolution. Each participant receives the stream that fits their network bandwidth.

Setting multiStream : false sends only one stream, at one resolution, to every viewer.

multiStreamistrueby default for a track created withcreateCameraVideoTrack(). If you don't pass a custom track, the camera that VideoSDK opens for you takesmultiStreamfrom theconfigofRoomProviderinstead, where it also defaults totrue.
Refer to the Simulcast (Adaptive Bitrate) guide for the layers each encoderConfig sends.
The setQuality() method will not have any effect if multiStream is set to false.
How to Setup a Custom Video Track ?
You can plug in your custom video track either before going live or dynamically while the session is ongoing.
1. Setting up a Custom Track during the initialization of a room
If you're starting the stream with the webcam enabled (camEnabled: true) and wish to use a custom track from the beginning, pass it through the config of RoomProvider.
Custom Track will not apply on the camEnabled: false configuration. The track is not published, so call stop() on it if you no longer need it.
Example
import { useEffect, useState } from "react";
import {
Constants,
createCameraVideoTrack,
RoomProvider,
useMediaDevice,
} from "@videosdk.live/react-native-sdk";
function App() {
const { requestPermission } = useMediaDevice();
const getTrack = async () => {
// createCameraVideoTrack() does not ask for access, so ask first.
await requestPermission(Constants.permission.AUDIO_AND_VIDEO);
const track = await createCameraVideoTrack({
encoderConfig: "h720p_w960p",
facingMode: "back",
});
setCustomTrack(track);
};
let [customTrack, setCustomTrack] = useState(null);
useEffect(() => {
getTrack();
}, []);
return (
customTrack && (
<RoomProvider
config={{
roomId: "<roomId>",
participantName: "John Doe",
micEnabled: true,
//If true, it will use the passed custom track to turn webcam on
camEnabled: true,
//Pass the custom video track here
customCameraTrack: customTrack,
}}
token={token}
>
<RoomView />
</RoomProvider>
)
);
}
2. Setting up a Custom Track with methods
During the live stream, you can update the video source by passing the CustomStreamTrack into the enableCam() method from the useRoom hook.
Make sure to call the disableCam() method before you pass a new track to enableCam(). While the camera is on, enableCam() rejects with ERROR_ALREADY_IN_REQUESTED_STATE (3054). To replace the track while the camera is on, pass it to changeCam().
Example
import { createCameraVideoTrack, useRoom } from "@videosdk.live/react-native-sdk";
import { TouchableOpacity, Text } from "react-native";
const RoomControls = () => {
const { isCamEnabled, enableCam, disableCam } = useRoom();
const handleToggleWebcam = async () => {
if (isCamEnabled) {
try {
await disableCam();
} catch (err) {
console.error("disableCam failed:", err);
}
} else {
try {
const customTrack = await createCameraVideoTrack({
encoderConfig: "h720p_w960p",
facingMode: "back",
multiStream: false,
});
await enableCam(customTrack);
} catch (err) {
console.error("enableCam failed:", err);
}
}
};
return (
<TouchableOpacity onPress={handleToggleWebcam}>
<Text>{isCamEnabled ? "Turn camera off" : "Turn camera on"}</Text>
</TouchableOpacity>
);
};
Pass only tracks created with the createCameraVideoTrack() method. RoomProvider, enableCam() and changeCam() do not accept other objects. A stopped or released track is refused with ERROR_INVALID_CUSTOM_VIDEO_TRACK (3029).
API Reference
The API references for all the methods and events utilized in this guide are provided below.
Got a Question? Ask us on discord

