Live video on the AT Protocol
79
fork

Configure Feed

Select the types of activity you want to include in your feed.

at eli/leaky-error-cases 206 lines 6.3 kB view raw
1import RNWebRTCPlugin from "@config-plugins/react-native-webrtc"; 2import { ExpoConfig } from "expo/config"; 3import { 4 ConfigPlugin, 5 IOSConfig, 6 withAppDelegate, 7 withMainApplication, 8 withXcodeProject, 9} from "expo/config-plugins"; 10import { resolve } from "path"; 11 12const buildError = (message: string) => { 13 if (process.env.SP_SKIP_CODEMODE_ERRORS !== "true") { 14 throw new Error(`@streamplace/config-native-webrtc ${message}`); 15 } else { 16 console.error( 17 `@streamplace/config-native-webrtc ${message}, skipping because SP_SKIP_CODEMODE_ERRORS=true`, 18 ); 19 } 20}; 21 22// https://github.com/react-native-webrtc/react-native-webrtc/blob/19ca31d4b77d149a659ee037fae54861a2d90a73/Documentation/AndroidInstallation.md#set-audio-category-output-to-media 23// look, i'm as upset about this as you are 24const androidApplicationReplacements = [ 25 { 26 from: "class MainApplication : Application(), ReactApplication {", 27 to: ` 28import com.oney.WebRTCModule.WebRTCModuleOptions 29import android.media.AudioAttributes 30import org.webrtc.audio.JavaAudioDeviceModule 31 32class MainApplication : Application(), ReactApplication {`, 33 }, 34 { 35 from: "override fun onCreate() {", 36 to: ` 37 override fun onCreate() { 38 // append this before WebRTCModule initializes 39 val options = WebRTCModuleOptions.getInstance() 40 val audioAttributes = AudioAttributes.Builder() 41 .setUsage(AudioAttributes.USAGE_MEDIA) 42 .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) 43 .build() 44 options.audioDeviceModule = JavaAudioDeviceModule.builder(this) 45 .setAudioAttributes(audioAttributes) 46 .createAudioDeviceModule() 47`, 48 }, 49]; 50 51export const withWorkingAndroidWebRTCAudio: ConfigPlugin = (configOuter) => { 52 return withMainApplication(configOuter, (config) => { 53 let stringContents: string = config.modResults.contents; 54 55 for (const { from, to } of androidApplicationReplacements) { 56 stringContents = stringContents.replace(from, to); 57 } 58 if (stringContents === config.modResults.contents) { 59 buildError("android codemod failed to apply"); 60 } 61 62 config.modResults.contents = stringContents; 63 64 return config; 65 }); 66}; 67 68const iosDelegateReplacements = [ 69 // Objective-C Version 70 { 71 from: "#import <React/RCTLinkingManager.h>", 72 to: (config) => ` 73#import <React/RCTLinkingManager.h> 74#import <WebRTC/WebRTC.h> 75#import "CaptureController.h" 76#import "CapturerEventsDelegate.h" 77#import "DataChannelWrapper.h" 78#import "RCTConvert+WebRTC.h" 79#import "RTCMediaStreamTrack+React.h" 80#import "RTCVideoViewManager.h" 81#import "ScreenCaptureController.h" 82#import "ScreenCapturePickerViewManager.h" 83#import "ScreenCapturer.h" 84#import "SerializeUtils.h" 85#import "SocketConnection.h" 86#import "TrackCapturerEventsEmitter.h" 87#import "VideoCaptureController.h" 88#import "WebRTCModule+RTCDataChannel.h" 89#import "WebRTCModule+RTCMediaStream.h" 90#import "WebRTCModule+RTCPeerConnection.h" 91#import "WebRTCModule+VideoTrackAdapter.h" 92#import "WebRTCModule.h" 93#import "WebRTCModuleOptions.h" 94#import "ExpoModulesCore-Swift.h" 95#import "${config.name.replaceAll(" ", "")}-Swift.h" 96`, 97 }, 98 { 99 from: " self.initialProps = @{};", 100 to: () => ` 101 self.initialProps = @{}; 102 ////RTC PATCH//// 103 RTCAudioSessionConfiguration* config = [RTCAudioSessionConfiguration webRTCConfiguration]; 104 105 AVAudioSession * session = [AVAudioSession sharedInstance]; 106 // Set audio to use phone speaker instead of headset speaker 107 [session setCategory:AVAudioSessionCategoryPlayAndRecord 108 withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionAllowBluetooth 109 error:nil]; 110 [session setActive:YES error:nil]; 111 112 id<RTCAudioDevice> device; 113 device = [[AUAudioUnitRTCAudioDevice alloc] init]; 114 115 WebRTCModuleOptions *options = [WebRTCModuleOptions sharedInstance]; 116 options.loggingSeverity = RTCLoggingSeverityWarning; 117 options.audioDevice = device; 118 ////END RTC PATCH//// 119 `, 120 }, 121 // Swift Version 122 { 123 from: " let delegate = ReactNativeDelegate()", 124 to: () => ` 125 // WebRTC Configuration 126 let config = RTCAudioSessionConfiguration.webRTC() 127 128 let session = AVAudioSession.sharedInstance() 129 do { 130 try session.setCategory(.playAndRecord, 131 options: [.defaultToSpeaker, .allowBluetooth]) 132 try session.setActive(true) 133 } catch { 134 print("Failed to configure audio session: \(error)") 135 } 136 137 let device = AUAudioUnitRTCAudioDevice() 138 139 let options = WebRTCModuleOptions.sharedInstance() 140 options.loggingSeverity = .warning 141 options.audioDevice = device 142 // End WebRTC Configuration 143 144 let delegate = ReactNativeDelegate() 145 `, 146 }, 147 { 148 from: "import ReactAppDependencyProvider", 149 to: () => ` 150import ReactAppDependencyProvider 151import WebRTC 152import react_native_webrtc 153import AVFoundation 154 `, 155 }, 156]; 157 158const withWorkingIOSWebRTCAudio: ConfigPlugin = (config) => { 159 const files = [ 160 "AUAudioUnitRTCAudioDevice.swift", 161 "AudioSessionHandler.swift", 162 "SimpleAudioConverter.swift", 163 "Utils.swift", 164 ]; 165 166 let called = false; 167 // modify the app delegate to make use of the CustomRTCAudioDevice 168 config = withAppDelegate(config, (config) => { 169 let stringContents: string = config.modResults.contents; 170 171 for (const { from, to } of iosDelegateReplacements) { 172 stringContents = stringContents.replace(from, to(config)); 173 } 174 if (stringContents === config.modResults.contents) { 175 buildError("ios codemod failed to change anything, aborting"); 176 } 177 178 config.modResults.contents = stringContents; 179 called = true; 180 181 return config; 182 }); 183 184 // add the CustomRTCAudioDevice files to the xcode project 185 config = withXcodeProject(config, (config) => { 186 const rtc = require.resolve("rtcaudiodevice"); 187 for (const file of files) { 188 IOSConfig.XcodeUtils.addBuildSourceFileToGroup({ 189 filepath: resolve(rtc, "..", "CustomRTCAudioDevice", file), 190 groupName: config.name, 191 project: config.modResults, 192 }); 193 } 194 195 return config; 196 }); 197 198 return config; 199}; 200 201export default function withStreamplaceReactNativeWebRTC(config: ExpoConfig) { 202 config = RNWebRTCPlugin(config); 203 config = withWorkingAndroidWebRTCAudio(config); 204 config = withWorkingIOSWebRTCAudio(config); 205 return config; 206}