### Create Offer for Session
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/BasicUsage.md
Initiate a call by creating an offer with defined session constraints. This starts ICE candidate gathering. Ensure to handle potential errors.
```javascript
try {
const offerDescription = await peerConnection.createOffer( sessionConstraints );
await peerConnection.setLocalDescription( offerDescription );
// Send the offerDescription to the other participant.
} catch( err ) {
// Handle Errors
};
```
--------------------------------
### JavaScript Code Block Example
Source: https://github.com/livekit/react-native-webrtc/blob/master/ISSUE_TEMPLATE.md
Use fenced code blocks with syntax highlighting for code samples. This helps in readability and understanding.
```javascript
console.log( 'Hello World' );
```
--------------------------------
### Get Available Media Devices
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/BasicUsage.md
Enumerate available media devices to determine the number of cameras or other media device information on the user's device.
```javascript
let cameraCount = 0;
try {
const devices = await mediaDevices.enumerateDevices();
devices.map( device => {
if ( device.kind != 'videoinput' ) { return; };
cameraCount = cameraCount + 1;
} );
} catch( err ) {
// Handle Error
};
```
--------------------------------
### Set iOS Platform Version
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/iOSInstallation.md
Ensure your Podfile specifies a minimum iOS platform version of '12.0' or higher to avoid installation errors. This is required for compatibility with the library.
```ruby
platform :ios, '12.0'
```
--------------------------------
### Get Local Media Stream
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/BasicUsage.md
Obtain a local media stream using getUserMedia with specified constraints. Optionally disable video tracks for voice-only calls.
```javascript
let localMediaStream;
let isVoiceOnly = false;
try {
const mediaStream = await mediaDevices.getUserMedia( mediaConstraints );
if ( isVoiceOnly ) {
let videoTrack = await mediaStream.getVideoTracks()[ 0 ];
videoTrack.enabled = false;
};
localMediaStream = mediaStream;
} catch( err ) {
// Handle Error
};
```
--------------------------------
### Get Display Media Stream
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/BasicUsage.md
Capture the device screen using getDisplayMedia. Note that Android 10+ requires a foreground service for screen capturing to function correctly.
```javascript
try {
const mediaStream = await mediaDevices.getDisplayMedia();
localMediaStream = mediaStream;
} catch( err ) {
// Handle Error
};
```
--------------------------------
### Create Offer and Set Local Description
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/CallGuide.md
Initiates the call by creating an offer and setting it as the local description. Ensure session constraints are defined before creating the offer.
```javascript
let sessionConstraints = {
offerToReceiveAudio: true,
offerToReceiveVideo: true,
voiceActivityDetection: true
};
try {
const offerDescription = await peerConnection.createOffer( sessionConstraints );
await peerConnection.setLocalDescription( offerDescription );
// Send the offerDescription to the other participant.
} catch( err ) {
// Handle Errors
};
```
--------------------------------
### Enable Media Projection Service for Screen-Sharing
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/AndroidInstallation.md
Initialize `WebRTCModuleOptions` in your main activity's `onCreate` method to enable the media projection service for screen sharing.
```java
// Initialize the WebRTC module options.
WebRTCModuleOptions options = WebRTCModuleOptions.getInstance();
options.enableMediaProjectionService = true;
```
--------------------------------
### Declare Camera and Microphone Permissions
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/iOSInstallation.md
Add these keys to your Info.plist file to request user permission for camera and microphone access. Provide clear descriptions for each.
```xml
NSCameraUsageDescription
Camera permission description
NSMicrophoneUsageDescription
Microphone permission description
```
--------------------------------
### Create Answer to Offer
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/BasicUsage.md
Respond to an incoming offer by creating an answer. This involves setting the remote description, creating the answer, and setting the local description. Proper ICE candidate handling is crucial.
```javascript
try {
// Use the received offerDescription
const offerDescription = new RTCSessionDescription( offerDescription );
await peerConnection.setRemoteDescription( offerDescription );
const answerDescription = await peerConnection.createAnswer();
await peerConnection.setLocalDescription( answerDescription );
// Send the answerDescription back as a response to the offerDescription.
} catch( err ) {
// Handle Errors
};
```
--------------------------------
### Create Peer Connection and Add Media Stream
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/CallGuide.md
Create a peer connection with ICE servers for establishing connections. Event listeners handle connection state changes, ICE candidates, and remote tracks. Add the local media stream to the peer connection to initiate the process.
```javascript
let peerConstraints = {
iceServers: [
{
urls: 'stun:stun.l.google.com:19302'
}
]
};
let peerConnection = new RTCPeerConnection( peerConstraints );
peerConnection.addEventListener( 'connectionstatechange', event => {
switch( peerConnection.connectionState ) {
case 'closed':
// You can handle the call being disconnected here.
break;
};
} );
peerConnection.addEventListener( 'icecandidate', event => {
// When you find a null candidate then there are no more candidates.
// Gathering of candidates has finished.
if ( !event.candidate ) { return; };
// Send the event.candidate onto the person you're calling.
// Keeping to Trickle ICE Standards, you should send the candidates immediately.
} );
peerConnection.addEventListener( 'icecandidateerror', event => {
// You can ignore some candidate errors.
// Connections can still be made even when errors occur.
} );
peerConnection.addEventListener( 'iceconnectionstatechange', event => {
switch( peerConnection.iceConnectionState ) {
case 'connected':
case 'completed':
// You can handle the call being connected here.
// Like setting the video streams to visible.
break;
};
} );
peerConnection.addEventListener( 'negotiationneeded', event => {
// You can start the offer stages here.
// Be careful as this event can be called multiple times.
} );
peerConnection.addEventListener( 'signalingstatechange', event => {
switch( peerConnection.signalingState ) {
case 'closed':
// You can handle the call being disconnected here.
break;
};
} );
peerConnection.addEventListener( 'track', event => {
// Grab the remote track from the connected participant.
remoteMediaStream = remoteMediaStream || new MediaStream();
remoteMediaStream.addTrack( event.track, remoteMediaStream );
} );
// Add our stream to the peer connection.
localMediaStream.getTracks().forEach(
track => peerConnection.addTrack( track, localMediaStream );
);
```
--------------------------------
### Google's Free STUN Servers
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/ImprovingCallReliability.md
These are publicly available STUN servers provided by Google. They can be used to discover public IP addresses and NAT types, aiding in establishing direct peer connections. Ensure your TURN server is configured with authentication for production use.
```text
stun:stun.l.google.com:19302
```
```text
stun:stun1.l.google.com:19302
```
```text
stun:stun2.l.google.com:19302
```
```text
stun:stun3.l.google.com:19302
```
```text
stun:stun4.l.google.com:19302
```
--------------------------------
### Prepare Media Stream
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/CallGuide.md
Obtain a media stream for the camera and microphone. You can disable the video track by setting `isVoiceOnly` to true, and re-enable it later if needed. Permissions for camera and microphone will be prompted.
```javascript
let mediaConstraints = {
audio: true,
video: {
frameRate: 30,
facingMode: 'user'
}
};
let localMediaStream;
let remoteMediaStream;
let isVoiceOnly = false;
try {
const mediaStream = await mediaDevices.getUserMedia( mediaConstraints );
if ( isVoiceOnly ) {
let videoTrack = await mediaStream.getVideoTracks()[ 0 ];
videoTrack.enabled = false;
};
localMediaStream = mediaStream;
} catch( err ) {
// Handle Error
};
```
--------------------------------
### Set Remote Description, Create Answer, and Set Local Description
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/CallGuide.md
Responds to an incoming offer by setting it as the remote description, creating an answer, and setting it as the local description. Processes any pending ICE candidates before sending the answer.
```javascript
try {
// Use the received offerDescription
const offerDescription = new RTCSessionDescription( offerDescription );
await peerConnection.setRemoteDescription( offerDescription );
const answerDescription = await peerConnection.createAnswer();
await peerConnection.setLocalDescription( answerDescription );
// Here is a good place to process candidates.
processCandidates();
// Send the answerDescription back as a response to the offerDescription.
} catch( err ) {
// Handle Errors
};
```
--------------------------------
### Create Data Channel
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/BasicUsage.md
Create a data channel on the peer connection. This action triggers the negotiation needed event. Ensure event listeners for 'open', 'close', and 'message' are attached.
```javascript
let datachannel = peerConnection.createDataChannel( 'my_channel' );
datachannel.addEventListener( 'open', event => {} );
datachannel.addEventListener( 'close', event => {} );
datachannel.addEventListener( 'message', message => {} );
```
--------------------------------
### Add Media Stream to Peer Connection
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/BasicUsage.md
Add media tracks from a local media stream to the peer connection. This action triggers the negotiation needed event.
```javascript
localMediaStream.getTracks().forEach(
track => peerConnection.addTrack( track, localMediaStream )
);
```
--------------------------------
### Create RTCPeerConnection
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/BasicUsage.md
Instantiate an RTCPeerConnection with defined peer constraints to initiate a call. Event listeners can be attached directly or by overwriting functions.
```javascript
let peerConnection = new RTCPeerConnection( peerConstraints );
peerConnection.addEventListener( 'connectionstatechange', event => {} );
peerConnection.addEventListener( 'icecandidate', event => {} );
peerConnection.addEventListener( 'icecandidateerror', event => {} );
peerConnection.addEventListener( 'iceconnectionstatechange', event => {} );
peerConnection.addEventListener( 'icegatheringstatechange', event => {} );
peerConnection.addEventListener( 'negotiationneeded', event => {} );
peerConnection.addEventListener( 'signalingstatechange', event => {} );
peerConnection.addEventListener( 'track', event => {} );
```
--------------------------------
### Declare Android Permissions
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/AndroidInstallation.md
Add these permissions to `AndroidManifest.xml` for camera, audio, and network access. Ensure API level compatibility for Bluetooth permissions.
```xml
```
```xml
```
--------------------------------
### CallKit Integration for Audio Session Management (Objective-C)
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/iOSInstallation.md
Implement these methods in your CXProviderDelegate to correctly manage the audio session when using CallKit. This ensures proper audio routing and handling of calls.
```objective-c
#import
- (void) provider:(CXProvider *) provider didActivateAudioSession:(AVAudioSession *) audioSession {
[[RTCAudioSession sharedInstance] audioSessionDidActivate:[AVAudioSession sharedInstance]];
}
- (void) provider:(CXProvider *) provider didDeactivateAudioSession:(AVAudioSession *) audioSession {
[[RTCAudioSession sharedInstance] audioSessionDidDeactivate:[AVAudioSession sharedInstance]];
}
```
--------------------------------
### Handle Incoming Data Channel
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/BasicUsage.md
Listen for the 'datachannel' event on the peer connection to handle data channels created by the remote participant. Attach the same event listeners as used when creating a data channel.
```javascript
peerConnection.addEventListener( 'datachannel', event => {
let datachannel = event.channel;
// Now you've got the datachannel.
// You can hookup and use the same events as above ^
} );
```
--------------------------------
### Import Core Components
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/BasicUsage.md
Import all necessary components and APIs from the react-native-webrtc library for immediate use.
```javascript
import {
ScreenCapturePickerView,
RTCPeerConnection,
RTCIceCandidate,
RTCSessionDescription,
RTCView,
MediaStream,
MediaStreamTrack,
mediaDevices,
registerGlobals
} from 'react-native-webrtc';
```
--------------------------------
### Set Audio Category to Media (Kotlin)
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/AndroidInstallation.md
Modify `MainApplication.kt` to set the audio category to `USAGE_MEDIA` for non-call audio streams. This requires importing necessary classes and configuring `JavaAudioDeviceModule`.
```kotlin
// add imports
import com.oney.WebRTCModule.WebRTCModuleOptions;
import android.media.AudioAttributes
import org.webrtc.audio.JavaAudioDeviceModule;
class MainApplication : Application(), ReactApplication {
override fun onCreate() {
// append this before WebRTCModule initializes
val options = WebRTCModuleOptions.getInstance()
val audioAttributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.build()
options.audioDeviceModule = JavaAudioDeviceModule.builder(this)
.setAudioAttributes(audioAttributes)
.createAudioDeviceModule()
}
}
```
--------------------------------
### Set Audio Category to Media (Java)
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/AndroidInstallation.md
Modify `MainApplication.java` to set the audio category to `USAGE_MEDIA` for non-call audio streams. This requires importing necessary classes and configuring `JavaAudioDeviceModule`.
```java
// add imports
import com.oney.WebRTCModule.WebRTCModuleOptions;
import android.media.AudioAttributes;
import org.webrtc.audio.JavaAudioDeviceModule;
public class MainApplication extends Application implements ReactApplication {
@Override
public void onCreate() {
// append this before WebRTCModule initializes
WebRTCModuleOptions options = WebRTCModuleOptions.getInstance();
AudioAttributes audioAttributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.build();
options.audioDeviceModule = JavaAudioDeviceModule.builder(this)
.setAudioAttributes(audioAttributes)
.createAudioDeviceModule();
}
}
```
--------------------------------
### Define Session Constraints
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/BasicUsage.md
Configure session constraints to specify desired media capabilities, such as offering to receive audio and video, and enabling voice activity detection.
```javascript
let sessionConstraints = {
offerToReceiveAudio: true,
offerToReceiveVideo: true,
voiceActivityDetection: true
};
```
--------------------------------
### Declare Screen-Sharing Permissions
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/AndroidInstallation.md
Include these permissions in `AndroidManifest.xml` to enable foreground services for screen sharing on Android 14 and later.
```xml
```
--------------------------------
### Render Media Stream with RTCView
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/BasicUsage.md
Use the RTCView component to display a media stream. Configure mirroring and object fitting as needed. The streamURL prop is required.
```javascript
```
--------------------------------
### Set tvOS Platform Version in Podfile
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/tvOSInstallation.md
Ensure your Podfile targets tvOS 16.0 or higher, as older versions do not support WebRTC.
```ruby
platform :tvos, '16.0'
```
--------------------------------
### Handle Remote ICE Candidates
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/CallGuide.md
Manages incoming ICE candidates, adding them to the peer connection. Stores candidates if the remote description is not yet set, processing them later.
```javascript
let remoteCandidates = [];
function handleRemoteCandidate( iceCandidate ) {
iceCandidate = new RTCIceCandidate( iceCandidate );
if ( peerConnection.remoteDescription == null ) {
return remoteCandidates.push( iceCandidate );
};
return peerConnection.addIceCandidate( iceCandidate );
};
function processCandidates() {
if ( remoteCandidates.length < 1 ) { return; };
remoteCandidates.map( candidate => peerConnection.addIceCandidate( candidate ) );
remoteCandidates = [];
};
```
--------------------------------
### Define Peer Connection Constraints
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/BasicUsage.md
Define constraints for the RTCPeerConnection, primarily specifying STUN servers for ICE candidate gathering. Consider using TURN servers for improved call reliability.
```javascript
let peerConstraints = {
iceServers: [
{
urls: 'stun:stun.l.google.com:19302'
}
]
};
```
--------------------------------
### Enable Java 8 Support in Gradle
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/AndroidInstallation.md
Configure `android/app/build.gradle` to enable Java 8 compatibility by setting source and target compatibility.
```gradle
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
```
--------------------------------
### Define Media Constraints
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/BasicUsage.md
Define media constraints for getUserMedia, specifying whether to capture audio and video, and configuring video properties like frame rate and facing mode.
```javascript
let mediaConstraints = {
audio: true,
video: {
frameRate: 30,
facingMode: 'user'
}
};
```
--------------------------------
### Handle Video Dimension Changes
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/BasicUsage.md
Implement the onDimensionsChange callback to react to video dimension updates. This is useful for UI adjustments or analytics. Ensure you have imported React and useState.
```javascript
import React, { useState } from 'react';
const [videoDimensions, setVideoDimensions] = useState({ width: 0, height: 0 });
{
const { width, height } = event.nativeEvent;
setVideoDimensions({ width, height });
console.log(`Video dimensions changed: ${width}x${height}`);
}}
/>
```
--------------------------------
### Fix UnsatisfiedLinkError on Android
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/AndroidInstallation.md
Add this line to `android/gradle.properties` to resolve a WebRTC runtime issue on certain devices.
```properties
# This one fixes a weird WebRTC runtime problem on some devices.
# https://github.com/jitsi/jitsi-meet-issues/7911#issuecomment-714323255
android.enableDexingArtifactTransform.desugaring=false
```
--------------------------------
### Switch Active Camera
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/BasicUsage.md
Change the active camera by applying constraints to the video track, specifying the desired facing mode ('user' for front, 'environment' for back). Ensure there is more than one camera available before attempting to switch.
```javascript
let isFrontCam = true;
try {
// Taken from above, we don't want to flip if we don't have another camera.
if ( cameraCount < 2 ) { return; };
const videoTrack = localMediaStream.getVideoTracks()[0];
const constraints = { facingMode: isFrontCam ? 'user' : 'environment' };
videoTrack.applyConstraints(constraints);
// _switchCamera is deprecated as of 124.0.5
// videoTrack._switchCamera();
isFrontCam = !isFrontCam;
} catch( err ) {
// Handle Error
};
```
--------------------------------
### Enable Background Camera Access
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/iOSInstallation.md
Set the `enableMultitaskingCameraAccess` flag to YES in your AppDelegate.m file to allow background camera access. This requires the 'voip' background mode capability for iOS 18+.
```objective-c
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[WebRTCModuleOptions sharedInstance].enableMultitaskingCameraAccess = YES;
// ...
}
```
--------------------------------
### Set Remote Description to Finalize Handshake
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/CallGuide.md
Completes the call handshake by setting the received answer as the remote description. This step is performed by the initial call initiator.
```javascript
try {
// Use the received answerDescription
const answerDescription = new RTCSessionDescription( answerDescription );
await peerConnection.setRemoteDescription( answerDescription );
} catch( err ) {
// Handle Error
};
```
--------------------------------
### Update package.json for tvOS
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/tvOSInstallation.md
Modify your project's package.json to use the `react-native-tvos` fork for tvOS compatibility.
```json
"react-native": "npm:react-native-tvos@0.69.8-2"
```
--------------------------------
### Control Remote Audio Track Volume
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/BasicUsage.md
Adjust the volume of individual remote audio tracks using the _setVolume function. The volume should be a number between 0 and 10, with 1 being the default.
```javascript
const audioTrack = remoteMediaStream.getAudioTracks()[0];
audioTrack._setVolume(0.5);
```
--------------------------------
### CallKit Integration for Audio Session Management (JavaScript)
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/iOSInstallation.md
Use these JavaScript methods to control the audio session when integrating with CallKit from your React Native application. These methods mirror the native Objective-C calls.
```javascript
import { RTCAudioSession } from '@livekit/react-native-webrtc'
// Call as needed.
RTCAudioSession.audioSessionDidActivate();
RTCAudioSession.audioSessionDidDeactivate();
```
--------------------------------
### Send Message via Data Channel
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/BasicUsage.md
Send data over an established data channel. Be mindful of data size limits, as sending large amounts is not advised.
```javascript
datachannel.send( 'Hey There!' );
```
--------------------------------
### Register Global WebRTC Functions
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/BasicUsage.md
Register global WebRTC functions, essential when integrating with libraries that expect browser-based WebRTC APIs or for react-native-web compatibility.
```javascript
registerGlobals();
```
--------------------------------
### Destroy Peer Connection
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/BasicUsage.md
Always dispose of peer connection resources when ending a call to prepare for subsequent calls.
```javascript
peerConnection.close();
peerConnection = null;
```
--------------------------------
### Destroy Data Channel
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/BasicUsage.md
Close a data channel manually. While data channels are typically destroyed automatically when the peer connection is destroyed, manual closure is good practice.
```javascript
datachannel.close();
datachannel = null;
```
--------------------------------
### Destroy Local Media Stream
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/BasicUsage.md
Clean up by stopping all tracks of the local media stream and setting the stream variable to null. This is typically done after a call has ended.
```javascript
localMediaStream.getTracks().forEach(
track => track.stop()
);
localMediaStream = null;
```
--------------------------------
### Resolve NoSuchMethodError on Android 9
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/AndroidInstallation.md
Adjust `compileOptions` in `android/app/build.gradle` and upgrade Gradle versions to fix a `NoSuchMethodError` related to `FloatBuffer` on Android 9.
```gradle
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_11
}
```
--------------------------------
### Toggle Microphone Mute
Source: https://github.com/livekit/react-native-webrtc/blob/master/Documentation/BasicUsage.md
Control the microphone's active state by toggling the 'enabled' property of the audio track. This can be applied to both local and remote tracks.
```javascript
let isMuted = false;
try {
const audioTrack = await localMediaStream.getAudioTracks()[ 0 ];
audioTrack.enabled = !audioTrack.enabled;
isMuted = !isMuted;
} catch( err ) {
// Handle Error
};
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.