Skip to main content

You are looking at Video Calling v3.x Docs. The newest version is  Video Calling 4.x

Android
iOS
macOS
Windows C++
Windows C#
Unity
Flutter
React Native
Electron
Cocos Creator
Cocos2d-x

Start a Video Call

This article describes how to build a React Native project that implements the video call function using the Agora React Native SDK.

Understand the tech

The following figure shows the workflow to integrate into your app in order to add Video Call functionality.

1627550978702

As shown in the figure, the workflow for adding Video Call in your project is as follows:

  1. Retrieve a token A token is the credential that authenticates a user when your app client joins a channel. In a test or production environment, your app client retrieves tokens from a server in your security infrastructure.

  2. Join a channel Call joinChannel to create and join a channel. App clients that pass the same channel name join the same channel.

  3. Publish and subscribe to audio and video in the channel After joining a channel, the app client automatically publishes and subscribes to audio and video in the channel.

For an app client to join a channel, you need the following information:

  • The App ID: A randomly generated string provided by Agora for identifying your app. You can get the App ID from Agora Console.
  • The user ID: The unique identifier of a user. You need to specify the user ID yourself, and ensure that it is unique in the channel.
  • A token: In a test or production environment, your app client retrieves tokens from a server in your security infrastructure. For this page, you use a temporary token with a validity period of 24 hours that you retrieve from Agora Console.
  • The channel name: A string that identifies the channel for the video call.

Sample project

Agora provides an open-source sample project API-Example-ReactNative on GitHub that implements interactive live audio and video streaming. You can download it and view the source code.

Prerequisites

Development environment

If your target platform is iOS, your development environment must meet the following requirements:

  • React Native 0.59.10 or later
  • macOS
  • Node 10 or later
  • Xcode 9.4 or later
  • CocoaPods
  • A physical or virtual mobile device running iOS 9.0 or later

If your target platform is Android, your development environment must meet the following requirements:

  • React Native 0.59.10 or later
  • macOS, Windows, or Linux
  • Node 10 or later
  • Java Development Kit (JDK) 8 or later
  • Android Studio (latest version recommended)
  • A physical or virtual mobile device running Android 5.0 or later
    For more information, see Setting up the development environment.

Other prerequisites

A valid Agora account..

If your network has a firewall, follow the instructions in Firewall Requirements to access Agora's services.

Create a React Native project

  1. Make sure you have set up the development environment based on your operating system and target platform.

  2. Run the following command and fill in your project name in ProjectName to create and initialize a new React Native project.

    npx react-native init ProjectName
    Copy

    A successful execution of this command generates a simple sample project in the directory that you run the command.

  3. Launch your Android or iOS simulator and run your project by executing the following command:

    1. Run npx react-native start in the root of your project to start Metro.
    2. Open another terminal in the root of your project and run npx react-native run-android to start the Android app, or run npx react-native run-ios to start the iOS app.

If everything is set up correctly, you should see your new app running in your Android or iOS simulator shortly.

You can also run your project on a physical Android or iOS device. For detailed instructions, see Running on device.

Now that you have your project running successfully, you can start trying to integrate the Agora React Native SDK and modify your project.

Integrate the SDK

This section describes how to integrate the SDK on React Native 0.60.0 or later.

If you use React Native 0.59.x, see Installing (React Native == 0.59.x) to integrate the Agora SDK.
  1. Install the latest version of the Agora React Native SDK:

    Method one: Install the SDK using npm

    npm i --save react-native-agora
    Copy

    Method two: Install the SDK using yarn

    // Install yarn.
    npm install -g yarn

    // Download the Agora React Native SDK using yarn.
    yarn add react-native-agora
    Copy
    Do not link native modules manually, as React Native 0.60.0 and later support automatically linking native modules. For details, see Autolinking.
  2. If your target platform is iOS, you also need to run the following command to install the SDK:

    npx pod-install
    Copy
    Ensure that you have already installed CocoaPods before performing this step. See Getting Started with CocoaPods.
  3. The Agora React Native SDK uses Swift in native modules, and therefore your project must support compiling Swift. Otherwise, you will get errors when building the iOS app.

    1. Open ios/ProjectName.xcworkspace with Xcode.
    2. Click File > New > File, select iOS > Swift File, and then click Next > Create to create a new File.swift file.

Add TypeScript

The sample code in this article is written in TypeScript. If you want to use this sample code directly, you need to add support for TypeScript to your project.

  1. Run one of the following commands in the root of your project to add TypeScript dependencies:

    Method one: Using npm

    npm install --save-dev typescript @types/jest @types/react @types/react-native @types/react-test-renderer
    Copy

    Method two: Using yarn

    yarn add --dev typescript @types/jest @types/react @types/react-native @types/react-test-renderer
    Copy
  2. Create a tsconfig.json file in the root of your project, and copy the following code to the file:

    {
    "compilerOptions": {
    "allowJs": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "isolatedModules": true,
    "jsx": "react",
    "lib": ["es6"],
    "moduleResolution": "node",
    "noEmit": true,
    "strict": true,
    "target": "esnext"
    },
    "exclude": [
    "node_modules",
    "babel.config.js",
    "metro.config.js",
    "jest.config.js"
    ]
    }
    Copy
  3. Create a jest.config.js file in the root of your project, and copy the following code to the file:

    module.exports = {
    preset: 'react-native',
    moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node']
    };
    Copy
  4. Rename App.js to App.tsx.

For more information, see Using TypeScript.

Implementation

1. Create the UI

Create the user interface (UI) for the video call in the layout file of your project.

For a video call, we recommend adding the following elements into the UI:

  • The start-call button
  • The end-call button
  • The local video view
  • The remote video view

The components/Style.ts file in the Agora-RN-Quickstart sample project defines the styles of the UI elements. You can create a components folder for your project, add a Style.ts file under that folder, and then copy the following code to the file:

import {Dimensions, StyleSheet} from 'react-native'

const dimensions = {
width: Dimensions.get('window').width,
height: Dimensions.get('window').height,
}

export default StyleSheet.create({
max: {
flex: 1,
},
buttonHolder: {
height: 100,
alignItems: 'center',
flex: 1,
flexDirection: 'row',
justifyContent: 'space-evenly',
},
button: {
paddingHorizontal: 20,
paddingVertical: 10,
backgroundColor: '#0093E9',
borderRadius: 25,
},
buttonText: {
color: '#fff',
},
fullView: {
width: dimensions.width,
height: dimensions.height - 100,
},
remoteContainer: {
width: '100%',
height: 150,
position: 'absolute',
top: 5
},
remote: {
width: 150,
height: 150,
marginHorizontal: 2.5
},
noUserText: {
paddingHorizontal: 10,
paddingVertical: 5,
color: '#0093E9',
},
})
Copy

2. Import classes

Open the App.tsx file, and delete all code. Add the following code to the beginning of the App.tsx file:

import React, {Component} from 'react'
import {Platform, ScrollView, Text, TouchableOpacity, View, PermissionsAndroid} from 'react-native'
// Import the RtcEngine class and view rendering components into your project.
import RtcEngine, {RtcLocalView, RtcRemoteView, VideoRenderMode} from 'react-native-agora'
// Import the UI styles.
import styles from './components/Style'
Copy

3. Add project permissions

Android

Add the following code to the App.tsx file to set a prompt box for getting permissions to use the microphone and camera on an Android device:

const requestCameraAndAudioPermission = async () =>{
try {
const granted = await PermissionsAndroid.requestMultiple([
PermissionsAndroid.PERMISSIONS.CAMERA,
PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
])
if (
granted['android.permission.RECORD_AUDIO'] === PermissionsAndroid.RESULTS.GRANTED
&& granted['android.permission.CAMERA'] === PermissionsAndroid.RESULTS.GRANTED
) {
console.log('You can use the cameras & mic')
} else {
console.log('Permission denied')
}
} catch (err) {
console.warn(err)
}
}
Copy

iOS

In Xcode, open the info.plist file. Add the following contents to add permissions for your device:

KeyTypeValue
Privacy - Microphone Usage DescriptionStringTo access the microphone, such as for a call or interactive live streaming.
Privacy - Camera Usage DescriptionStringTo access the camera, such as for a call or interactive live streaming.

4. Create an App component

When creating an App component, you need to define your App ID, token, and channel name, which will be used for initializing the RtcEngine object and joining the channel. Ensure the App ID and channel name are the same as the App ID and channel name used for generating the token.

  • appId:The App ID of your Agora project. See Get an App ID for details.

  • channelName:The unique channel name for the AgoraRTC session. Users with the same App ID and channel name can join the same channel.

  • token:Pass a token that identifies the role and privilege of the user. The token must be generated using the preceding App ID and channel name. You can set it to one of the following values:

    • A temporary token generated in Console. A temporary token is valid for 24 hours. For details, see Get a Temporary Token.
If your project has enabled the app certificate, ensure that you provide a token.
// Define a Props interface.
interface Props {
}

// Define a State interface.
interface State {
appId: string,
channelName: string,
token: string,
joinSucceed: boolean,
peerIds: number[],
}

// Create an App component, which extends the properties of the Pros and State interfaces.
export default class App extends Component<Props, State> {
_engine?: RtcEngine
// Add a constructor,and initialize this.state. You need:
// Replace yourAppId with the App ID of your Agora project.
// Replace yourChannel with the channel name that you want to join.
// Replace yourToken with the token that you generated using the App ID and channel name above.
constructor(props) {
super(props)
this.state = {
appId: 'yourAppId',
channelName: 'yourChannel',
token: 'yourToken',
joinSucceed: false,
peerIds: [],
}
if (Platform.OS === 'android') {
requestCameraAndAudioPermission().then(() => {
console.log('requested!')
})
}
}
// Other code. See step 5 to step 10.
...
}
Copy

5. Initialize RtcEngine

Create and initialize the RtcEngine object before calling any other Agora APIs.

You can also listen for callback events, such as when the local user joins the channel, when a remote user joins the channel, and when a remote user leaves the channel.

Add the following code after // Other code in App.tsx

// Mount the App component into the DOM.
componentDidMount() {
this.init()
}
// Pass in your App ID through this.state, create and initialize an RtcEngine object.
init = async () => {
const {appId} = this.state
this._engine = await RtcEngine.create(appId)
// Enable the video module.
await this._engine.enableVideo()

// Listen for the UserJoined callback.
// This callback occurs when the remote user successfully joins the channel.
this._engine.addListener('UserJoined', (uid, elapsed) => {
console.log('UserJoined', uid, elapsed)
const {peerIds} = this.state
if (peerIds.indexOf(uid) === -1) {
this.setState({
peerIds: [...peerIds, uid]
})
}
})

// Listen for the UserOffline callback.
// This callback occurs when the remote user leaves the channel or drops offline.
this._engine.addListener('UserOffline', (uid, reason) => {
console.log('UserOffline', uid, reason)
const {peerIds} = this.state
this.setState({
// Remove peer ID from state array
peerIds: peerIds.filter(id => id !== uid)
})
})

// Listen for the JoinChannelSuccess callback.
// This callback occurs when the local user successfully joins the channel.
this._engine.addListener('JoinChannelSuccess', (channel, uid, elapsed) => {
console.log('JoinChannelSuccess', channel, uid, elapsed)
this.setState({
joinSucceed: true
})
})
}
Copy

6. Join a channel

After initializing the RtcEngine object, you can call joinChannel to join a channel.

// Pass in your token and channel name through this.state.token and this.state.channelName.
// Set the ID of the local user, which is an integer and should be unique. If you set uid as 0,
// the SDK assigns a user ID for the local user and returns it in the JoinChannelSuccess callback.
startCall = async () => {
await this._engine?.joinChannel(this.state.token, this.state.channelName, null, 0)
}
Copy

7. Render UI elements

Call the render() method in the App component to render the UI elements and handle the button click event.

render() {
return (
<View style={styles.max}>
<View style={styles.max}>
<View style={styles.buttonHolder}>
<TouchableOpacity
onPress={this.startCall}
style={styles.button}>
<Text style={styles.buttonText}> Start Call </Text>
</TouchableOpacity>
<TouchableOpacity
onPress={this.endCall}
style={styles.button}>
<Text style={styles.buttonText}> End Call </Text>
</TouchableOpacity>
</View>
{this._renderVideos()}
</View>
</View>
)
}
Copy

8. Render the local video view

Configure the video view of the local user. After joining the channel, the user can see themselves. You can also call startPreview to start the local video preview before joining the channel.

// Set the rendering mode of the video view as Hidden,
// which uniformly scales the video until it fills the visible boundaries.
_renderVideos = () => {
const {joinSucceed} = this.state
return joinSucceed ? (
<View style={styles.fullView}>
<RtcLocalView.SurfaceView
style={styles.max}
channelId={this.state.channelName}
renderMode={VideoRenderMode.Hidden}/>
{this._renderRemoteVideos()}
</View>
) : null
}
Copy

9. Render the remote video view

In a video call, you should be able to see other users. After joining the channel, pass in the uid of the remote user sending the video, and set the video view of the remote user.

// Set the rendering mode of the video view as Hidden,
// which uniformly scales the video until it fills the visible boundaries.
_renderRemoteVideos = () => {
const {peerIds} = this.state
return (
<ScrollView
style={styles.remoteContainer}
contentContainerStyle={{paddingHorizontal: 2.5}}
horizontal={true}>
{peerIds.map((value, index, array) => {
return (
<RtcRemoteView.SurfaceView
style={styles.remote}
uid={value}
channelId={this.state.channelName}
renderMode={VideoRenderMode.Hidden}
zOrderMediaOverlay={true}/>
)
})}
</ScrollView>
)
}
Copy

10. Leave the channel

Call leaveChannel to leave the current channel according to your scenario. For example, when the video call ends, when you need to close the app, or when your app runs in the background.

endCall = async () => {
await this._engine?.leaveChannel()
this.setState({peerIds: [], joinSucceed: false})
}
Copy

Run the project

Agora recommends you run this project on a physical mobile device, as some simulators may not support the full features of this project.

To run the Android app on a physical device:

  1. Enable Developer options on your Android device, and then connect it to your computer using a USB cable.
  2. Run npx react-native run-android in the project root directory.

To run the iOS app on a physical device:

  1. Open the ProjectName/ios/ProjectName.xcworkspace folder with Xcode.
  2. Connect your iOS device to your computer using a USB cable.
  3. Click the Build and run button in Xcode.

You should see the app installed on your device after a while. You can see both the local and remote video views when you successfully start a video call in the app.

Video Calling