The Amazon Chime SDK is a set of real-time communications components that developers can use to quickly add audio calling, video calling, and screen sharing capabilities to their own applications. Developers can leverage the same communication infrastructure and services that power Amazon Chime, an online meetings service from AWS, to deliver engaging experiences in their applications. For instance, they can add video calling to a healthcare application so patients can consult remotely with doctors on health issues, or add audio calling to a company website so customers can quickly connect with sales. By using the Amazon Chime SDK, developers can eliminate the cost, complexity, and friction of creating and maintaining their own real-time communication infrastructure and services.
This demo shows how to integrate the Amazon Chime SDK into your React Native (or RN) application.
For more details about the SDK APIs, please refer to the Getting Started guide of the following SDK repositories:
Note: Deploying the Amazon Chime SDK demo applications contained in this repository will cause your AWS Account to be billed for services, including the Amazon Chime SDK, used by the application.
- Run
git clone
to download the source code - Run
npm install
inside the folder that was just created
The Mobile SDKs for Android could be downloaded from the Maven Central repository, by integrated into your Android project's Gradle files, or you can be directly embedded via .aar files.
We recommend obtaining the dependency from Maven. To obtain the dependencies from Maven, add the dependencies to android/app/build.gradle
.
dependencies {
implementation 'software.aws.chimesdk:amazon-chime-sdk-media:$MEDIA_VERSION'
implementation 'software.aws.chimesdk:amazon-chime-sdk:$SDK_VERSION'
}
The version numbers could be obtained from the release.
You can also download the Mobile SDKs from S3 following these steps:
- Create a folder named
libs
underandroid/app
- Download the Amazon Chime SDK binaries
- Unzip, copy both
amazon-chime-sdk.aar
andamazon-chime-sdk-media.aar
into theandroid/app/libs
folder
With pod 'AmazonChimeSDK-Bitcode', '0.22.7'
declared in the ios/Podfile
, the specified version of AmazonChimeSDK-Bitcode
pod will be downloaded and integrated when you run pod install
in the step 5 below.
AmazonChimeSDK-No-Bitcode
is available in Cocoapods as well.
The current version of Demo app works with AmazonChimeSDK up to 0.22.7
.
Follow the instructions in amazon-chime-sdk-js to deploy the serverless demo.
Update SERVER_URL
and SERVER_REGION
in src/utils/Api.js
with the server URL and region of the serverless demo you created.
Run npm start
to start the React Native development server.
-
Connect a physical Android testing device (we currently do not support x86 architecture/simulators) to your computer
-
Run
npx react-native run-android
which builds and installs the demo onto the testing device -
In order to run on single device run
npx react-native run-android --deviceId=<device-id>
. Device id can be obtained fromadb devices
- Run
pod install
inios
folder - Open
ios/RNDemo.xcworkspace
in Xcode - Select iOS simulator or a testing device, then build and run the demo application
Follow the steps below to add the Amazon Chime SDK into your React Native projects for both iOS and Android.
The following camera and microphone permissions need to be granted to enable audio and video functions.
android.permission.CAMERA
android.permission.MODIFY_AUDIO_SETTINGS
android.permission.RECORD_AUDIO
NSCameraUsageDescription
NSMicrophoneUsageDescription
More details on how to request permissions can be found in Android and iOS official documents.
You'll need following libraries to be able to build the Android application.
From build.gradle
buildscript {
ext {
kotlin_version = '1.3.71'
minSdkVersion = 21
compileSdkVersion = 29
targetSdkVersion = 29
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
allprojects {
repositories {
flatDir {
dirs 'libs'
}
}
}
From app/build.gradle
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
dependencies {
implementation(name: 'amazon-chime-sdk', ext: 'aar')
implementation(name: 'amazon-chime-sdk-media', ext: 'aar')
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3'
implementation 'com.google.code.gson:gson:2.8.6'
}
You need Native Module to proxy calls to the Amazon Chime SDK. A Native Module exposes native methods as JavaScript functions to be used in the React Native code. And Amazon Chime SDK callbacks are converted to React Native events that are handled by JavaScript listeners.
Android: Send Events to JavaScript and iOS: Send Events to JavaScript provide good examples on how to pass events from native to React Native. You can also look at the following files in our demo application for reference.
- React Native: Bridge.js
- iOS: NativeMobileSDKBridge.h and NativeMobileSDKBridge.m
- Android: NativeMobileSDKBridge.kt and RNEventEmitter.kt
To directly reuse code from this demo, here are the files you likely need and main functionality of each file.
src/utils/Bridge.js
: Native Module API calls and the event handler singleton.src/components/RNVideoRenderView.js
: Wrapper for the video tile UI component.
Add these files to you iOS project through Xcode
ios/RNDemo/MeetingObserver.h
andios/RNDemo/MeetingObserver.m
: Event handlers to pass Amazon Chime SDK events into React Native.ios/RNDemo/NativeMobileSDKBridge.h
andios/RNDemo/NativeMobileSDKBridge.m
: Functions that will be available in React Native through Native Module.ios/RNDemo/RNVideoViewManager.h
andios/RNDemo/RNVideoViewManager.m
: UI component manager.
The following files are all under android/app/src/main/java/com/amazonaws/services/chime/rndemo
.
If you are copy pasting the following files, make sure to adjust the package path and import path accordingly at the top of these files.
NativeMobileSDKBridge.kt
:Functions that will be available in React Native through Native Module.RNEventEmitter.kt
: Utility class that provides helper to send events to React Native.MeetingObservers.kt
: Event handlers to pass Amazon Chime SDK events into React Native.RNVideoViewManager.kt
: UI component manager.NativeMobileSDKBridgePackage.kt
: Package definition to register the bridge in the Android application.MainApplication.java
: Because React Native framework already generates this file for you, you only need to add the following line in functionprotected List<ReactPackage> getPackages()
to register the Native Module.
packages.add(new NativeMobileSDKBridgePackage());
- When the login button is pressed,
startMeeting()
inLogin.js
is called. - After
App.js
completes HTTP request, the meeting response object is passed intoNativeFuntion.startMeeting()
- As defined in
Bridge.js
, the function will call the corresponding native platform code, ochastrated by React Bridge.- For iOS
// NativeMobileSDKBridge.m RCT_EXPORT_METHOD(startMeeting:(NSDictionary *)meetingInfoDict attendeeInfo:(NSDictionary *)attendeeInfoDict)
- For Android
// ChimeReactnativeSDKDemoManager.kt @ReactMethod fun startMeeting(meetingInfo: ReadableMap, attendeeInfo: ReadableMap)
- In the native code,
startMeeting()
function will do the following.- Construct
MeetingSession
- Bind
AudioVideoObserver
which will listen to the Amazon Chime SDK events - Call
MeetingSession.AudioVideo.start()
- An
onAudioSessionStarted
event will be triggered and handled when the meeting is started- For iOS
// MeetingObservers.m - (void)audioSessionDidStartWithReconnecting:(BOOL)reconnecting { if (!reconnecting) { [_logger infoWithMsg:@"Meeting Started!"]; [_bridge sendEventWithName:kEventOnMeetingStart body:nil]; } }
- For Android
// MeetingObservers.kt override fun onAudioSessionStarted(reconnecting: Boolean) { logger.info(TAG, "Received event for audio session started. Reconnecting: $reconnecting") if (!reconnecting) { eventEmitter.sendReactNativeEvent(RNEventEmitter.RN_EVENT_MEETING_START, null) } }
- Construct
- A ReactNativeEvent called
OnMeetingStart
will be dispatched to the React Native side. - In
App.js
, there is a handler registered for this event.
// App.js
this.onMeetingStartSubscription = getSDKEventEmitter().addListener(MobileSDKEvent.OnMeetingStart, () => {
this.setState({ isInMeeting: true });
});
- After state
isInMeeting
is set to betrue
, user will start to see the meeting view.
A customized Android Native UI Component and iOS Native UI Component is created to render the video tile from the React Native side.
We need to find the reference of the native view to bind/unbind the video tile.
This can be done by [uiManager viewForReactTag:];
. React Native provides a way to find this "tag" by calling findNodeHandle
. We will pass the tagId as an integer from React Native to Native side.
// RNVideoRenderView.js
componentDidMount() {
setTimeout(() => {
NativeFunction.bindVideoView(findNodeHandle(this), this.props.tileId);
});
}
RCT_EXPORT_METHOD(bindVideoView:(NSNumber * _Nonnull)viewIdentifier tileId:(NSNumber * _Nonnull)tileId)
{
dispatch_async(dispatch_get_main_queue(), ^{
UIView* view = [self.bridge.uiManager viewForReactTag:viewIdentifier];
[meetingSession.audioVideo bindVideoViewWithVideoView:(DefaultVideoRenderView*)view tileId:[tileId integerValue]];
});
}
There is no viewForReactTag
function available in Android. Therefore, we use View Prop Setter to handle the binding.
// RNVideoViewManager.kt
@ReactProp(name = "tileId")
fun setTileId(renderView: DefaultVideoRenderView, tileId: Int) {
logger.info(TAG, "Setting tileId: $tileId")
ChimeReactNativeSDKDemoManager.meetingSession?.let {
it.audioVideo.bindVideoView(renderView, tileId)
}
}
If you want to create a video tile and then bind the video immediately, you may run into a race condition. The bind
function is called before the native UI component is fully initialized.
To mitigate this race condition, we need to make sure bind
function is called after UI component is initialized.
setTimeout(() => {
NativeFunction.bindVideoView(findNodeHandle(this), this.props.tileId);
});
In Android, we use setTileId()
to bind the video tile. This will solve the problem because setTileId()
is called after the UI component is initialized. You can read Direct Manipulation for more details.
If you no longer want to keep the demo active in your AWS account and want to avoid incurring AWS charges, the demo resources can be removed. Delete the two AWS CloudFormation (https://aws.amazon.com/cloudformation/) stacks created in the prerequisites that can be found in the AWS CloudFormation console (https://console.aws.amazon.com/cloudformation/home).
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.