Platforms:
People using a version < 1.0.1 please move to 1.0.1 since the project changed a lot internally to support the stable TwilioVideo version.
yarn add https://github.com/blackuy/react-native-twilio-video-webrtc
npm install https://github.com/blackuy/react-native-twilio-video-webrtc --save
pod 'react-native-twilio-video-webrtc', path: '../node_modules/react-native-twilio-video-webrtc'
Note that this will automatically pull in the appropriate version of the underlying TwilioVideo
pod.
pod install
pod 'TwilioVideo'
pod install
Libraries
directory fromnode_modules/react-native-twilio-video-webrtc/ios/RNTwilioVideoWebRTC.xcodeproj
Add libRNTwilioVideoWebRTC.a
to your XCode project target’s Linked Frameworks and Libraries
Update Build Settings
Find Search Paths
and add $(SRCROOT)/../node_modules/react-native-twilio-video-webrtc/ios
with recursive
to Framework Search Paths
and Library Search Paths
Be sure to increment your iOS Deployment Target to at least iOS 11 through XCode and your Podfile
contains
platform :ios, '11.0'
To enable camera usage and microphone usage you will need to add the following entries to your Info.plist
file:
<key>NSCameraUsageDescription</key>
<string>Your message to user when the camera is accessed for the first time</string>
<key>NSMicrophoneUsageDescription</key>
<string>Your message to user when the microphone is accessed for the first time</string>
TwilioVideo version 1.3.8 (latest) has the following know issues.
As with iOS, make sure the package is installed:
yarn add https://github.com/blackuy/react-native-twilio-video-webrtc
Then add the library to your settings.gradle
file:
include ':react-native-twilio-video-webrtc'
project(':react-native-twilio-video-webrtc').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-twilio-video-webrtc/android')
And include the library in your dependencies in android/app/build.gradle
:
dependencies {
.....
.....
.....
compile project(':react-native-twilio-video-webrtc')
}
You will also need to update this file so that you compile with java 8 features:
android {
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
}
Now you’re ready to load the package in MainApplication.java
. In the imports section, add this:
import com.twiliorn.library.TwilioPackage;
Then update the getPackages()
method:
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
...
new TwilioPackage()
);
}
For most applications, you’ll want to add camera and audio permissions to your AndroidManifest.xml
file:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
<uses-feature android:name="android.hardware.microphone" android:required="false" />
Newer versions of Android have a different permissions model. You will need to use the PermissionsAndroid
class in react-native
in order to request the CAMERA
and RECORD_AUDIO
permissions.
Under default settings, the Android build will fail if the total number of symbols exceeds a certain threshold. If you should encounter this issue when adding this library (e.g., if your build fails with com.android.dex.DexIndexOverflowException
), you can turn on jumbo mode by editing your app/build.gradle
:
android {
...
dexOptions {
jumboMode true
}
}
If you are using proguard (very likely), you will also need to ensure that the symbols needed by this library are not stripped. To do that, add these two lines to proguard-rules.pro
:
-keep class org.webrtc.** { *; }
-keep class com.twilio.** { *; }
-keep class tvi.webrtc.** { *; }
You can see the documentation here.
We have three important components to understand:
import {
TwilioVideo,
TwilioVideoLocalView,
TwilioVideoParticipantView
} from 'react-native-twilio-video-webrtc'
TwilioVideo
/ is responsible for connecting to rooms, events delivery and camera/audio.TwilioVideoLocalView
/ is responsible local camera feed viewTwilioVideoParticipantView
/ is responsible remote peer’s camera feed viewHere you can see a complete example of a simple application that uses almost all the apis:
import React, { Component } from 'react';
import {
TwilioVideoLocalView,
TwilioVideoParticipantView,
TwilioVideo
} from 'react-native-twilio-video-webrtc'
export default class Example extends Component {
state = {
isAudioEnabled: true,
isVideoEnabled: true,
status: 'disconnected',
participants: new Map(),
videoTracks: new Map(),
token: ''
}
_onConnectButtonPress = () => {
this.refs.twilioVideo.connect({ accessToken: this.state.token })
this.setState({status: 'connecting'})
}
_onEndButtonPress = () => {
this.refs.twilioVideo.disconnect()
}
_onMuteButtonPress = () => {
this.refs.twilioVideo.setLocalAudioEnabled(!this.state.isAudioEnabled)
.then(isEnabled => this.setState({isAudioEnabled: isEnabled}))
}
_onFlipButtonPress = () => {
this.refs.twilioVideo.flipCamera()
}
_onRoomDidConnect = ({ roomName, error }) => {
console.log('onRoomDidConnect: ', roomName);
this.setState({ status: 'connected' });
};
_onRoomDidDisconnect = ({roomName, error}) => {
console.log("ERROR: ", error)
this.setState({status: 'disconnected'})
}
_onRoomDidFailToConnect = (error) => {
console.log("ERROR: ", error)
this.setState({status: 'disconnected'})
}
_onParticipantAddedVideoTrack = ({participant, track}) => {
console.log("onParticipantAddedVideoTrack: ", participant, track)
this.setState({
videoTracks: new Map([
...this.state.videoTracks,
[track.trackSid, { participantSid: participant.sid, videoTrackSid: track.trackSid }]
]),
});
}
_onParticipantRemovedVideoTrack = ({participant, track}) => {
console.log("onParticipantRemovedVideoTrack: ", participant, track)
const videoTracks = new Map(this.state.videoTracks)
videoTracks.delete(track.trackSid)
this.setState({videoTracks})
}
render() {
return (
<View style={styles.container}>
{
this.state.status === 'disconnected' &&
<View>
<Text style={styles.welcome}>
React Native Twilio Video
</Text>
<TextInput
style={styles.input}
autoCapitalize='none'
value={this.state.token}
onChangeText={(text) => this.setState({token: text})}>
</TextInput>
<Button
title="Connect"
style={styles.button}
onPress={this._onConnectButtonPress}>
</Button>
</View>
}
{
(this.state.status === 'connected' || this.state.status === 'connecting') &&
<View style={styles.callContainer}>
{
this.state.status === 'connected' &&
<View style={styles.remoteGrid}>
{
Array.from(this.state.videoTracks, ([trackSid, trackIdentifier]) => {
return (
<TwilioVideoParticipantView
style={styles.remoteVideo}
key={trackSid}
trackIdentifier={trackIdentifier}
/>
)
})
}
</View>
}
<View
style={styles.optionsContainer}>
<TouchableOpacity
style={styles.optionButton}
onPress={this._onEndButtonPress}>
<Text style={{fontSize: 12}}>End</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.optionButton}
onPress={this._onMuteButtonPress}>
<Text style={{fontSize: 12}}>{ this.state.isAudioEnabled ? "Mute" : "Unmute" }</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.optionButton}
onPress={this._onFlipButtonPress}>
<Text style={{fontSize: 12}}>Flip</Text>
</TouchableOpacity>
<TwilioVideoLocalView
enabled={true}
style={styles.localVideo}
/>
</View>
</View>
}
<TwilioVideo
ref="twilioVideo"
onRoomDidConnect={ this._onRoomDidConnect }
onRoomDidDisconnect={ this._onRoomDidDisconnect }
onRoomDidFailToConnect= { this._onRoomDidFailToConnect }
onParticipantAddedVideoTrack={ this._onParticipantAddedVideoTrack }
onParticipantRemovedVideoTrack= { this._onParticipantRemovedVideoTrack }
/>
</View>
);
}
}
AppRegistry.registerComponent('Example', () => Example);
To run the example application:
cd Example
yarn install
cd ios && pod install
open Example.xcworkspace
s.dependency 'TwilioVideo', '~> 2.2.0'
Both participants and tracks are uniquely identified by their sid
/trackSid
field. The trackId
field no longer exists and should be replaced by trackSid
. Commensurate with this change, participant views now expect participantSid
and videoTrackSid
keys in the trackIdentity
prop (instead of identity
and trackId
).
Make sure you’re listening to participant events via onParticipant{Added/Removed}VideoTrack
rather than onParticipant{Enabled/Disabled}Track
.
Author: blackuy
Source Code: https://github.com/blackuy/react-native-twilio-video-webrtc
#react-native #react #mobile-apps