diff --git a/shared/video-sdk/get-started/get-started-sdk/project-implementation/react-native.mdx b/shared/video-sdk/get-started/get-started-sdk/project-implementation/react-native.mdx
index f9a775e47..c99581a3c 100644
--- a/shared/video-sdk/get-started/get-started-sdk/project-implementation/react-native.mdx
+++ b/shared/video-sdk/get-started/get-started-sdk/project-implementation/react-native.mdx
@@ -11,7 +11,7 @@ The following figure illustrates the essential steps:
![](/images/video-sdk/quickstart-voice-call-sequence.svg)
-A complete code sample that implements the basic process of is presented here for your reference. Copy the code into your project to quickly implement the basic functionality.
+A complete code sample that implements the basic process of is presented here for your reference. Copy the code into `ProjectName/App.tsx` to quickly implement the basic functionality.
Complete sample code for real-time
@@ -27,61 +27,78 @@ import {
StyleSheet,
Text,
View,
+ Switch,
} from 'react-native';
-// Import components for obtaining Android device permissions
+// Import components related to obtaining Android device permissions
import { PermissionsAndroid, Platform } from 'react-native';
// Import Agora SDK
import {
- ClientRoleType,
createAgoraRtcEngine,
- IRtcEngine,
ChannelProfileType,
+ ClientRoleType,
+ IRtcEngine,
+ RtcSurfaceView,
+ RtcConnection,
+ IRtcEngineEventHandler
} from 'react-native-agora';
+
// Define basic information
const appId = '<-- Insert App ID -->';
const token = '<-- Insert Token -->';
const channelName = '<-- Insert Channel Name -->';
-const uid = 0; // Local user UID, no need to modify
+const uid = 0; // Local user Uid, no need to modify
const App = () => {
const agoraEngineRef = useRef(); // IRtcEngine instance
const [isJoined, setIsJoined] = useState(false); // Whether the local user has joined the channel
- const [remoteUid, setRemoteUid] = useState(0); // Remote user UID
+ const [isHost, setIsHost] = useState(true); // User role
+ const [remoteUid, setRemoteUid] = useState(0); // Uid of the remote user
const [message, setMessage] = useState(''); // User prompt message
+ const eventHandler = useRef(); // Implement callback functions
- // Initialize the engine when starting the App
useEffect(() => {
+ // Initialize the engine when the App starts
setupVideoSDKEngine();
- });
+ // Release memory when the App is closed
+ return () => {
+ agoraEngineRef.current?.unregisterEventHandler(eventHandler.current!);
+ agoraEngineRef.current?.release();
+ };
+ }, []);
+
+ // Define the setupVideoSDKEngine method called when the App starts
const setupVideoSDKEngine = async () => {
try {
- // Create RtcEngine after checking and obtaining device permissions
+ // Create RtcEngine after obtaining device permissions
if (Platform.OS === 'android') {
await getPermission();
}
agoraEngineRef.current = createAgoraRtcEngine();
const agoraEngine = agoraEngineRef.current;
-
- // Register event callbacks
- agoraEngine.registerEventHandler({
+ eventHandler.current = {
onJoinChannelSuccess: () => {
- showMessage('Successfully joined the channel: ' + channelName);
+ showMessage('Successfully joined channel: ' + channelName);
setIsJoined(true);
},
- onUserJoined: (_connection, Uid) => {
- showMessage('Remote user ' + Uid + ' has joined');
- setRemoteUid(Uid);
+ onUserJoined: (_connection: RtcConnection, uid: number) => {
+ showMessage('Remote user ' + uid + ' joined');
+ setRemoteUid(uid);
},
- onUserOffline: (_connection, Uid) => {
- showMessage('Remote user ' + Uid + ' has left the channel');
+ onUserOffline: (_connection: RtcConnection, uid: number) => {
+ showMessage('Remote user ' + uid + ' left the channel');
setRemoteUid(0);
},
- });
+ };
+
+ // Register the event handler
+ agoraEngine.registerEventHandler(eventHandler.current);
// Initialize the engine
agoraEngine.initialize({
appId: appId,
});
+ // Enable local video
+ agoraEngine.enableVideo();
} catch (e) {
console.log(e);
}
@@ -93,24 +110,51 @@ const App = () => {
return;
}
try {
- // Set the channel profile type to live broadcasting after joining the channel
- agoraEngineRef.current?.setChannelProfile(
- ChannelProfileType.ChannelProfileBroadcasting,
- );
- // Call the joinChannel method to join the channel
- agoraEngineRef.current?.joinChannel(token, channelName, uid, {
- // Set the user role to broadcaster
- clientRoleType: ClientRoleType.ClientRoleBroadcaster,
- audienceLatencyLevelType: AudienceLatencyLevelType.AudienceLatencyLevelLowLatency
- });
+ if (isHost) {
+ // Start preview
+ agoraEngineRef.current?.startPreview();
+ // Join the channel as a broadcaster
+ agoraEngineRef.current?.joinChannel(token, channelName, uid, {
+ // Set channel profile to live broadcast
+ channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting,
+ // Set user role to broadcaster
+ clientRoleType: ClientRoleType.ClientRoleBroadcaster,
+ // Publish audio collected by the microphone
+ publishMicrophoneTrack: true,
+ // Publish video collected by the camera
+ publishCameraTrack: true,
+ // Automatically subscribe to all audio streams
+ autoSubscribeAudio: true,
+ // Automatically subscribe to all video streams
+ autoSubscribeVideo: true,
+ });
+ } else {
+ // Join the channel as an audience
+ agoraEngineRef.current?.joinChannel(token, channelName, uid, {
+ // Set channel profile to live broadcast
+ channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting,
+ // Set user role to audience
+ clientRoleType: ClientRoleType.ClientRoleAudience,
+ // Do not publish audio collected by the microphone
+ publishMicrophoneTrack: false,
+ // Do not publish video collected by the camera
+ publishCameraTrack: false,
+ // Automatically subscribe to all audio streams
+ autoSubscribeAudio: true,
+ // Automatically subscribe to all video streams
+ autoSubscribeVideo: true,
+ // Change the delay level of the audience to achieve fast live broadcast
+ audienceLatencyLevel: AudienceLatencyLevelType.AudienceLatencyLevelLowLatency,
+ });
+ }
} catch (e) {
console.log(e);
}
};
- // Define the leave method called after clicking the leave channel button
+ // Define the leave method called after clicking the leave channel button
const leave = () => {
try {
- // Call the leaveChannel method to leave the channel
+ // Call leaveChannel method to leave the channel
agoraEngineRef.current?.leaveChannel();
setRemoteUid(0);
setIsJoined(false);
@@ -120,10 +164,10 @@ const App = () => {
}
};
- // Render the user interface
+ // Render user interface
return (
- Agora Voice Call Quick Start
+ Agora Video SDK Quickstart
Join Channel
@@ -132,25 +176,49 @@ const App = () => {
Leave Channel
+
+ Audience
+ {
+ setIsHost(switchValue);
+ if (isJoined) {
+ leave();
+ }
+ }}
+ value={isHost}
+ />
+ Host
+
- {isJoined ? (
- Local user UID: {uid}
+ {isJoined && isHost ? (
+
+ {/* Create a local view using RtcSurfaceView */}
+
+ Local user uid: {uid}
+
) : (
Join a channel
)}
{isJoined && remoteUid !== 0 ? (
- Remote user UID: {remoteUid}
+
+ {/* Create a remote view using RtcSurfaceView */}
+
+ Remote user uid: {remoteUid}
+
) : (
- Waiting for remote users to join
+ {isJoined && !isHost ? 'Waiting for remote user to join' : ''}
)}
- {message}
+ {message}
);
- // Display message
+ // Display information
function showMessage(msg: string) {
setMessage(msg);
}
@@ -172,17 +240,21 @@ const styles = StyleSheet.create({
videoView: { width: '90%', height: 200 },
btnContainer: { flexDirection: 'row', justifyContent: 'center' },
head: { fontSize: 20 },
+ info: { backgroundColor: '#ffffe0', paddingHorizontal: 8, color: '#0000ff' },
});
const getPermission = async () => {
if (Platform.OS === 'android') {
await PermissionsAndroid.requestMultiple([
PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
+ PermissionsAndroid.PERMISSIONS.CAMERA,
]);
}
};
-export default App;`}
+export default App;
+
+`}
@@ -197,61 +269,78 @@ import {
StyleSheet,
Text,
View,
+ Switch,
} from 'react-native';
-// Import components for obtaining Android device permissions
+// Import components related to obtaining Android device permissions
import { PermissionsAndroid, Platform } from 'react-native';
// Import Agora SDK
import {
- ClientRoleType,
createAgoraRtcEngine,
- IRtcEngine,
ChannelProfileType,
+ ClientRoleType,
+ IRtcEngine,
+ RtcSurfaceView,
+ RtcConnection,
+ IRtcEngineEventHandler
} from 'react-native-agora';
+
// Define basic information
const appId = '<-- Insert App ID -->';
const token = '<-- Insert Token -->';
const channelName = '<-- Insert Channel Name -->';
-const uid = 0; // Local user UID, no need to modify
+const uid = 0; // Local user Uid, no need to modify
const App = () => {
const agoraEngineRef = useRef(); // IRtcEngine instance
const [isJoined, setIsJoined] = useState(false); // Whether the local user has joined the channel
- const [remoteUid, setRemoteUid] = useState(0); // Remote user UID
+ const [isHost, setIsHost] = useState(true); // User role
+ const [remoteUid, setRemoteUid] = useState(0); // Uid of the remote user
const [message, setMessage] = useState(''); // User prompt message
+ const eventHandler = useRef(); // Implement callback functions
- // Initialize the engine when starting the App
useEffect(() => {
+ // Initialize the engine when the App starts
setupVideoSDKEngine();
- });
+ // Release memory when the App is closed
+ return () => {
+ agoraEngineRef.current?.unregisterEventHandler(eventHandler.current!);
+ agoraEngineRef.current?.release();
+ };
+ }, []);
+
+ // Define the setupVideoSDKEngine method called when the App starts
const setupVideoSDKEngine = async () => {
try {
- // Create RtcEngine after checking and obtaining device permissions
+ // Create RtcEngine after obtaining device permissions
if (Platform.OS === 'android') {
await getPermission();
}
agoraEngineRef.current = createAgoraRtcEngine();
const agoraEngine = agoraEngineRef.current;
-
- // Register event callbacks
- agoraEngine.registerEventHandler({
+ eventHandler.current = {
onJoinChannelSuccess: () => {
- showMessage('Successfully joined the channel: ' + channelName);
+ showMessage('Successfully joined channel: ' + channelName);
setIsJoined(true);
},
- onUserJoined: (_connection, Uid) => {
- showMessage('Remote user ' + Uid + ' has joined');
- setRemoteUid(Uid);
+ onUserJoined: (_connection: RtcConnection, uid: number) => {
+ showMessage('Remote user ' + uid + ' joined');
+ setRemoteUid(uid);
},
- onUserOffline: (_connection, Uid) => {
- showMessage('Remote user ' + Uid + ' has left the channel');
+ onUserOffline: (_connection: RtcConnection, uid: number) => {
+ showMessage('Remote user ' + uid + ' left the channel');
setRemoteUid(0);
},
- });
+ };
+
+ // Register the event handler
+ agoraEngine.registerEventHandler(eventHandler.current);
// Initialize the engine
agoraEngine.initialize({
appId: appId,
});
+ // Enable local video
+ agoraEngine.enableVideo();
} catch (e) {
console.log(e);
}
@@ -263,16 +352,43 @@ const App = () => {
return;
}
try {
- // Set the channel profile type to live broadcasting after joining the channel
- agoraEngineRef.current?.setChannelProfile(
- ChannelProfileType.ChannelProfileBroadcasting,
- );
- // Call the joinChannel method to join the channel
- agoraEngineRef.current?.joinChannel(token, channelName, uid, {
- // Set the user role to broadcaster
- clientRoleType: ClientRoleType.ClientRoleBroadcaster,
- audienceLatencyLevelType: AudienceLatencyLevelType.AudienceLatencyLevelUltraLowLatency
- });
+ if (isHost) {
+ // Start preview
+ agoraEngineRef.current?.startPreview();
+ // Join the channel as a broadcaster
+ agoraEngineRef.current?.joinChannel(token, channelName, uid, {
+ // Set channel profile to live broadcast
+ channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting,
+ // Set user role to broadcaster
+ clientRoleType: ClientRoleType.ClientRoleBroadcaster,
+ // Publish audio collected by the microphone
+ publishMicrophoneTrack: true,
+ // Publish video collected by the camera
+ publishCameraTrack: true,
+ // Automatically subscribe to all audio streams
+ autoSubscribeAudio: true,
+ // Automatically subscribe to all video streams
+ autoSubscribeVideo: true,
+ });
+ } else {
+ // Join the channel as an audience
+ agoraEngineRef.current?.joinChannel(token, channelName, uid, {
+ // Set channel profile to live broadcast
+ channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting,
+ // Set user role to audience
+ clientRoleType: ClientRoleType.ClientRoleAudience,
+ // Do not publish audio collected by the microphone
+ publishMicrophoneTrack: false,
+ // Do not publish video collected by the camera
+ publishCameraTrack: false,
+ // Automatically subscribe to all audio streams
+ autoSubscribeAudio: true,
+ // Automatically subscribe to all video streams
+ autoSubscribeVideo: true,
+ // Change the delay level of the audience to achieve ultra-fast live broadcast
+ audienceLatencyLevel: AudienceLatencyLevelType.AudienceLatencyLevelUltraLowLatency,
+ });
+ }
} catch (e) {
console.log(e);
}
@@ -280,7 +396,7 @@ const App = () => {
// Define the leave method called after clicking the leave channel button
const leave = () => {
try {
- // Call the leaveChannel method to leave the channel
+ // Call leaveChannel method to leave the channel
agoraEngineRef.current?.leaveChannel();
setRemoteUid(0);
setIsJoined(false);
@@ -290,10 +406,10 @@ const App = () => {
}
};
- // Render the user interface
+ // Render user interface
return (
- Agora Voice Call Quick Start
+ Agora Video SDK Quickstart
Join Channel
@@ -302,25 +418,49 @@ const App = () => {
Leave Channel
+
+ Audience
+ {
+ setIsHost(switchValue);
+ if (isJoined) {
+ leave();
+ }
+ }}
+ value={isHost}
+ />
+ Host
+
- {isJoined ? (
- Local user UID: {uid}
+ {isJoined && isHost ? (
+
+ {/* Create a local view using RtcSurfaceView */}
+
+ Local user uid: {uid}
+
) : (
Join a channel
)}
{isJoined && remoteUid !== 0 ? (
- Remote user UID: {remoteUid}
+
+ {/* Create a remote view using RtcSurfaceView */}
+
+ Remote user uid: {remoteUid}
+
) : (
- Waiting for remote users to join
+ {isJoined && !isHost ? 'Waiting for remote user to join' : ''}
)}
- {message}
+ {message}
);
- // Display message
+ // Display information
function showMessage(msg: string) {
setMessage(msg);
}
@@ -342,17 +482,21 @@ const styles = StyleSheet.create({
videoView: { width: '90%', height: 200 },
btnContainer: { flexDirection: 'row', justifyContent: 'center' },
head: { fontSize: 20 },
+ info: { backgroundColor: '#ffffe0', paddingHorizontal: 8, color: '#0000ff' },
});
const getPermission = async () => {
if (Platform.OS === 'android') {
await PermissionsAndroid.requestMultiple([
PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
+ PermissionsAndroid.PERMISSIONS.CAMERA,
]);
}
};
-export default App;`}
+export default App;
+
+`}
@@ -367,61 +511,78 @@ import {
StyleSheet,
Text,
View,
+ Switch,
} from 'react-native';
-// Import components for obtaining Android device permissions
+// Import components related to obtaining Android device permissions
import { PermissionsAndroid, Platform } from 'react-native';
// Import Agora SDK
import {
- ClientRoleType,
createAgoraRtcEngine,
- IRtcEngine,
ChannelProfileType,
+ ClientRoleType,
+ IRtcEngine,
+ RtcSurfaceView,
+ RtcConnection,
+ IRtcEngineEventHandler,
} from 'react-native-agora';
+
// Define basic information
const appId = '<-- Insert App ID -->';
const token = '<-- Insert Token -->';
const channelName = '<-- Insert Channel Name -->';
-const uid = 0; // Local user UID, no need to modify
+const uid = 0; // Local user Uid, no need to modify
const App = () => {
const agoraEngineRef = useRef(); // IRtcEngine instance
const [isJoined, setIsJoined] = useState(false); // Whether the local user has joined the channel
- const [remoteUid, setRemoteUid] = useState(0); // Remote user UID
+ const [isHost, setIsHost] = useState(true); // User role
+ const [remoteUid, setRemoteUid] = useState(0); // Uid of the remote user
const [message, setMessage] = useState(''); // User prompt message
+ const eventHandler = useRef(); // Implement callback functions
- // Initialize the engine when starting the App
useEffect(() => {
+ // Initialize the engine when the App starts
setupVideoSDKEngine();
- });
+ // Release memory when the App is closed
+ return () => {
+ agoraEngineRef.current?.unregisterEventHandler(eventHandler.current!);
+ agoraEngineRef.current?.release();
+ };
+ }, []);
+
+ // Define the setupVideoSDKEngine method called when the App starts
const setupVideoSDKEngine = async () => {
try {
- // Create RtcEngine after checking and obtaining device permissions
+ // Create RtcEngine after obtaining device permissions
if (Platform.OS === 'android') {
await getPermission();
}
agoraEngineRef.current = createAgoraRtcEngine();
const agoraEngine = agoraEngineRef.current;
-
- // Register event callbacks
- agoraEngine.registerEventHandler({
+ eventHandler.current = {
onJoinChannelSuccess: () => {
- showMessage('Successfully joined the channel: ' + channelName);
+ showMessage('Successfully joined channel: ' + channelName);
setIsJoined(true);
},
- onUserJoined: (_connection, Uid) => {
- showMessage('Remote user ' + Uid + ' has joined');
- setRemoteUid(Uid);
+ onUserJoined: (_connection: RtcConnection, uid: number) => {
+ showMessage('Remote user ' + uid + ' joined');
+ setRemoteUid(uid);
},
- onUserOffline: (_connection, Uid) => {
- showMessage('Remote user ' + Uid + ' has left the channel');
+ onUserOffline: (_connection: RtcConnection, uid: number) => {
+ showMessage('Remote user ' + uid + ' left the channel');
setRemoteUid(0);
},
- });
+ };
+
+ // Register the event handler
+ agoraEngine.registerEventHandler(eventHandler.current);
// Initialize the engine
agoraEngine.initialize({
appId: appId,
});
+ // Enable local video
+ agoraEngine.enableVideo();
} catch (e) {
console.log(e);
}
@@ -433,15 +594,41 @@ const App = () => {
return;
}
try {
- // Set the channel profile type to ChannelProfileCommunication after joining the channel
- agoraEngineRef.current?.setChannelProfile(
- ChannelProfileType.ChannelProfileCommunication,
- );
- // Call the joinChannel method to join the channel
- agoraEngineRef.current?.joinChannel(token, channelName, uid, {
- // Set the user role to broadcaster
- clientRoleType: ClientRoleType.ClientRoleBroadcaster,
- });
+ if (isHost) {
+ // Start preview
+ agoraEngineRef.current?.startPreview();
+ // Join the channel as a broadcaster
+ agoraEngineRef.current?.joinChannel(token, channelName, uid, {
+ // Set channel profile to live broadcast
+ channelProfile: ChannelProfileType.ChannelProfileCommunication,
+ // Set user role to broadcaster
+ clientRoleType: ClientRoleType.ClientRoleBroadcaster,
+ // Publish audio collected by the microphone
+ publishMicrophoneTrack: true,
+ // Publish video collected by the camera
+ publishCameraTrack: true,
+ // Automatically subscribe to all audio streams
+ autoSubscribeAudio: true,
+ // Automatically subscribe to all video streams
+ autoSubscribeVideo: true,
+ });
+ } else {
+ // Join the channel as an audience
+ agoraEngineRef.current?.joinChannel(token, channelName, uid, {
+ // Set channel profile to live broadcast
+ channelProfile: ChannelProfileType.ChannelProfileCommunication,
+ // Set user role to audience
+ clientRoleType: ClientRoleType.ClientRoleAudience,
+ // Do not publish audio collected by the microphone
+ publishMicrophoneTrack: false,
+ // Do not publish video collected by the camera
+ publishCameraTrack: false,
+ // Automatically subscribe to all audio streams
+ autoSubscribeAudio: true,
+ // Automatically subscribe to all video streams
+ autoSubscribeVideo: true,
+ });
+ }
} catch (e) {
console.log(e);
}
@@ -449,7 +636,7 @@ const App = () => {
// Define the leave method called after clicking the leave channel button
const leave = () => {
try {
- // Call the leaveChannel method to leave the channel
+ // Call leaveChannel method to leave the channel
agoraEngineRef.current?.leaveChannel();
setRemoteUid(0);
setIsJoined(false);
@@ -459,10 +646,10 @@ const App = () => {
}
};
- // Render the user interface
+ // Render user interface
return (
- Agora Voice Call Quick Start
+ Agora Video SDK Quickstart
Join Channel
@@ -471,25 +658,49 @@ const App = () => {
Leave Channel
+
+ Audience
+ {
+ setIsHost(switchValue);
+ if (isJoined) {
+ leave();
+ }
+ }}
+ value={isHost}
+ />
+ Host
+
- {isJoined ? (
- Local user UID: {uid}
+ {isJoined && isHost ? (
+
+ {/* Create a local view using RtcSurfaceView */}
+
+ Local user uid: {uid}
+
) : (
Join a channel
)}
{isJoined && remoteUid !== 0 ? (
- Remote user UID: {remoteUid}
+
+ {/* Create a remote view using RtcSurfaceView */}
+
+ Remote user uid: {remoteUid}
+
) : (
- Waiting for remote users to join
+ {isJoined && !isHost ? 'Waiting for remote user to join' : ''}
)}
- {message}
+ {message}
);
- // Display message
+ // Display information
function showMessage(msg: string) {
setMessage(msg);
}
@@ -511,17 +722,21 @@ const styles = StyleSheet.create({
videoView: { width: '90%', height: 200 },
btnContainer: { flexDirection: 'row', justifyContent: 'center' },
head: { fontSize: 20 },
+ info: { backgroundColor: '#ffffe0', paddingHorizontal: 8, color: '#0000ff' },
});
const getPermission = async () => {
if (Platform.OS === 'android') {
await PermissionsAndroid.requestMultiple([
PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
+ PermissionsAndroid.PERMISSIONS.CAMERA,
]);
}
};
-export default App;`}
+export default App;
+
+`}
@@ -536,56 +751,69 @@ import {
Text,
View,
} from 'react-native';
-// Import components for obtaining Android device permissions
+// Import components related to obtaining Android device permissions
import { PermissionsAndroid, Platform } from 'react-native';
// Import Agora SDK
import {
- ClientRoleType,
createAgoraRtcEngine,
- IRtcEngine,
ChannelProfileType,
+ ClientRoleType,
+ IRtcEngine,
+ RtcConnection,
+ IRtcEngineEventHandler,
} from 'react-native-agora';
+
// Define basic information
const appId = '<-- Insert App ID -->';
const token = '<-- Insert Token -->';
const channelName = '<-- Insert Channel Name -->';
-const uid = 0; // Local user UID, no need to modify
+const uid = 0; // Local user Uid, no need to modify
const App = () => {
const agoraEngineRef = useRef(); // IRtcEngine instance
const [isJoined, setIsJoined] = useState(false); // Whether the local user has joined the channel
- const [remoteUid, setRemoteUid] = useState(0); // Remote user UID
+ const [isHost, setIsHost] = useState(true); // User role
+ const [remoteUid, setRemoteUid] = useState(0); // Uid of the remote user
const [message, setMessage] = useState(''); // User prompt message
+ const eventHandler = useRef(); // Callback functions
- // Initialize the engine when starting the App
useEffect(() => {
+ // Initialize the engine when the App starts
setupVideoSDKEngine();
- });
+ // Release memory when the App is closed
+ return () => {
+ agoraEngineRef.current?.unregisterEventHandler(eventHandler.current!);
+ agoraEngineRef.current?.release();
+ };
+ }, []);
+
+ // Define the setupVideoSDKEngine method called when the App starts
const setupVideoSDKEngine = async () => {
try {
- // Create RtcEngine after checking and obtaining device permissions
+ // Create RtcEngine after obtaining device permissions
if (Platform.OS === 'android') {
await getPermission();
}
agoraEngineRef.current = createAgoraRtcEngine();
const agoraEngine = agoraEngineRef.current;
-
- // Register event callbacks
- agoraEngine.registerEventHandler({
+ eventHandler.current = {
onJoinChannelSuccess: () => {
- showMessage('Successfully joined the channel: ' + channelName);
+ showMessage('Successfully joined channel: ' + channelName);
setIsJoined(true);
},
- onUserJoined: (_connection, Uid) => {
- showMessage('Remote user ' + Uid + ' has joined');
- setRemoteUid(Uid);
+ onUserJoined: (_connection: RtcConnection, uid: number) => {
+ showMessage('Remote user ' + uid + ' joined');
+ setRemoteUid(uid);
},
- onUserOffline: (_connection, Uid) => {
- showMessage('Remote user ' + Uid + ' has left the channel');
+ onUserOffline: (_connection: RtcConnection, uid: number) => {
+ showMessage('Remote user ' + uid + ' left the channel');
setRemoteUid(0);
},
- });
+ };
+
+ // Register the event handler
+ agoraEngine.registerEventHandler(eventHandler.current);
// Initialize the engine
agoraEngine.initialize({
appId: appId,
@@ -601,15 +829,31 @@ const App = () => {
return;
}
try {
- // Set the channel profile type to communication after joining the channel
- agoraEngineRef.current?.setChannelProfile(
- ChannelProfileType.ChannelProfileCommunication,
- );
- // Call the joinChannel method to join the channel
- agoraEngineRef.current?.joinChannel(token, channelName, uid, {
- // Set the user role to broadcaster
- clientRoleType: ClientRoleType.ClientRoleBroadcaster,
- });
+ if (isHost) {
+ // Join the channel as a broadcaster
+ agoraEngineRef.current?.joinChannel(token, channelName, uid, {
+ // Set channel profile to live broadcast
+ channelProfile: ChannelProfileType.ChannelProfileCommunication,
+ // Set user role to broadcaster
+ clientRoleType: ClientRoleType.ClientRoleBroadcaster,
+ // Publish audio collected by the microphone
+ publishMicrophoneTrack: true,
+ // Automatically subscribe to all audio streams
+ autoSubscribeAudio: true,
+ });
+ } else {
+ // Join the channel as an audience
+ agoraEngineRef.current?.joinChannel(token, channelName, uid, {
+ // Set channel profile to live broadcast
+ channelProfile: ChannelProfileType.ChannelProfileCommunication,
+ // Set user role to audience
+ clientRoleType: ClientRoleType.ClientRoleAudience,
+ // Do not publish audio collected by the microphone
+ publishMicrophoneTrack: false,
+ // Automatically subscribe to all audio streams
+ autoSubscribeAudio: true,
+ });
+ }
} catch (e) {
console.log(e);
}
@@ -617,7 +861,7 @@ const App = () => {
// Define the leave method called after clicking the leave channel button
const leave = () => {
try {
- // Call the leaveChannel method to leave the channel
+ // Call leaveChannel method to leave the channel
agoraEngineRef.current?.leaveChannel();
setRemoteUid(0);
setIsJoined(false);
@@ -627,10 +871,10 @@ const App = () => {
}
};
- // Render the user interface
+ // Render user interface
return (
- Agora Voice Call Quick Start
+ Agora Voice Calling Quickstart
Join Channel
@@ -643,21 +887,21 @@ const App = () => {
style={styles.scroll}
contentContainerStyle={styles.scrollContainer}>
{isJoined ? (
- Local user UID: {uid}
+ Local user uid: {uid}
) : (
Join a channel
)}
{isJoined && remoteUid !== 0 ? (
- Remote user UID: {remoteUid}
+ Remote user uid: {remoteUid}
) : (
- Waiting for remote users to join
+ Waiting for remote user to join
)}
{message}
);
- // Display message
+ // Display information
function showMessage(msg: string) {
setMessage(msg);
}
@@ -689,7 +933,9 @@ const getPermission = async () => {
}
};
-export default App;`}
+export default App;
+
+`}
@@ -697,33 +943,55 @@ export default App;`}
Follow the implementation steps to understand the core API calls in the sample code.
### Import dependencies
+
Add platform and dependencies required to build your app:
-
+
+
+
```jsx
-import {PermissionsAndroid, Platform} from 'react-native';
-// Import Agora SDK
import {
- ClientRoleType,
createAgoraRtcEngine,
+ ChannelProfileType,
+ ClientRoleType,
IRtcEngine,
RtcSurfaceView,
+ RtcConnection,
+ IRtcEngineEventHandler,
+} from 'react-native-agora';
+```
+
+
+
+
+
+```jsx
+import {
+ createAgoraRtcEngine,
ChannelProfileType,
+ ClientRoleType,
AudienceLatencyLevelType,
+ IRtcEngine,
+ RtcSurfaceView,
+ RtcConnection,
+ IRtcEngineEventHandler,
} from 'react-native-agora';
```
+
+
```jsx
-import {PermissionsAndroid, Platform} from 'react-native';
-// Import Agora SDK
import {
- ClientRoleType,
createAgoraRtcEngine,
- IRtcEngine,
ChannelProfileType,
+ ClientRoleType,
+ IRtcEngine,
+ RtcConnection,
+ IRtcEngineEventHandler,
} from 'react-native-agora';
```
+
### Declare variables
Declare variables to hold the app ID, the temporary token obtained from , and the channel name you used to generate the token. You use these parameters to initialize the engine and join a channel.
@@ -742,16 +1010,20 @@ Gain access to the microphone and camera on your target platform.
On Android devices, pop up a prompt box to obtain permission to use the microphone and camera.
- ```jsx
- const getPermission = async () => {
- if (Platform.OS === 'android') {
- await PermissionsAndroid.requestMultiple([
- PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
- PermissionsAndroid.PERMISSIONS.CAMERA,
- ]);
- }
- };
- ```
+
+{`// Import components related to Android device permissions
+import {PermissionsAndroid, Platform} from 'react-native';
+
+const getPermission = async () => {
+ if (Platform.OS === 'android') {
+ await PermissionsAndroid.requestMultiple([
+ PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
+ PermissionsAndroid.PERMISSIONS.CAMERA,
+ ]);
+ }
+};`}
+
+
In Xcode, open the `info.plist` file and add the following content to the list on the right to obtain the corresponding device permissions:
@@ -778,17 +1050,44 @@ Gain access to the microphone and camera on your target platform.
-Gain access to the microphone on your target platform.
-```jsx
+
+
+On Android devices, pop up a prompt box to obtain permission to use the microphone.
+
+
+
+{`// Import components related to Android device permissions
+import {PermissionsAndroid, Platform} from 'react-native';
+
const getPermission = async () => {
if (Platform.OS === 'android') {
await PermissionsAndroid.requestMultiple([
PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
]);
}
-};
-```
+};`}
+
+
+
+
+ In Xcode, open the `info.plist` file and add the following content to the list on the right to obtain the corresponding device permissions:
+
+
+
+
Key
+
Type
+
Value
+
+
+
Privacy - Microphone Usage Description
+
String
+
The purpose of using the microphone, for example, for a call or live interactive streaming.
+
+
+
+
+
### Initialize the engine
@@ -817,114 +1116,192 @@ agoraEngineRef.current?.startPreview();
```
-### Set up an event handler
-Call `registerEventHandler` to add the following callback events and handle the event logic:
-
-- `onJoinChannelSuccess`: The local user successfully joined a channel.
-- `onUserJoined`: A remote user joined the channel.
-- `onUserOffline`: A remote user left the channel.
-
-```jsx
-// Register event handler
-agoraEngine.registerEventHandler({
- onJoinChannelSuccess: () => {
- showMessage('Successfully joined the channel:' + channelName);
- setIsJoined(true);
- },
- onUserJoined: (_connection, Uid) => {
- showMessage('Remote user ' + Uid + ' joined');
- setRemoteUid(Uid);
- },
- onUserOffline: (_connection, Uid) => {
- showMessage('Remote user ' + Uid + ' left the channel');
- setRemoteUid(0);
- },
-});
-```
-
### Join a channel
-When a user clicks the **Join Channel** button, you call `setChannelProfile` to set the channel profile. Call `joinChannel` and set the `clientRoleType` to `ClientRoleBroadcaster` to join as a host, or `ClientRoleAudience` to join as audience.
+When a user clicks the **Join Channel** button, call `joinChannel` with the `token`, `channelName`, and `uid`. Use the `options` parameter to specify `ChannelMediaOptions`. Set the `clientRoleType` to `ClientRoleBroadcaster` to join as a host, or `ClientRoleAudience` to join as audience.
+
```jsx
-// Set the channel profile
-agoraEngineRef.current?.setChannelProfile(
- ChannelProfileType.ChannelProfileLiveBroadcasting,
-);
if (isHost) {
- // Enable local preview
+ // Start preview
agoraEngineRef.current?.startPreview();
- // Join the channel as a host
+ // Join the channel as a broadcaster
agoraEngineRef.current?.joinChannel(token, channelName, uid, {
+ // Set channel profile to live broadcast
+ channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting,
+ // Set user role to broadcaster
clientRoleType: ClientRoleType.ClientRoleBroadcaster,
- audienceLatencyLevelType: AudienceLatencyLevelType.AudienceLatencyLevelLowLatency
- });
+ // Publish audio collected by the microphone
+ publishMicrophoneTrack: true,
+ // Publish video collected by the camera
+ publishCameraTrack: true,
+ // Automatically subscribe to all audio streams
+ autoSubscribeAudio: true,
+ // Automatically subscribe to all video streams
+ autoSubscribeVideo: true,
+ });
} else {
- // Join the channel as audience
+ // Join the channel as an audience
agoraEngineRef.current?.joinChannel(token, channelName, uid, {
+ // Set channel profile to live broadcast
+ channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting,
+ // Set user role to audience
clientRoleType: ClientRoleType.ClientRoleAudience,
- audienceLatencyLevelType: AudienceLatencyLevelType.AudienceLatencyLevelUltraLowLatency
- });
+ // Do not publish audio collected by the microphone
+ publishMicrophoneTrack: false,
+ // Do not publish video collected by the camera
+ publishCameraTrack: false,
+ // Automatically subscribe to all audio streams
+ autoSubscribeAudio: true,
+ // Automatically subscribe to all video streams
+ autoSubscribeVideo: true,
+ // Change the delay level of the audience to achieve ultra-fast live broadcast
+ audienceLatencyLevel: AudienceLatencyLevelType.AudienceLatencyLevelUltraLowLatency,
+ });
}
```
+
```jsx
-// Set the channel profile
-agoraEngineRef.current?.setChannelProfile(
- ChannelProfileType.ChannelProfileLiveBroadcasting,
-);
if (isHost) {
- // Enable local preview
+ // Start preview
agoraEngineRef.current?.startPreview();
- // Join the channel as a host
+ // Join the channel as a broadcaster
agoraEngineRef.current?.joinChannel(token, channelName, uid, {
+ // Set channel profile to live broadcast
+ channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting,
+ // Set user role to broadcaster
clientRoleType: ClientRoleType.ClientRoleBroadcaster,
- audienceLatencyLevelType: AudienceLatencyLevelType.AudienceLatencyLevelLowLatency
- });
+ // Publish audio collected by the microphone
+ publishMicrophoneTrack: true,
+ // Publish video collected by the camera
+ publishCameraTrack: true,
+ // Automatically subscribe to all audio streams
+ autoSubscribeAudio: true,
+ // Automatically subscribe to all video streams
+ autoSubscribeVideo: true,
+ });
} else {
- // Join the channel as audience
+ // Join the channel as an audience
agoraEngineRef.current?.joinChannel(token, channelName, uid, {
+ // Set channel profile to live broadcast
+ channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting,
+ // Set user role to audience
clientRoleType: ClientRoleType.ClientRoleAudience,
- audienceLatencyLevelType: AudienceLatencyLevelType.AudienceLatencyLevelLowLatency
- });
+ // Do not publish audio collected by the microphone
+ publishMicrophoneTrack: false,
+ // Do not publish video collected by the camera
+ publishCameraTrack: false,
+ // Automatically subscribe to all audio streams
+ autoSubscribeAudio: true,
+ // Automatically subscribe to all video streams
+ autoSubscribeVideo: true,
+ // Change the delay level of the audience to achieve fast live broadcast
+ audienceLatencyLevel: AudienceLatencyLevelType.AudienceLatencyLevelLowLatency,
+ });
}
```
+
```jsx
-// Set the channel profile
-agoraEngineRef.current?.setChannelProfile(
- ChannelProfileType.ChannelProfileCommunication,
-);
if (isHost) {
- // Enable local preview
+ // Start preview
agoraEngineRef.current?.startPreview();
- // Join the channel as a host
+ // Join the channel as a broadcaster
agoraEngineRef.current?.joinChannel(token, channelName, uid, {
- clientRoleType: ClientRoleType.ClientRoleBroadcaster});
+ // Set channel profile to live broadcast
+ channelProfile: ChannelProfileType.ChannelProfileCommunication,
+ // Set user role to broadcaster
+ clientRoleType: ClientRoleType.ClientRoleBroadcaster,
+ // Publish audio collected by the microphone
+ publishMicrophoneTrack: true,
+ // Publish video collected by the camera
+ publishCameraTrack: true,
+ // Automatically subscribe to all audio streams
+ autoSubscribeAudio: true,
+ // Automatically subscribe to all video streams
+ autoSubscribeVideo: true,
+ });
} else {
- // Join the channel as audience
+ // Join the channel as an audience
agoraEngineRef.current?.joinChannel(token, channelName, uid, {
- clientRoleType: ClientRoleType.ClientRoleAudience
- });
+ // Set channel profile to live broadcast
+ channelProfile: ChannelProfileType.ChannelProfileCommunication,
+ // Set user role to audience
+ clientRoleType: ClientRoleType.ClientRoleAudience,
+ // Do not publish audio collected by the microphone
+ publishMicrophoneTrack: false,
+ // Do not publish video collected by the camera
+ publishCameraTrack: false,
+ // Automatically subscribe to all audio streams
+ autoSubscribeAudio: true,
+ // Automatically subscribe to all video streams
+ autoSubscribeVideo: true,
+ });
}
```
+
```jsx
-// Set the channel profile type to communication after joining the channel
-agoraEngineRef.current?.setChannelProfile(
- ChannelProfileType.ChannelProfileCommunication,
-);
-// Call the joinChannel method to join the channel
-agoraEngineRef.current?.joinChannel(token, channelName, uid, {
- // Set the user role to broadcaster
- clientRoleType: ClientRoleType.ClientRoleBroadcaster,
-});
+if (isHost) {
+ // Join the channel as a broadcaster
+ agoraEngineRef.current?.joinChannel(token, channelName, uid, {
+ // Set channel profile to live broadcast
+ channelProfile: ChannelProfileType.ChannelProfileCommunication,
+ // Set user role to broadcaster
+ clientRoleType: ClientRoleType.ClientRoleBroadcaster,
+ // Publish audio collected by the microphone
+ publishMicrophoneTrack: true,
+ // Automatically subscribe to all audio streams
+ autoSubscribeAudio: true,
+ });
+} else {
+ // Join the channel as an audience
+ agoraEngineRef.current?.joinChannel(token, channelName, uid, {
+ // Set channel profile to live broadcast
+ channelProfile: ChannelProfileType.ChannelProfileCommunication,
+ // Set user role to audience
+ clientRoleType: ClientRoleType.ClientRoleAudience,
+ // Do not publish audio collected by the microphone
+ publishMicrophoneTrack: false,
+ // Automatically subscribe to all audio streams
+ autoSubscribeAudio: true,
+ });
+}
```
+### Set up an event handler
+Call `registerEventHandler` to add the following callback events and handle the event logic:
+
+- `onJoinChannelSuccess`: The local user successfully joined a channel.
+- `onUserJoined`: A remote user joined the channel.
+- `onUserOffline`: A remote user left the channel.
+
+```jsx
+const eventHandler = useRef();
+eventHandler.current = {
+ onJoinChannelSuccess: () => {
+ showMessage('Successfully joined channel: ' + channelName);
+ setIsJoined(true);
+ },
+ onUserJoined: (_connection: RtcConnection, uid: number) => {
+ showMessage('Remote user ' + uid + ' has joined');
+ setRemoteUid(uid);
+ },
+ onUserOffline: (_connection: RtcConnection, uid: number) => {
+ showMessage('Remote user ' + uid + ' has left the channel');
+ setRemoteUid(0);
+ },
+};
+
+// Register the event handler
+agoraEngine.registerEventHandler(eventHandler.current);
+```
+
### Leave the channel
Call `leaveChannel` to leave the channel and release resources.
@@ -936,4 +1313,17 @@ setIsJoined(false);
showMessage('You left the channel');
```
+When you no longer need to use the engine instance, unregister the event handler and call `release` to release engine resources.
+
+```jsx
+// Unregister callback events
+agoraEngineRef.current?.unregisterEventHandler(eventHandles);
+// Destroy the engine
+agoraEngineRef.current?.release();
+```
+
+
+After calling `release,` methods and callbacks of the SDK are no longer available. To use the SDK functions again, create a new engine instance.
+
+
\ No newline at end of file
diff --git a/shared/video-sdk/get-started/get-started-sdk/project-setup/react-native.mdx b/shared/video-sdk/get-started/get-started-sdk/project-setup/react-native.mdx
index c4a319fee..2b5f72660 100644
--- a/shared/video-sdk/get-started/get-started-sdk/project-setup/react-native.mdx
+++ b/shared/video-sdk/get-started/get-started-sdk/project-setup/react-native.mdx
@@ -6,23 +6,31 @@ import CodeBlock from '@theme/CodeBlock';
Refer to the following steps to create a React Native project.
-1. Ensure that your development environment is set up according to the operating system you are using and the target platform.
+1. To initialize a new `package.json` file in your project directory, run the following command:
-1. To create and initialize a new project, run the following command after replacing `ProjectName`, with the name of your project:
+ ```bash
+ npm init
+ ```
+
+1. To install React Native as a dependency in your project, execute:
```bash
- npx react-native init ProjectName --template react-native-template-typescript
+ npm install react-native
```
- The command creates a basic sample project in the folder where the command is executed.
+1. To create and initialize a new project, run the following command. Replace `ProjectName`, with the name of your project:
+
+ ```bash
+ npx react-native init ProjectName
+ ```
-1. Start your Android or iOS simulator and execute the following command to run your project:
+1. To run the app for your target platform, enter the `ProjectName` folder and execute one of the following commands:
- 1. In the project root folder, execute `npx react-native start` to start Metro.
+ - Android: `npx react-native run-android`
+ - iOS: `npx react-native run-ios`
- 1. Open another Terminal in the project directory and execute `npx react-native run-android` to run your project on Android or `npx react-native run-ios` to run the iOS application.
+ You see that the simulator is launched, the app is automatically installed on the simulator and starts running. You can also run the app on an Android or iOS device, see [Run on a device](https://reactnative.dev/docs/running-on-device) for details.
- The application is automatically installed on the emulator and launched. To run the app on a real Android or iOS device, see [Running On Device](https://reactnative.dev/docs/running-on-device).
### Integrate the SDK
@@ -75,72 +83,74 @@ import {
Switch,
} from 'react-native';
-const App = () => {
+const App = () => {
const agoraEngineRef = useRef(); // IRtcEngine instance
const [isJoined, setIsJoined] = useState(false); // Whether the local user has joined the channel
const [isHost, setIsHost] = useState(true); // User role
const [remoteUid, setRemoteUid] = useState(0); // Uid of the remote user
- const [message, setMessage] = useState(''); // Message for the user
+ const [message, setMessage] = useState(''); // User prompt message
// Render user interface
return (
-
- Agora Video SDK Quickstart
-
-
- Join channel
-
-
- Leave channel
-
-
-
- Audience
- {
- setIsHost(switchValue);
- if (isJoined) {
- leave();
- }
- }}
- value={isHost}
- />
- Host
-
-
- {isJoined ? (
-
-
- Local user uid: {uid}
-
- ) : (
- Join a channel
- )}
- {isJoined && !isHost && remoteUid !== 0 ? (
-
-
+ Agora Video SDK Quickstart
+
+
+ Join channel
+
+
+ Leave channel
+
+
+
+ Audience
+ {
+ setIsHost(switchValue);
+ if (isJoined) {
+ leave();
+ }
+ }}
+ value={isHost}
/>
- Remote user uid: {remoteUid}
-
- ) : (
- {isJoined && !isHost ? 'Waiting for remote users to join' : ''}
- )}
- {message}
-
-
-);
+ Host
+
+
+ {isJoined && isHost ? (
+
+ {/* Create a local view using RtcSurfaceView */}
+
+ Local user uid: {uid}
+
+ ) : (
+ Join a channel
+ )}
+ {isJoined && remoteUid !== 0 ? (
+
+ {/* Create a remote view using RtcSurfaceView */}
+
+ Remote user uid: {remoteUid}
+
+ ) : (
+ {isJoined && !isHost ? 'Waiting for remote user to join' : ''}
+ )}
+ {message}
+
+
+ );
- // Display information
+ // Display information
function showMessage(msg: string) {
setMessage(msg);
}
};
-// Define the UI style
+// Define user interface styles
const styles = StyleSheet.create({
button: {
paddingHorizontal: 25,
@@ -150,13 +160,13 @@ const styles = StyleSheet.create({
backgroundColor: '#0055cc',
margin: 5,
},
- main: {flex: 1, alignItems: 'center'},
- scroll: {flex: 1, backgroundColor: '#ddeeff', width: '100%'},
- scrollContainer: {alignItems: 'center'},
- videoView: {width: '90%', height: 200},
- btnContainer: {flexDirection: 'row', justifyContent: 'center'},
- head: {fontSize: 20},
- info: {backgroundColor: '#ffffe0', paddingHorizontal: 8, color: '#0000ff'}
+ main: { flex: 1, alignItems: 'center' },
+ scroll: { flex: 1, backgroundColor: '#ddeeff', width: '100%' },
+ scrollContainer: { alignItems: 'center' },
+ videoView: { width: '90%', height: 200 },
+ btnContainer: { flexDirection: 'row', justifyContent: 'center' },
+ head: { fontSize: 20 },
+ info: { backgroundColor: '#ffffe0', paddingHorizontal: 8, color: '#0000ff' }
});`}
@@ -164,7 +174,7 @@ const styles = StyleSheet.create({
{`// Import React Hooks
-import React, { useRef, useState, useEffect } from 'react';
+import React, {useRef, useState, useEffect} from 'react';
// Import user interface elements
import {
SafeAreaView,
@@ -177,13 +187,13 @@ import {
const App = () => {
const agoraEngineRef = useRef(); // IRtcEngine instance
const [isJoined, setIsJoined] = useState(false); // Whether the local user has joined the channel
- const [remoteUid, setRemoteUid] = useState(0); // Remote user UID
+ const [remoteUid, setRemoteUid] = useState(0); // Uid of the remote user
const [message, setMessage] = useState(''); // User prompt message
- // Render the user interface
+ // Render user interface
return (
- Agora Voice Call Quick Start
+ Agora Voice Calling Quickstart
Join Channel
@@ -196,21 +206,21 @@ const App = () => {
style={styles.scroll}
contentContainerStyle={styles.scrollContainer}>
{isJoined ? (
- Local user UID: {uid}
+ Local user uid: {uid}
) : (
Join a channel
)}
{isJoined && remoteUid !== 0 ? (
- Remote user UID: {remoteUid}
+ Remote user uid: {remoteUid}
) : (
- Waiting for remote users to join
+ Waiting for remote user to join
)}
{message}
);
- // Display message
+ // Display information
function showMessage(msg: string) {
setMessage(msg);
}