├── .babelrc ├── .buckconfig ├── .flowconfig ├── .gitattributes ├── .gitignore ├── .vscode └── launch.json ├── .watchmanconfig ├── App.js ├── LICENSE.md ├── README.md ├── README.zh.md ├── __tests__ └── App.js ├── android ├── .gitignore ├── .idea │ ├── caches │ │ └── build_file_checksums.ser │ ├── codeStyles │ │ └── Project.xml │ └── runConfigurations.xml ├── app │ ├── BUCK │ ├── build.gradle │ ├── libs │ │ └── PLACEHOLDER │ ├── proguard-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── com │ │ │ └── rnapi │ │ │ ├── AgoraModule.java │ │ │ ├── AgoraPackage.java │ │ │ ├── ConvertUtils.java │ │ │ ├── MainActivity.java │ │ │ ├── MainApplication.java │ │ │ └── SurfaceViewManager.java │ │ ├── jniLibs │ │ ├── arm64-v8a │ │ │ └── PLACEHOLDER │ │ └── armeabi-v7a │ │ │ └── PLACEHOLDER │ │ └── res │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ └── values │ │ ├── strings.xml │ │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── keystores │ ├── BUCK │ └── debug.keystore.properties └── settings.gradle ├── apis.md ├── app.json ├── components ├── AgoraRendererView.js └── AgoraRtcEngineModule.js ├── contributions.md ├── guide.md ├── index.js ├── ios ├── Agora-SDK-For-React-Native-API │ ├── AgoraEnum.h │ ├── AgoraEnum.m │ ├── AgoraNotify.h │ ├── AgoraRtcEngineModule+EnumConvert.h │ ├── AgoraRtcEngineModule+EnumConvert.m │ ├── AgoraRtcEngineModule.h │ ├── AgoraRtcEngineModule.m │ ├── AgoraViewManager.h │ ├── AgoraViewManager.m │ ├── AgroaEnumConvert.h │ └── AgroaEnumConvert.m ├── RNapi-tvOS │ └── Info.plist ├── RNapi-tvOSTests │ └── Info.plist ├── RNapi.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ ├── RNapi-tvOS.xcscheme │ │ └── RNapi.xcscheme └── RNapi │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ └── LaunchScreen.xib │ ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json │ ├── Info.plist │ └── main.m ├── package-lock.json └── package.json /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["react-native"] 3 | } 4 | -------------------------------------------------------------------------------- /.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | ; We fork some components by platform 3 | .*/*[.]android.js 4 | 5 | ; Ignore "BUCK" generated dirs 6 | /\.buckd/ 7 | 8 | ; Ignore unexpected extra "@providesModule" 9 | .*/node_modules/.*/node_modules/fbjs/.* 10 | 11 | ; Ignore duplicate module providers 12 | ; For RN Apps installed via npm, "Libraries" folder is inside 13 | ; "node_modules/react-native" but in the source repo it is in the root 14 | .*/Libraries/react-native/React.js 15 | 16 | ; Ignore polyfills 17 | .*/Libraries/polyfills/.* 18 | 19 | ; Ignore metro 20 | .*/node_modules/metro/.* 21 | 22 | [include] 23 | 24 | [libs] 25 | node_modules/react-native/Libraries/react-native/react-native-interface.js 26 | node_modules/react-native/flow/ 27 | node_modules/react-native/flow-github/ 28 | 29 | [options] 30 | emoji=true 31 | 32 | module.system=haste 33 | 34 | munge_underscores=true 35 | 36 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' 37 | 38 | module.file_ext=.js 39 | module.file_ext=.jsx 40 | module.file_ext=.json 41 | module.file_ext=.native.js 42 | 43 | suppress_type=$FlowIssue 44 | suppress_type=$FlowFixMe 45 | suppress_type=$FlowFixMeProps 46 | suppress_type=$FlowFixMeState 47 | 48 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) 49 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ 50 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy 51 | suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError 52 | 53 | [version] 54 | ^0.65.0 55 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/reactnative 3 | 4 | ### ReactNative ### 5 | # React Native Stack Base 6 | ### ReactNative.Xcode Stack ### 7 | # Xcode 8 | # 9 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 10 | 11 | ## Build generated 12 | build/ 13 | DerivedData/ 14 | 15 | ## Various settings 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | xcuserdata/ 25 | 26 | ## Other 27 | *.moved-aside 28 | *.xccheckout 29 | *.xcscmblueprint 30 | 31 | ### ReactNative.Buck Stack ### 32 | buck-out/ 33 | .buckconfig.local 34 | .buckd/ 35 | .buckversion 36 | .fakebuckversion 37 | 38 | ### ReactNative.Linux Stack ### 39 | *~ 40 | 41 | # temporary files which can be created if a process still has a handle open of a deleted file 42 | .fuse_hidden* 43 | 44 | # KDE directory preferences 45 | .directory 46 | 47 | # Linux trash folder which might appear on any partition or disk 48 | .Trash-* 49 | 50 | # .nfs files are created when an open file is removed but is still being accessed 51 | .nfs* 52 | 53 | ### ReactNative.Node Stack ### 54 | # Logs 55 | logs 56 | *.log 57 | npm-debug.log* 58 | yarn-debug.log* 59 | yarn-error.log* 60 | 61 | # Runtime data 62 | pids 63 | *.pid 64 | *.seed 65 | *.pid.lock 66 | 67 | # Directory for instrumented libs generated by jscoverage/JSCover 68 | lib-cov 69 | 70 | # Coverage directory used by tools like istanbul 71 | coverage 72 | 73 | # nyc test coverage 74 | .nyc_output 75 | 76 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 77 | .grunt 78 | 79 | # Bower dependency directory (https://bower.io/) 80 | bower_components 81 | 82 | # node-waf configuration 83 | .lock-wscript 84 | 85 | # Compiled binary addons (http://nodejs.org/api/addons.html) 86 | build/Release 87 | 88 | # Dependency directories 89 | node_modules/ 90 | jspm_packages/ 91 | 92 | # Typescript v1 declaration files 93 | typings/ 94 | 95 | # Optional npm cache directory 96 | .npm 97 | 98 | # Optional eslint cache 99 | .eslintcache 100 | 101 | # Optional REPL history 102 | .node_repl_history 103 | 104 | # Output of 'npm pack' 105 | *.tgz 106 | 107 | # Yarn Integrity file 108 | .yarn-integrity 109 | 110 | # dotenv environment variables file 111 | .env 112 | 113 | 114 | ### ReactNative.Android Stack ### 115 | # Built application files 116 | *.apk 117 | *.ap_ 118 | 119 | # Files for the ART/Dalvik VM 120 | *.dex 121 | 122 | # Java class files 123 | *.class 124 | 125 | # Generated files 126 | bin/ 127 | gen/ 128 | out/ 129 | 130 | # Gradle files 131 | .gradle/ 132 | 133 | # Local configuration file (sdk path, etc) 134 | local.properties 135 | 136 | # Proguard folder generated by Eclipse 137 | proguard/ 138 | 139 | # Log Files 140 | 141 | # Android Studio Navigation editor temp files 142 | .navigation/ 143 | 144 | # Android Studio captures folder 145 | captures/ 146 | 147 | # Intellij 148 | *.iml 149 | .idea/workspace.xml 150 | .idea/tasks.xml 151 | .idea/gradle.xml 152 | .idea/dictionaries 153 | .idea/libraries 154 | 155 | # External native build folder generated in Android Studio 2.2 and later 156 | .externalNativeBuild 157 | 158 | # Freeline 159 | freeline.py 160 | freeline/ 161 | freeline_project_description.json 162 | 163 | ### ReactNative.macOS Stack ### 164 | *.DS_Store 165 | .AppleDouble 166 | .LSOverride 167 | 168 | # Icon must end with two \r 169 | Icon 170 | 171 | 172 | # Thumbnails 173 | ._* 174 | 175 | # Files that might appear in the root of a volume 176 | .DocumentRevisions-V100 177 | .fseventsd 178 | .Spotlight-V100 179 | .TemporaryItems 180 | .Trashes 181 | .VolumeIcon.icns 182 | .com.apple.timemachine.donotpresent 183 | 184 | # Directories potentially created on remote AFP share 185 | .AppleDB 186 | .AppleDesktop 187 | Network Trash Folder 188 | Temporary Items 189 | .apdisk 190 | 191 | ### ReactNative.Gradle Stack ### 192 | .gradle 193 | **/build/ 194 | 195 | # Ignore Gradle GUI config 196 | gradle-app.setting 197 | 198 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 199 | !gradle-wrapper.jar 200 | 201 | # Cache of project 202 | .gradletasknamecache 203 | 204 | # # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 205 | # gradle/wrapper/gradle-wrapper.properties 206 | 207 | 208 | # End of https://www.gitignore.io/api/reactnative -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Debug Android", 9 | "program": "${workspaceRoot}/.vscode/launchReactNative.js", 10 | "type": "reactnative", 11 | "request": "launch", 12 | "platform": "android", 13 | "sourceMaps": true, 14 | "outDir": "${workspaceRoot}/.vscode/.react" 15 | }, 16 | { 17 | "name": "Debug iOS", 18 | "program": "${workspaceRoot}/.vscode/launchReactNative.js", 19 | "type": "reactnative", 20 | "request": "launch", 21 | "platform": "ios", 22 | "sourceMaps": true, 23 | "outDir": "${workspaceRoot}/.vscode/.react" 24 | }, 25 | { 26 | "name": "Attach to packager", 27 | "program": "${workspaceRoot}/.vscode/launchReactNative.js", 28 | "type": "reactnative", 29 | "request": "attach", 30 | "sourceMaps": true, 31 | "outDir": "${workspaceRoot}/.vscode/.react" 32 | }, 33 | { 34 | "name": "Debug in Exponent", 35 | "program": "${workspaceRoot}/.vscode/launchReactNative.js", 36 | "type": "reactnative", 37 | "request": "launch", 38 | "platform": "exponent", 39 | "sourceMaps": true, 40 | "outDir": "${workspaceRoot}/.vscode/.react" 41 | } 42 | ] 43 | } -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /App.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * @flow 5 | */ 6 | 7 | import React, { Component } from 'react'; 8 | import { 9 | Platform, 10 | Button, 11 | StyleSheet, 12 | Text, 13 | View, 14 | Image, 15 | findNodeHandle, 16 | NativeEventEmitter, 17 | NativeModules, 18 | UIManager, 19 | DeviceEventEmitter 20 | } from 'react-native'; 21 | import AgoraRtcEngine from './components/AgoraRtcEngineModule' 22 | import AgoraRendererView from './components/AgoraRendererView' 23 | 24 | const agoraKitEmitter = new NativeEventEmitter(AgoraRtcEngine); 25 | var isSpeakerPhone = false; 26 | //provide this url if you want rtmp relevant features 27 | var cdn_url = "YOUR_CDN_URL" 28 | 29 | export default class App extends Component { 30 | state = { 31 | localStream: null, 32 | remoteStreams: [] 33 | } 34 | viewRegistry = {} 35 | listeners = [] 36 | 37 | componentDidMount() { 38 | this.registerCallbacks(); 39 | AgoraRtcEngine.createEngine("YOUR_APP_ID"); 40 | 41 | AgoraRtcEngine.enableVideo(); 42 | AgoraRtcEngine.enableAudio(); 43 | AgoraRtcEngine.setVideoProfileDetail(360, 640, 15, 300); 44 | } 45 | 46 | componentDidUpdate() { 47 | //the view registry could be changed after render update 48 | //resetup remote views here 49 | let remoteStreams = this.state.remoteStreams || []; 50 | for (let i = 0; i < remoteStreams.length; i++) { 51 | let stream = remoteStreams[i]; 52 | let { uid } = stream; 53 | AgoraRtcEngine.setRemoteVideoView(this.viewRegistry[uid], uid, AgoraRtcEngine.AgoraVideoRenderModeFit) 54 | } 55 | } 56 | 57 | // Agora Action 58 | _joinChannel() { 59 | AgoraRtcEngine.setLocalVideoView(this.viewRegistry["local"], AgoraRtcEngine.AgoraVideoRenderModeFit); 60 | AgoraRtcEngine.setChannelProfile(1); 61 | AgoraRtcEngine.setClientRole(1); 62 | AgoraRtcEngine.setVideoProfile(AgoraRtcEngine.AgoraVideoProfileDEFAULT, true); 63 | AgoraRtcEngine.startPreview(); 64 | AgoraRtcEngine.joinChannel(null, "rnchannel01", "React Native for Agora RTC SDK", 0); 65 | } 66 | 67 | _leaveChannel() { 68 | AgoraRtcEngine.stopPreview(); 69 | AgoraRtcEngine.leaveChannel(); 70 | } 71 | 72 | _switchCamera() { 73 | AgoraRtcEngine.switchCamera(); 74 | } 75 | 76 | _switchAudio() { 77 | AgoraRtcEngine.setEnableSpeakerphone(isSpeakerPhone); 78 | isSpeakerPhone = !isSpeakerPhone; 79 | } 80 | 81 | _startPublish() { 82 | AgoraRtcEngine.addPublishStreamUrl(cdn_url, false) 83 | } 84 | 85 | _stopPublish() { 86 | AgoraRtcEngine.removePublishStreamUrl(cdn_url) 87 | } 88 | 89 | render() { 90 | let remoteViews = this.state.remoteStreams.map(stream => { 91 | let { uid } = stream; 92 | return ( 93 | this.viewRegistry[uid] = component} 95 | key={uid} 96 | style={{ width: 360, height: 240 }} 97 | /> 98 | ) 99 | }) 100 | return ( 101 | 102 | 103 | this.viewRegistry["local"] = component} 105 | style={{ width: 360, height: 240 }} 106 | /> 107 | {remoteViews} 108 | 109 |