### Initialize and Create PeerConnectionFactory Source: https://context7.com/webrtc-sdk/android/llms.txt Initialize the WebRTC library, create an EGL context for video rendering, and build the PeerConnectionFactory with hardware acceleration for encoders and decoders. Use WrappedVideoDecoderFactory to prevent frame drops with hardware decoders. ```java import org.webrtc.PeerConnectionFactory; import org.webrtc.DefaultVideoEncoderFactory; import org.webrtc.DefaultVideoDecoderFactory; import org.webrtc.EglBase; // Initialize WebRTC PeerConnectionFactory.initialize( PeerConnectionFactory.InitializationOptions.builder(context) .setEnableInternalTracer(true) .createInitializationOptions() ); // Create EGL context for video rendering EglBase eglBase = EglBase.create(); // Create encoder/decoder factories with hardware acceleration DefaultVideoEncoderFactory encoderFactory = new DefaultVideoEncoderFactory( eglBase.getEglBaseContext(), true, // enableIntelVp8Encoder true // enableH264HighProfile ); // Use WrappedVideoDecoderFactory to avoid frame drops with hardware decoders DefaultVideoDecoderFactory decoderFactory = new DefaultVideoDecoderFactory( eglBase.getEglBaseContext() ); // Build the PeerConnectionFactory PeerConnectionFactory factory = PeerConnectionFactory.builder() .setVideoEncoderFactory(encoderFactory) .setVideoDecoderFactory(decoderFactory) .createPeerConnectionFactory(); ``` -------------------------------- ### Create a PeerConnection Source: https://context7.com/webrtc-sdk/android/llms.txt Configure ICE servers (STUN/TURN) and create an RTC configuration. Then, create a PeerConnection with an observer to handle events like ICE candidates, track reception, and connection state changes. Ensure to implement other required observer methods. ```java import org.webrtc.PeerConnection; import org.webrtc.IceCandidate; import org.webrtc.MediaStream; import org.webrtc.RtpReceiver; // Configure ICE servers (STUN/TURN) List iceServers = new ArrayList<>(); iceServers.add(PeerConnection.IceServer.builder("stun:stun.l.google.com:19302").createIceServer()); iceServers.add(PeerConnection.IceServer.builder("turn:your-turn-server.com:3478") .setUsername("username") .setPassword("password") .createIceServer()); // Create RTC configuration PeerConnection.RTCConfiguration config = new PeerConnection.RTCConfiguration(iceServers); config.sdpSemantics = PeerConnection.SdpSemantics.UNIFIED_PLAN; // Create peer connection with observer PeerConnection peerConnection = factory.createPeerConnection(config, new PeerConnection.Observer() { @Override public void onIceCandidate(IceCandidate candidate) { // Send candidate to remote peer via signaling server signalingServer.sendIceCandidate(candidate.sdpMid, candidate.sdpMLineIndex, candidate.sdp); } @Override public void onTrack(RtpTransceiver transceiver) { MediaStreamTrack track = transceiver.getReceiver().track(); if (track instanceof VideoTrack) { // Attach remote video track to renderer ((VideoTrack) track).addSink(remoteVideoRenderer); } } @Override public void onConnectionChange(PeerConnection.PeerConnectionState newState) { Log.d("WebRTC", "Connection state: " + newState); } // ... implement other required methods }); ``` -------------------------------- ### Configure and Create Data Channel Source: https://context7.com/webrtc-sdk/android/llms.txt Set up a data channel with specific configurations for ordered delivery and retransmission limits. This is essential for reliable messaging and file transfers. ```java import org.webrtc.DataChannel; import java.nio.ByteBuffer; // Create data channel configuration DataChannel.Init init = new DataChannel.Init(); init.ordered = true; // Guarantee message order init.negotiated = false; // Let WebRTC negotiate init.maxRetransmits = 3; // Max retransmit attempts // Create data channel DataChannel dataChannel = peerConnection.createDataChannel("messaging", init); ``` -------------------------------- ### Capture and Add Local Audio Track Source: https://context7.com/webrtc-sdk/android/llms.txt Create an audio track from the device microphone with noise suppression and echo cancellation enabled. Configure audio constraints using MediaConstraints. ```java import org.webrtc.AudioSource; import org.webrtc.AudioTrack; import org.webrtc.MediaConstraints; // Configure audio constraints MediaConstraints audioConstraints = new MediaConstraints(); audioConstraints.mandatory.add(new MediaConstraints.KeyValuePair("googEchoCancellation", "true")); audioConstraints.mandatory.add(new MediaConstraints.KeyValuePair("googNoiseSuppression", "true")); audioConstraints.mandatory.add(new MediaConstraints.KeyValuePair("googAutoGainControl", "true")); // Create audio source and track AudioSource audioSource = factory.createAudioSource(audioConstraints); AudioTrack localAudioTrack = factory.createAudioTrack("audio0", audioSource); // Add audio track to peer connection peerConnection.addTrack(localAudioTrack, Arrays.asList("stream0")); // Mute/unmute audio localAudioTrack.setEnabled(false); // Mute localAudioTrack.setEnabled(true); // Unmute ``` -------------------------------- ### Capture and Add Local Video Track Source: https://context7.com/webrtc-sdk/android/llms.txt Capture video from the device camera and add it as a local video track to the peer connection. Ensure the SurfaceTextureHelper is properly initialized and the EGL context is available. ```java import org.webrtc.Camera2Enumerator; import org.webrtc.CameraVideoCapturer; import org.webrtc.SurfaceTextureHelper; import org.webrtc.VideoSource; import org.webrtc.VideoTrack; // Enumerate available cameras Camera2Enumerator enumerator = new Camera2Enumerator(context); String[] deviceNames = enumerator.getDeviceNames(); // Find front-facing camera CameraVideoCapturer videoCapturer = null; for (String deviceName : deviceNames) { if (enumerator.isFrontFacing(deviceName)) { videoCapturer = enumerator.createCapturer(deviceName, null); break; } } // Create video source and track SurfaceTextureHelper surfaceTextureHelper = SurfaceTextureHelper.create( "CaptureThread", eglBase.getEglBaseContext() ); VideoSource videoSource = factory.createVideoSource(videoCapturer.isScreencast()); videoCapturer.initialize(surfaceTextureHelper, context, videoSource.getCapturerObserver()); // Start capturing at 720p, 30fps videoCapturer.startCapture(1280, 720, 30); // Create video track and add to peer connection VideoTrack localVideoTrack = factory.createVideoTrack("video0", videoSource); localVideoTrack.addSink(localVideoRenderer); peerConnection.addTrack(localVideoTrack, Arrays.asList("stream0")); // Control video receive state localVideoTrack.setShouldReceive(true); // Enable receiving boolean isReceiving = localVideoTrack.shouldReceive(); // Check state // Check if track is disposed if (!localVideoTrack.isDisposed()) { localVideoTrack.setEnabled(false); // Mute video } ``` -------------------------------- ### libvpx License Header Source: https://github.com/webrtc-sdk/android/blob/main/Licenses/WEBRTC.md Standard BSD-style license header for the libvpx library. ```text Copyright (c) 2010, The WebM Project authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google, nor the WebM Project, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ``` -------------------------------- ### Create Audio Device Module with Custom Processing Source: https://context7.com/webrtc-sdk/android/llms.txt Configure JavaAudioDeviceModule to enable hardware echo cancellation and noise suppression, and to receive captured audio samples for external processing. Use this module when initializing the PeerConnectionFactory. ```java import org.webrtc.audio.AudioDeviceModule; import org.webrtc.audio.JavaAudioDeviceModule; // Create audio device module with external audio processing JavaAudioDeviceModule audioDeviceModule = JavaAudioDeviceModule.builder(context) .setUseHardwareAcousticEchoCanceler(true) .setUseHardwareNoiseSuppressor(true) .setSamplesReadyCallback(new JavaAudioDeviceModule.SamplesReadyCallback() { @Override public void onWebRtcAudioRecordSamplesReady(JavaAudioDeviceModule.AudioSamples samples) { // Process captured audio samples // samples.getData() - raw PCM audio data // samples.getSampleRate() - sample rate (e.g., 48000) // samples.getChannelCount() - number of channels } }) .createAudioDeviceModule(); // Use the audio device module in PeerConnectionFactory PeerConnectionFactory factory = PeerConnectionFactory.builder() .setAudioDeviceModule(audioDeviceModule) .setVideoEncoderFactory(encoderFactory) .setVideoDecoderFactory(decoderFactory) .createPeerConnectionFactory(); // Audio prewarm for faster startup audioDeviceModule.prewarmAudio(); ``` -------------------------------- ### Add Standard WebRTC Library Dependency Source: https://context7.com/webrtc-sdk/android/llms.txt Include this dependency in your app's build.gradle file to add the standard WebRTC library for full functionality. ```gradle implementation 'io.github.webrtc-sdk:android:144.7559.01' ``` -------------------------------- ### Add Prefixed WebRTC Library Dependency Source: https://context7.com/webrtc-sdk/android/llms.txt Use this dependency if your project includes other libraries that bundle WebRTC to avoid package name collisions. It relocates the 'org.webrtc' package. ```gradle implementation 'io.github.webrtc-sdk:android-prefixed:144.7559.01' ``` -------------------------------- ### libsrtp License Header Source: https://github.com/webrtc-sdk/android/blob/main/Licenses/WEBRTC.md Standard BSD-style license header for the libsrtp library. ```text /* * * Copyright (c) 2001-2017 Cisco Systems, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Cisco Systems, Inc. nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * */ ``` -------------------------------- ### Add Prefixed-Stripped WebRTC Library Dependency Source: https://context7.com/webrtc-sdk/android/llms.txt Incorporate this dependency for applications where APK size is critical. It removes software video codecs and is optimized for size. ```gradle implementation 'io.github.webrtc-sdk:android-prefixed-stripped:144.7559.01' ``` -------------------------------- ### Set Codec Preferences for Video Transceiver Source: https://context7.com/webrtc-sdk/android/llms.txt Configure preferred codecs for video transceivers to prioritize specific codecs like H.265/HEVC or AV1. This involves retrieving capabilities, reordering codecs, and applying them to the transceiver. ```java import org.webrtc.RtpTransceiver; import org.webrtc.RtpCapabilities; import org.webrtc.RtpParameters; // Get video transceiver RtpTransceiver videoTransceiver = null; for (RtpTransceiver transceiver : peerConnection.getTransceivers()) { if (transceiver.getMediaType() == MediaStreamTrack.MediaType.MEDIA_TYPE_VIDEO) { videoTransceiver = transceiver; break; } } // Get available codec capabilities RtpCapabilities capabilities = factory.getRtpSenderCapabilities(MediaStreamTrack.MediaType.MEDIA_TYPE_VIDEO); List codecs = capabilities.codecs; // Reorder codecs to prioritize H265 (HEVC) or AV1 List preferredCodecs = new ArrayList<>(); for (RtpCapabilities.CodecCapability codec : codecs) { if (codec.mimeType.equalsIgnoreCase("video/H265")) { preferredCodecs.add(0, codec); // Add H265 first } else if (codec.mimeType.equalsIgnoreCase("video/AV1")) { preferredCodecs.add(codec); } } preferredCodecs.addAll(codecs); // Add remaining codecs // Apply codec preferences videoTransceiver.setCodecPreferences(preferredCodecs); ``` -------------------------------- ### Add Prefixed WebRTC SDK Android Dependency Source: https://github.com/webrtc-sdk/android/blob/main/README.md Use this dependency for the shadowed version that moves the 'org.webrtc' package to 'livekit.org.webrtc', preventing conflicts with other WebRTC libraries. ```gradle dependencies { implementation 'io.github.webrtc-sdk:android-prefixed:144.7559.01' } ``` -------------------------------- ### Add WebRTC SDK Android Dependency Source: https://github.com/webrtc-sdk/android/blob/main/README.md Include this dependency to add the standard WebRTC pre-compiled library for Android to your project. ```gradle dependencies { implementation 'io.github.webrtc-sdk:android:144.7559.01' } ``` -------------------------------- ### Register Data Channel Observer Source: https://context7.com/webrtc-sdk/android/llms.txt Implement the DataChannel.Observer interface to handle state changes, monitor buffer amounts for flow control, and process incoming messages (both text and binary). ```java dataChannel.registerObserver(new DataChannel.Observer() { @Override public void onBufferedAmountChange(long previousAmount) { // Monitor buffer for flow control } @Override public void onStateChange() { DataChannel.State state = dataChannel.state(); if (state == DataChannel.State.OPEN) { Log.d("DataChannel", "Channel is open, ready to send"); } } @Override public void onMessage(DataChannel.Buffer buffer) { ByteBuffer data = buffer.data; byte[] bytes = new byte[data.remaining()]; data.get(bytes); if (buffer.binary) { // Handle binary data Log.d("DataChannel", "Received binary: " + bytes.length + " bytes"); } else { // Handle text message String message = new String(bytes, StandardCharsets.UTF_8); Log.d("DataChannel", "Received: " + message); } } }); ``` -------------------------------- ### Implement End-to-End Encryption with FrameCryptor Source: https://context7.com/webrtc-sdk/android/llms.txt Use the FrameCryptor API to enable end-to-end encryption for media streams. This involves creating a KeyProvider, setting encryption keys, and attaching FrameCryptors to RtpSenders and RtpReceivers. Ensure to handle cryptor state changes and ratchet keys for forward secrecy. ```java import org.webrtc.FrameCryptor; import org.webrtc.FrameCryptorFactory; import org.webrtc.KeyProvider; import org.webrtc.FrameCryptorKeyProvider; // Create key provider with options KeyProviderOptions options = new KeyProviderOptions( true, // sharedKey 128, // ratchetWindowSize new byte[32], // ratchetSalt 16, // keyRingSize true // discardFrameWhenCryptorNotReady ); FrameCryptorKeyProvider keyProvider = FrameCryptorFactory.createFrameCryptorKeyProvider(options); // Set encryption key for participant byte[] encryptionKey = generateSecureKey(); // Your key generation keyProvider.setKey("participant-id", 0, encryptionKey); // Or set a shared key for all participants keyProvider.setSharedKey(0, encryptionKey); // Create frame cryptor for sender RtpSender videoSender = peerConnection.getSenders().get(0); FrameCryptor senderCryptor = FrameCryptorFactory.createFrameCryptorForRtpSender( factory, videoSender, "participant-id", FrameCryptor.Algorithm.AES_GCM, keyProvider ); // Create frame cryptor for receiver RtpReceiver videoReceiver = peerConnection.getReceivers().get(0); FrameCryptor receiverCryptor = FrameCryptorFactory.createFrameCryptorForRtpReceiver( factory, videoReceiver, "participant-id", FrameCryptor.Algorithm.AES_GCM, keyProvider ); // Enable encryption senderCryptor.setEnabled(true); receiverCryptor.setEnabled(true); // Listen for cryptor state changes senderCryptor.setObserver(new FrameCryptor.Observer() { @Override public void onFrameCryptionStateChanged(String participantId, FrameCryptor.State state) { Log.d("E2EE", "Encryption state for " + participantId + ": " + state); } }); // Ratchet key for forward secrecy keyProvider.ratchetKey("participant-id", 0); ``` -------------------------------- ### Add Stripped-Down Prefixed WebRTC SDK Android Dependency Source: https://github.com/webrtc-sdk/android/blob/main/README.md This dependency provides a stripped-down variant of the prefixed library, optimized for size by removing software video codecs. ```gradle dependencies { implementation 'io.github.webrtc-sdk:android-prefixed-stripped:144.7559.01' } ``` -------------------------------- ### Configure Scalability Mode for SVC Codecs Source: https://context7.com/webrtc-sdk/android/llms.txt Adapt video streaming quality by configuring Scalable Video Coding (SVC) modes for AV1 and VP9 codecs. This involves modifying RtpParameters, specifically the encoding settings, to define spatial and temporal layers, max bitrate, and framerate. ```java import org.webrtc.RtpParameters; import org.webrtc.RtpSender; // Get the video sender RtpSender videoSender = peerConnection.getSenders().stream() .filter(s -> s.track() != null && s.track().kind().equals("video")) .findFirst() .orElse(null); // Configure encoding parameters with scalability mode RtpParameters parameters = videoSender.getParameters(); List encodings = parameters.encodings; if (!encodings.isEmpty()) { RtpParameters.Encoding encoding = encodings.get(0); // Set scalability mode for AV1 or VP9 // L3T3 = 3 spatial layers, 3 temporal layers encoding.scalabilityMode = "L3T3"; // Configure bitrate and resolution encoding.maxBitrateBps = 2500000; // 2.5 Mbps encoding.maxFramerate = 30; encoding.scaleResolutionDownBy = 1.0; videoSender.setParameters(parameters); } ``` -------------------------------- ### Send Data via Data Channel Source: https://context7.com/webrtc-sdk/android/llms.txt Send text or binary data over an established data channel. Ensure the data is wrapped in a ByteBuffer. For binary data, consider encryption. ```java // Send text message String message = "Hello, peer!"; ByteBuffer textBuffer = ByteBuffer.wrap(message.getBytes(StandardCharsets.UTF_8)); dataChannel.send(new DataChannel.Buffer(textBuffer, false)); // Send binary data with encryption byte[] encryptedData = encryptData(fileBytes); ByteBuffer binaryBuffer = ByteBuffer.wrap(encryptedData); dataChannel.send(new DataChannel.Buffer(binaryBuffer, true)); ``` -------------------------------- ### Retrieve RTP Statistics Source: https://context7.com/webrtc-sdk/android/llms.txt Obtain detailed RTP statistics for senders and receivers using the getStats method. This data is crucial for monitoring call quality, including bitrate, packet loss, and jitter. You can retrieve stats for individual RtpSenders/Receivers or the entire PeerConnection. ```java import org.webrtc.RTCStatsReport; import org.webrtc.RTCStatsCollectorCallback; // Get stats for specific sender RtpSender videoSender = peerConnection.getSenders().get(0); videoSender.getStats(new RTCStatsCollectorCallback() { @Override public void onStatsDelivered(RTCStatsReport report) { for (RTCStats stats : report.getStatsMap().values()) { if (stats.getType().equals("outbound-rtp")) { Map members = stats.getMembers(); long bytesSent = (long) members.get("bytesSent"); long packetsSent = (long) members.get("packetsSent"); Log.d("Stats", "Sent: " + bytesSent + " bytes, " + packetsSent + " packets"); } } } }); // Get stats for specific receiver RtpReceiver videoReceiver = peerConnection.getReceivers().get(0); videoReceiver.getStats(new RTCStatsCollectorCallback() { @Override public void onStatsDelivered(RTCStatsReport report) { for (RTCStats stats : report.getStatsMap().values()) { if (stats.getType().equals("inbound-rtp")) { Map members = stats.getMembers(); long bytesReceived = (long) members.get("bytesReceived"); long packetsReceived = (long) members.get("packetsReceived"); long packetsLost = (long) members.get("packetsLost"); double jitter = (double) members.get("jitter"); Log.d("Stats", "Received: " + bytesReceived + " bytes, lost: " + packetsLost); } } } }); // Get full peer connection stats peerConnection.getStats(new RTCStatsCollectorCallback() { @Override public void onStatsDelivered(RTCStatsReport report) { // Process all stats types } }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.