### 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.