From d0781e0cddd91b65b15c651d9f024308840d009e Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Tue, 22 Sep 2026 11:17:07 +0800 Subject: [PATCH 1/4] chore: bump libwebrtc to m150 and add enableSctpSnap. --- android/build.gradle | 2 +- .../java/com/oney/WebRTCModule/WebRTCModule.java | 8 ++++++++ ios/RCTWebRTC/RCTConvert+WebRTC.m | 15 +++++++++++---- livekit-react-native-webrtc.podspec | 2 +- src/RTCPeerConnection.ts | 1 + 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 372b74205..cef9e3d1d 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -31,6 +31,6 @@ android { dependencies { implementation "com.facebook.react:react-android:+" - api 'io.github.webrtc-sdk:android-prefixed:144.7559.15' + api 'io.github.webrtc-sdk:android-prefixed:150.7871.01' implementation "androidx.core:core:1.7.0" } diff --git a/android/src/main/java/com/oney/WebRTCModule/WebRTCModule.java b/android/src/main/java/com/oney/WebRTCModule/WebRTCModule.java index c2d992ecf..04b46b539 100644 --- a/android/src/main/java/com/oney/WebRTCModule/WebRTCModule.java +++ b/android/src/main/java/com/oney/WebRTCModule/WebRTCModule.java @@ -413,6 +413,14 @@ private PeerConnection.RTCConfiguration parseRTCConfiguration(ReadableMap map) { conf.presumeWritableWhenFullyRelayed = v; } + // enableSctpSnap (private api) + // Maps to an immutable field of the native configuration, so it must hold the same + // value at peer connection creation and on every setConfiguration call. + if (map.hasKey("enableSctpSnap") && map.getType("enableSctpSnap") == ReadableType.Boolean) { + final boolean v = map.getBoolean("enableSctpSnap"); + conf.enableSctpSnap = v; + } + return conf; } diff --git a/ios/RCTWebRTC/RCTConvert+WebRTC.m b/ios/RCTWebRTC/RCTConvert+WebRTC.m index 25ee138c2..f248e771c 100644 --- a/ios/RCTWebRTC/RCTConvert+WebRTC.m +++ b/ios/RCTWebRTC/RCTConvert+WebRTC.m @@ -91,10 +91,13 @@ + (nonnull LKRTCConfiguration *)LKRTCConfiguration:(id)json { config.enableImplicitRollback = YES; // Enable GCM ciphers. - LKRTCCryptoOptions *cryptoOptions = [[LKRTCCryptoOptions alloc] initWithSrtpEnableGcmCryptoSuites:YES - srtpEnableAes128Sha1_32CryptoCipher:NO - srtpEnableEncryptedRtpHeaderExtensions:NO - sframeRequireFrameEncryption:NO]; + LKRTCCryptoOptions *cryptoOptions = + [[LKRTCCryptoOptions alloc] initWithSrtpEnableGcmCryptoSuites:YES + srtpPreferGcmCryptoSuites:NO + srtpEnableAes128Sha1_32CryptoCipher:NO + srtpEnableAes128Sha1_80CryptoCipher:YES + srtpEnableEncryptedRtpHeaderExtensions:NO + sframeRequireFrameEncryption:NO]; config.cryptoOptions = cryptoOptions; if (!json) { @@ -122,6 +125,10 @@ + (nonnull LKRTCConfiguration *)LKRTCConfiguration:(id)json { } } + if (json[@"enableSctpSnap"] != nil && [json[@"enableSctpSnap"] isKindOfClass:[NSNumber class]]) { + config.enableSctpSnap = [RCTConvert BOOL:json[@"enableSctpSnap"]]; + } + if (json[@"iceBackupCandidatePairPingInterval"] != nil && [json[@"iceBackupCandidatePairPingInterval"] isKindOfClass:[NSNumber class]]) { config.iceBackupCandidatePairPingInterval = [RCTConvert int:json[@"iceBackupCandidatePairPingInterval"]]; diff --git a/livekit-react-native-webrtc.podspec b/livekit-react-native-webrtc.podspec index 45301f518..a727f5430 100644 --- a/livekit-react-native-webrtc.podspec +++ b/livekit-react-native-webrtc.podspec @@ -19,7 +19,7 @@ Pod::Spec.new do |s| s.libraries = 'c', 'sqlite3', 'stdc++' s.framework = 'AudioToolbox','AVFoundation', 'CoreAudio', 'CoreGraphics', 'CoreVideo', 'GLKit', 'VideoToolbox' s.dependency 'React-Core' - s.dependency 'LiveKitWebRTC', '= 144.7559.15' + s.dependency 'LiveKitWebRTC', '= 150.7871.02' # Swift/Objective-C compatibility s.pod_target_xcconfig = { diff --git a/src/RTCPeerConnection.ts b/src/RTCPeerConnection.ts index 955887748..bf28e0fc6 100644 --- a/src/RTCPeerConnection.ts +++ b/src/RTCPeerConnection.ts @@ -55,6 +55,7 @@ type RTCIceServer = { type RTCConfiguration = { bundlePolicy?: 'balanced' | 'max-compat' | 'max-bundle', + enableSctpSnap?: boolean, iceCandidatePoolSize?: number, iceServers?: RTCIceServer[], iceTransportPolicy?: 'all' | 'relay', From 269fd9c4b41141f623425d31791b3dc74ade8f55 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Tue, 22 Sep 2026 11:21:43 +0800 Subject: [PATCH 2/4] clang-format. --- ios/RCTWebRTC/RCTConvert+WebRTC.m | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/ios/RCTWebRTC/RCTConvert+WebRTC.m b/ios/RCTWebRTC/RCTConvert+WebRTC.m index f248e771c..07ea91aa5 100644 --- a/ios/RCTWebRTC/RCTConvert+WebRTC.m +++ b/ios/RCTWebRTC/RCTConvert+WebRTC.m @@ -91,13 +91,12 @@ + (nonnull LKRTCConfiguration *)LKRTCConfiguration:(id)json { config.enableImplicitRollback = YES; // Enable GCM ciphers. - LKRTCCryptoOptions *cryptoOptions = - [[LKRTCCryptoOptions alloc] initWithSrtpEnableGcmCryptoSuites:YES - srtpPreferGcmCryptoSuites:NO - srtpEnableAes128Sha1_32CryptoCipher:NO - srtpEnableAes128Sha1_80CryptoCipher:YES - srtpEnableEncryptedRtpHeaderExtensions:NO - sframeRequireFrameEncryption:NO]; + LKRTCCryptoOptions *cryptoOptions = [[LKRTCCryptoOptions alloc] initWithSrtpEnableGcmCryptoSuites:YES + srtpPreferGcmCryptoSuites:NO + srtpEnableAes128Sha1_32CryptoCipher:NO + srtpEnableAes128Sha1_80CryptoCipher:YES + srtpEnableEncryptedRtpHeaderExtensions:NO + sframeRequireFrameEncryption:NO]; config.cryptoOptions = cryptoOptions; if (!json) { From 735daf9c47546b05413b07a55473d96c3a4d613a Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Tue, 22 Sep 2026 11:25:17 +0800 Subject: [PATCH 3/4] ci(ios): add the livekit/podspecs source for LiveKitWebRTC 150.7871.x LiveKitWebRTC 150.7871.x has not been pushed to the CocoaPods trunk CDN yet (trunk still tops out at 144.7559.15), so `pod install` in the example app cannot resolve the dependency and iOS CI fails with: None of your spec sources contain a spec satisfying the dependency: `LiveKitWebRTC (= 150.7871.02)`. Add the livekit/podspecs repository as an additional source, which is the fallback already documented in Documentation/iOSInstallation.md. This can be dropped again once the pod reaches the trunk CDN. Co-Authored-By: Claude Opus 5 (1M context) --- examples/GumTestApp/ios/Podfile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/examples/GumTestApp/ios/Podfile b/examples/GumTestApp/ios/Podfile index 3ee160926..d102a3cf0 100644 --- a/examples/GumTestApp/ios/Podfile +++ b/examples/GumTestApp/ios/Podfile @@ -24,6 +24,11 @@ require_relative '../node_modules/@react-native-community/cli-platform-ios/nativ platform :ios, 13.0 prepare_react_native_project! +# LiveKitWebRTC 150.7871.x has not reached the CocoaPods trunk CDN yet, so the +# livekit/podspecs repository is needed as an additional source. +source 'https://cdn.cocoapods.org/' +source 'https://github.com/livekit/podspecs.git' + # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set. # because `react-native-flipper` depends on (FlipperKit,...) that will be excluded # From fc3525a8c5f775dbaf6367922d0a857f4896efa3 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Tue, 22 Sep 2026 11:26:55 +0800 Subject: [PATCH 4/4] update. --- .../GumTestApp/ios/GumTestApp.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/GumTestApp/ios/GumTestApp.xcodeproj/project.pbxproj b/examples/GumTestApp/ios/GumTestApp.xcodeproj/project.pbxproj index 90418cb29..40dc5ca4e 100644 --- a/examples/GumTestApp/ios/GumTestApp.xcodeproj/project.pbxproj +++ b/examples/GumTestApp/ios/GumTestApp.xcodeproj/project.pbxproj @@ -400,12 +400,12 @@ ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-GumTestApp/Pods-GumTestApp-frameworks.sh", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/WebRTC-SDK/WebRTC.framework/WebRTC", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/LiveKitWebRTC/LiveKitWebRTC.framework/LiveKitWebRTC", "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/WebRTC.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/LiveKitWebRTC.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework", ); runOnlyForDeploymentPostprocessing = 0; @@ -460,12 +460,12 @@ ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-GumTestApp-GumTestAppTests/Pods-GumTestApp-GumTestAppTests-frameworks.sh", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/WebRTC-SDK/WebRTC.framework/WebRTC", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/LiveKitWebRTC/LiveKitWebRTC.framework/LiveKitWebRTC", "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/WebRTC.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/LiveKitWebRTC.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework", ); runOnlyForDeploymentPostprocessing = 0;