Live video on the AT Protocol

@streamplace/config-react-native-webrtc: init (#110)

* build: refactor streamplace-react-native-webrtc into its own file

* add @streamplace/react-native-webrtc

* react-native-webrtc: fix header imports

* config-react-native-webrtc: rename

* private: false

* yarn.lock

* README

* postinstall

authored by

Eli Mallon and committed by
GitHub
47b2b652 b2e96aa1

+221 -126
+2 -124
js/app/app.config.ts
··· 1 1 import { 2 2 ConfigPlugin, 3 - IOSConfig, 4 - withAppDelegate, 5 3 withEntitlementsPlist, 6 - withMainApplication, 7 4 withXcodeProject, 8 5 } from "expo/config-plugins"; 9 - import path from "path"; 6 + import streamplaceReactNativeWebRTC from "../config-react-native-webrtc"; 10 7 export const withNotificationsIOS: ConfigPlugin = (config) => { 11 8 config = withEntitlementsPlist(config, (config) => { 12 9 config.modResults["aps-environment"] = "production"; ··· 45 42 return config; 46 43 }; 47 44 48 - // https://github.com/react-native-webrtc/react-native-webrtc/blob/19ca31d4b77d149a659ee037fae54861a2d90a73/Documentation/AndroidInstallation.md#set-audio-category-output-to-media 49 - // look, i'm as upset about this as you are 50 - const androidApplicationReplacements = [ 51 - { 52 - from: "class MainApplication : Application(), ReactApplication {", 53 - to: ` 54 - import com.oney.WebRTCModule.WebRTCModuleOptions 55 - import android.media.AudioAttributes 56 - import org.webrtc.audio.JavaAudioDeviceModule 57 - 58 - class MainApplication : Application(), ReactApplication {`, 59 - }, 60 - { 61 - from: "override fun onCreate() {", 62 - to: ` 63 - override fun onCreate() { 64 - // append this before WebRTCModule initializes 65 - val options = WebRTCModuleOptions.getInstance() 66 - val audioAttributes = AudioAttributes.Builder() 67 - .setUsage(AudioAttributes.USAGE_MEDIA) 68 - .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) 69 - .build() 70 - options.audioDeviceModule = JavaAudioDeviceModule.builder(this) 71 - .setAudioAttributes(audioAttributes) 72 - .createAudioDeviceModule() 73 - `, 74 - }, 75 - ]; 76 - 77 - export const withWorkingAndroidWebRTCAudio: ConfigPlugin = (configOuter) => { 78 - return withMainApplication(configOuter, (config) => { 79 - let stringContents: string = config.modResults.contents; 80 - 81 - for (const { from, to } of androidApplicationReplacements) { 82 - stringContents = stringContents.replace(from, to); 83 - } 84 - 85 - config.modResults.contents = stringContents; 86 - 87 - return config; 88 - }); 89 - }; 90 - 91 - const iosDelegateReplacements = [ 92 - { 93 - from: "#import <React/RCTLinkingManager.h>", 94 - to: (config) => ` 95 - #import <React/RCTLinkingManager.h> 96 - #import <WebRTC/WebRTC.h> 97 - #import <react-native-webrtc-umbrella.h> 98 - #import "ExpoModulesCore-Swift.h" 99 - #import "${config.name}-Swift.h" 100 - `, 101 - }, 102 - { 103 - from: " self.initialProps = @{};", 104 - to: () => ` 105 - self.initialProps = @{}; 106 - ////RTC PATCH//// 107 - RTCAudioSessionConfiguration* config = [RTCAudioSessionConfiguration webRTCConfiguration]; 108 - 109 - AVAudioSession * session = [AVAudioSession sharedInstance]; 110 - // Set audio to use phone speaker instead of headset speaker 111 - [session setCategory:AVAudioSessionCategoryPlayAndRecord 112 - withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionAllowBluetooth 113 - error:nil]; 114 - [session setActive:YES error:nil]; 115 - 116 - id<RTCAudioDevice> device; 117 - device = [[AUAudioUnitRTCAudioDevice alloc] init]; 118 - 119 - WebRTCModuleOptions *options = [WebRTCModuleOptions sharedInstance]; 120 - options.loggingSeverity = RTCLoggingSeverityWarning; 121 - options.audioDevice = device; 122 - ////END RTC PATCH//// 123 - `, 124 - }, 125 - ]; 126 - 127 - const withWorkingIOSWebRTCAudio: ConfigPlugin = (config) => { 128 - const files = [ 129 - "AUAudioUnitRTCAudioDevice.swift", 130 - "AudioSessionHandler.swift", 131 - "SimpleAudioConverter.swift", 132 - "Utils.swift", 133 - ]; 134 - 135 - // modify the app delegate to make use of the CustomRTCAudioDevice 136 - config = withAppDelegate(config, (config) => { 137 - let stringContents: string = config.modResults.contents; 138 - 139 - for (const { from, to } of iosDelegateReplacements) { 140 - stringContents = stringContents.replace(from, to(config)); 141 - } 142 - 143 - config.modResults.contents = stringContents; 144 - 145 - return config; 146 - }); 147 - 148 - // add the CustomRTCAudioDevice files to the xcode project 149 - config = withXcodeProject(config, (config) => { 150 - const rtc = require.resolve("rtcaudiodevice"); 151 - for (const file of files) { 152 - IOSConfig.XcodeUtils.addBuildSourceFileToGroup({ 153 - filepath: path.resolve(rtc, "..", "CustomRTCAudioDevice", file), 154 - groupName: config.name, 155 - project: config.modResults, 156 - }); 157 - } 158 - 159 - return config; 160 - }); 161 - 162 - return config; 163 - }; 164 - 165 45 // turn a semver string into a always-increasing integer for google 166 46 export const versionCode = (verStr: string) => { 167 47 const [major, minor, patch] = verStr.split(".").map((x) => parseInt(x)); ··· 231 111 favicon: "./assets/images/favicon.png", 232 112 }, 233 113 plugins: [ 234 - withWorkingIOSWebRTCAudio, 235 - withWorkingAndroidWebRTCAudio, 236 - "@config-plugins/react-native-webrtc", 114 + streamplaceReactNativeWebRTC, 237 115 ["expo-sqlite", { useSQLCipher: true }], 238 116 "expo-file-system", 239 117 [
+2
js/config-react-native-webrtc/.gitignore
··· 1 + dist 2 + tsconfig.tsbuildinfo
+17
js/config-react-native-webrtc/README.md
··· 1 + # @streamplace/config-react-native-webrtc 2 + 3 + This npm module contains code to install the Streamplace-optimized version of 4 + react-native-webrtc. 5 + 6 + To use: 7 + `[yarn/pnpm/npm] add @streamplace/config-react-native-webrtc react-native-webrtc` 8 + 9 + And add to the `plugins` array in your `app.config.ts`: 10 + 11 + ```tsx 12 + export default { 13 + expo: { 14 + plugins: ["@streamplace/config-react-native-webrtc"], 15 + }, 16 + }; 17 + ```
+24
js/config-react-native-webrtc/package.json
··· 1 + { 2 + "name": "@streamplace/config-react-native-webrtc", 3 + "version": "0.0.1", 4 + "description": "react-native-webrtc config mod with some changes to make it useful for streamplace", 5 + "packageManager": "yarn@4.3.0", 6 + "scripts": { 7 + "postinstall": "tsc -p tsconfig.json" 8 + }, 9 + "dependencies": { 10 + "@config-plugins/react-native-webrtc": "10.0.0", 11 + "react-native-webrtc": "124.0.4", 12 + "rtcaudiodevice": "git+https://github.com/streamplace/RTCAudioDevice.git#7b4659fe845545d366623cbc813936987144b76f" 13 + }, 14 + "devDependencies": { 15 + "typescript": "~5.3.3" 16 + }, 17 + "main": "./dist/config-react-native-webrtc.js", 18 + "src": "./src/config-react-native-webrtc.ts", 19 + "types": "./dist/config-react-native-webrtc.d.ts", 20 + "files": [ 21 + "dist", 22 + "src" 23 + ] 24 + }
+152
js/config-react-native-webrtc/src/config-react-native-webrtc.ts
··· 1 + import RNWebRTCPlugin from "@config-plugins/react-native-webrtc"; 2 + import { ExpoConfig } from "expo/config"; 3 + import { 4 + ConfigPlugin, 5 + IOSConfig, 6 + withAppDelegate, 7 + withMainApplication, 8 + withXcodeProject, 9 + } from "expo/config-plugins"; 10 + import { 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 14 + const androidApplicationReplacements = [ 15 + { 16 + from: "class MainApplication : Application(), ReactApplication {", 17 + to: ` 18 + import com.oney.WebRTCModule.WebRTCModuleOptions 19 + import android.media.AudioAttributes 20 + import org.webrtc.audio.JavaAudioDeviceModule 21 + 22 + class 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 + 41 + export 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 + 55 + const 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 + 109 + const 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 + 147 + export default function withStreamplaceReactNativeWebRTC(config: ExpoConfig) { 148 + config = RNWebRTCPlugin(config); 149 + config = withWorkingAndroidWebRTCAudio(config); 150 + config = withWorkingIOSWebRTCAudio(config); 151 + return config; 152 + }
+11
js/config-react-native-webrtc/tsconfig.json
··· 1 + { 2 + "extends": "../app/tsconfig.base", 3 + "compilerOptions": { 4 + "strict": true, 5 + "outDir": "./dist", 6 + "rootDir": "./src", 7 + "declaration": true, 8 + "module": "CommonJS" 9 + }, 10 + "include": ["src/**/*.ts"] 11 + }
+13 -2
yarn.lock
··· 2935 2935 languageName: node 2936 2936 linkType: hard 2937 2937 2938 - "@config-plugins/react-native-webrtc@npm:^10.0.0": 2938 + "@config-plugins/react-native-webrtc@npm:10.0.0, @config-plugins/react-native-webrtc@npm:^10.0.0": 2939 2939 version: 10.0.0 2940 2940 resolution: "@config-plugins/react-native-webrtc@npm:10.0.0" 2941 2941 peerDependencies: ··· 7910 7910 checksum: 10/fb5469e390ee2515d926633e3e179038894ac4f5e8c8cd2c2fc912022e34a051112eab0fe80c4dbc6e59129679844182562a036abff89444e5c4a05dd42ed329 7911 7911 languageName: node 7912 7912 linkType: hard 7913 + 7914 + "@streamplace/config-react-native-webrtc@workspace:js/config-react-native-webrtc": 7915 + version: 0.0.0-use.local 7916 + resolution: "@streamplace/config-react-native-webrtc@workspace:js/config-react-native-webrtc" 7917 + dependencies: 7918 + "@config-plugins/react-native-webrtc": "npm:10.0.0" 7919 + react-native-webrtc: "npm:124.0.4" 7920 + rtcaudiodevice: "git+https://github.com/streamplace/RTCAudioDevice.git#7b4659fe845545d366623cbc813936987144b76f" 7921 + typescript: "npm:~5.3.3" 7922 + languageName: unknown 7923 + linkType: soft 7913 7924 7914 7925 "@swc/core-darwin-arm64@npm:1.6.13": 7915 7926 version: 1.6.13 ··· 23939 23950 languageName: node 23940 23951 linkType: hard 23941 23952 23942 - "react-native-webrtc@npm:^124.0.4": 23953 + "react-native-webrtc@npm:124.0.4, react-native-webrtc@npm:^124.0.4": 23943 23954 version: 124.0.4 23944 23955 resolution: "react-native-webrtc@npm:124.0.4" 23945 23956 dependencies: