Live video on the AT Protocol
at eli/sync-changes 152 lines 4.8 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 12// https://github.com/react-native-webrtc/react-native-webrtc/blob/19ca31d4b77d149a659ee037fae54861a2d90a73/Documentation/AndroidInstallation.md#set-audio-category-output-to-media 13// look, i'm as upset about this as you are 14const androidApplicationReplacements = [ 15 { 16 from: "class MainApplication : Application(), ReactApplication {", 17 to: ` 18import com.oney.WebRTCModule.WebRTCModuleOptions 19import android.media.AudioAttributes 20import org.webrtc.audio.JavaAudioDeviceModule 21 22class MainApplication : Application(), ReactApplication {`, 23 }, 24 { 25 from: "override fun onCreate() {", 26 to: ` 27 override fun onCreate() { 28 // append this before WebRTCModule initializes 29 val options = WebRTCModuleOptions.getInstance() 30 val audioAttributes = AudioAttributes.Builder() 31 .setUsage(AudioAttributes.USAGE_MEDIA) 32 .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) 33 .build() 34 options.audioDeviceModule = JavaAudioDeviceModule.builder(this) 35 .setAudioAttributes(audioAttributes) 36 .createAudioDeviceModule() 37`, 38 }, 39]; 40 41export const withWorkingAndroidWebRTCAudio: ConfigPlugin = (configOuter) => { 42 return withMainApplication(configOuter, (config) => { 43 let stringContents: string = config.modResults.contents; 44 45 for (const { from, to } of androidApplicationReplacements) { 46 stringContents = stringContents.replace(from, to); 47 } 48 49 config.modResults.contents = stringContents; 50 51 return config; 52 }); 53}; 54 55const iosDelegateReplacements = [ 56 { 57 from: "#import <React/RCTLinkingManager.h>", 58 to: (config) => ` 59#import <React/RCTLinkingManager.h> 60#import <WebRTC/WebRTC.h> 61#import "CaptureController.h" 62#import "CapturerEventsDelegate.h" 63#import "DataChannelWrapper.h" 64#import "RCTConvert+WebRTC.h" 65#import "RTCMediaStreamTrack+React.h" 66#import "RTCVideoViewManager.h" 67#import "ScreenCaptureController.h" 68#import "ScreenCapturePickerViewManager.h" 69#import "ScreenCapturer.h" 70#import "SerializeUtils.h" 71#import "SocketConnection.h" 72#import "TrackCapturerEventsEmitter.h" 73#import "VideoCaptureController.h" 74#import "WebRTCModule+RTCDataChannel.h" 75#import "WebRTCModule+RTCMediaStream.h" 76#import "WebRTCModule+RTCPeerConnection.h" 77#import "WebRTCModule+VideoTrackAdapter.h" 78#import "WebRTCModule.h" 79#import "WebRTCModuleOptions.h" 80#import "ExpoModulesCore-Swift.h" 81#import "${config.name.replaceAll(" ", "")}-Swift.h" 82`, 83 }, 84 { 85 from: " self.initialProps = @{};", 86 to: () => ` 87 self.initialProps = @{}; 88 ////RTC PATCH//// 89 RTCAudioSessionConfiguration* config = [RTCAudioSessionConfiguration webRTCConfiguration]; 90 91 AVAudioSession * session = [AVAudioSession sharedInstance]; 92 // Set audio to use phone speaker instead of headset speaker 93 [session setCategory:AVAudioSessionCategoryPlayAndRecord 94 withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionAllowBluetooth 95 error:nil]; 96 [session setActive:YES error:nil]; 97 98 id<RTCAudioDevice> device; 99 device = [[AUAudioUnitRTCAudioDevice alloc] init]; 100 101 WebRTCModuleOptions *options = [WebRTCModuleOptions sharedInstance]; 102 options.loggingSeverity = RTCLoggingSeverityWarning; 103 options.audioDevice = device; 104 ////END RTC PATCH//// 105 `, 106 }, 107]; 108 109const withWorkingIOSWebRTCAudio: ConfigPlugin = (config) => { 110 const files = [ 111 "AUAudioUnitRTCAudioDevice.swift", 112 "AudioSessionHandler.swift", 113 "SimpleAudioConverter.swift", 114 "Utils.swift", 115 ]; 116 117 // modify the app delegate to make use of the CustomRTCAudioDevice 118 config = withAppDelegate(config, (config) => { 119 let stringContents: string = config.modResults.contents; 120 121 for (const { from, to } of iosDelegateReplacements) { 122 stringContents = stringContents.replace(from, to(config)); 123 } 124 125 config.modResults.contents = stringContents; 126 127 return config; 128 }); 129 130 // add the CustomRTCAudioDevice files to the xcode project 131 config = withXcodeProject(config, (config) => { 132 const rtc = require.resolve("rtcaudiodevice"); 133 for (const file of files) { 134 IOSConfig.XcodeUtils.addBuildSourceFileToGroup({ 135 filepath: resolve(rtc, "..", "CustomRTCAudioDevice", file), 136 groupName: config.name, 137 project: config.modResults, 138 }); 139 } 140 141 return config; 142 }); 143 144 return config; 145}; 146 147export default function withStreamplaceReactNativeWebRTC(config: ExpoConfig) { 148 config = RNWebRTCPlugin(config); 149 config = withWorkingAndroidWebRTCAudio(config); 150 config = withWorkingIOSWebRTCAudio(config); 151 return config; 152}