From eb8042a543562939b1ec0725916c5288604f94fe Mon Sep 17 00:00:00 2001 From: CSantos <4a.santos@gmail.com> Date: Fri, 17 May 2019 16:44:23 +0200 Subject: [PATCH] Added React Native tutorial --- openvidu-react-native/.buckconfig | 6 + openvidu-react-native/.flowconfig | 69 + openvidu-react-native/.gitattributes | 1 + openvidu-react-native/.gitignore | 56 + openvidu-react-native/.watchmanconfig | 1 + openvidu-react-native/App.js | 373 ++++ openvidu-react-native/__tests__/App-test.js | 14 + openvidu-react-native/android/app/BUCK | 55 + .../android/app/build.gradle | 152 ++ .../android/app/build_defs.bzl | 19 + .../android/app/proguard-rules.pro | 17 + .../android/app/src/debug/AndroidManifest.xml | 8 + .../android/app/src/main/AndroidManifest.xml | 35 + .../openvidu_react_native/MainActivity.java | 15 + .../MainApplication.java | 47 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3056 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 5024 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2096 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 2858 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4569 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 7098 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 6464 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 10676 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 9250 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 15523 bytes .../app/src/main/res/values/strings.xml | 3 + .../app/src/main/res/values/styles.xml | 8 + openvidu-react-native/android/build.gradle | 33 + .../android/gradle.properties | 18 + .../gradle/wrapper/gradle-wrapper.properties | 5 + openvidu-react-native/android/gradlew | 172 ++ openvidu-react-native/android/gradlew.bat | 84 + openvidu-react-native/android/keystores/BUCK | 8 + .../keystores/debug.keystore.properties | 4 + openvidu-react-native/android/settings.gradle | 4 + openvidu-react-native/app.json | 4 + openvidu-react-native/babel.config.js | 3 + openvidu-react-native/index.js | 9 + .../ios/openvidu_react_native-tvOS/Info.plist | 54 + .../Info.plist | 24 + .../project.pbxproj | 1502 +++++++++++++++++ .../openvidu_react_native-tvOS.xcscheme | 129 ++ .../xcschemes/openvidu_react_native.xcscheme | 129 ++ .../ios/openvidu_react_native/AppDelegate.h | 15 + .../ios/openvidu_react_native/AppDelegate.m | 42 + .../Base.lproj/LaunchScreen.xib | 42 + .../AppIcon.appiconset/Contents.json | 38 + .../Images.xcassets/Contents.json | 6 + .../ios/openvidu_react_native/Info.plist | 60 + .../ios/openvidu_react_native/main.m | 16 + .../ios/openvidu_react_nativeTests/Info.plist | 24 + .../openvidu_react_nativeTests.m | 68 + openvidu-react-native/metro.config.js | 17 + openvidu-react-native/package.json | 25 + 54 files changed, 3414 insertions(+) create mode 100644 openvidu-react-native/.buckconfig create mode 100644 openvidu-react-native/.flowconfig create mode 100644 openvidu-react-native/.gitattributes create mode 100644 openvidu-react-native/.gitignore create mode 100644 openvidu-react-native/.watchmanconfig create mode 100644 openvidu-react-native/App.js create mode 100644 openvidu-react-native/__tests__/App-test.js create mode 100644 openvidu-react-native/android/app/BUCK create mode 100644 openvidu-react-native/android/app/build.gradle create mode 100644 openvidu-react-native/android/app/build_defs.bzl create mode 100644 openvidu-react-native/android/app/proguard-rules.pro create mode 100644 openvidu-react-native/android/app/src/debug/AndroidManifest.xml create mode 100644 openvidu-react-native/android/app/src/main/AndroidManifest.xml create mode 100644 openvidu-react-native/android/app/src/main/java/com/openvidu_react_native/MainActivity.java create mode 100644 openvidu-react-native/android/app/src/main/java/com/openvidu_react_native/MainApplication.java create mode 100644 openvidu-react-native/android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 openvidu-react-native/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png create mode 100644 openvidu-react-native/android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 openvidu-react-native/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png create mode 100644 openvidu-react-native/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 openvidu-react-native/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png create mode 100644 openvidu-react-native/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 openvidu-react-native/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 openvidu-react-native/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 openvidu-react-native/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 openvidu-react-native/android/app/src/main/res/values/strings.xml create mode 100644 openvidu-react-native/android/app/src/main/res/values/styles.xml create mode 100644 openvidu-react-native/android/build.gradle create mode 100644 openvidu-react-native/android/gradle.properties create mode 100644 openvidu-react-native/android/gradle/wrapper/gradle-wrapper.properties create mode 100755 openvidu-react-native/android/gradlew create mode 100644 openvidu-react-native/android/gradlew.bat create mode 100644 openvidu-react-native/android/keystores/BUCK create mode 100644 openvidu-react-native/android/keystores/debug.keystore.properties create mode 100644 openvidu-react-native/android/settings.gradle create mode 100644 openvidu-react-native/app.json create mode 100644 openvidu-react-native/babel.config.js create mode 100644 openvidu-react-native/index.js create mode 100644 openvidu-react-native/ios/openvidu_react_native-tvOS/Info.plist create mode 100644 openvidu-react-native/ios/openvidu_react_native-tvOSTests/Info.plist create mode 100644 openvidu-react-native/ios/openvidu_react_native.xcodeproj/project.pbxproj create mode 100644 openvidu-react-native/ios/openvidu_react_native.xcodeproj/xcshareddata/xcschemes/openvidu_react_native-tvOS.xcscheme create mode 100644 openvidu-react-native/ios/openvidu_react_native.xcodeproj/xcshareddata/xcschemes/openvidu_react_native.xcscheme create mode 100644 openvidu-react-native/ios/openvidu_react_native/AppDelegate.h create mode 100644 openvidu-react-native/ios/openvidu_react_native/AppDelegate.m create mode 100644 openvidu-react-native/ios/openvidu_react_native/Base.lproj/LaunchScreen.xib create mode 100644 openvidu-react-native/ios/openvidu_react_native/Images.xcassets/AppIcon.appiconset/Contents.json create mode 100644 openvidu-react-native/ios/openvidu_react_native/Images.xcassets/Contents.json create mode 100644 openvidu-react-native/ios/openvidu_react_native/Info.plist create mode 100644 openvidu-react-native/ios/openvidu_react_native/main.m create mode 100644 openvidu-react-native/ios/openvidu_react_nativeTests/Info.plist create mode 100644 openvidu-react-native/ios/openvidu_react_nativeTests/openvidu_react_nativeTests.m create mode 100644 openvidu-react-native/metro.config.js create mode 100644 openvidu-react-native/package.json diff --git a/openvidu-react-native/.buckconfig b/openvidu-react-native/.buckconfig new file mode 100644 index 00000000..934256cb --- /dev/null +++ b/openvidu-react-native/.buckconfig @@ -0,0 +1,6 @@ + +[android] + target = Google Inc.:Google APIs:23 + +[maven_repositories] + central = https://repo1.maven.org/maven2 diff --git a/openvidu-react-native/.flowconfig b/openvidu-react-native/.flowconfig new file mode 100644 index 00000000..47d80d95 --- /dev/null +++ b/openvidu-react-native/.flowconfig @@ -0,0 +1,69 @@ +[ignore] +; We fork some components by platform +.*/*[.]android.js + +; Ignore "BUCK" generated dirs +/\.buckd/ + +; Ignore unexpected extra "@providesModule" +.*/node_modules/.*/node_modules/fbjs/.* + +; Ignore duplicate module providers +; For RN Apps installed via npm, "Libraries" folder is inside +; "node_modules/react-native" but in the source repo it is in the root +.*/Libraries/react-native/React.js + +; Ignore polyfills +.*/Libraries/polyfills/.* + +; Ignore metro +.*/node_modules/metro/.* + +[include] + +[libs] +node_modules/react-native/Libraries/react-native/react-native-interface.js +node_modules/react-native/flow/ + +[options] +emoji=true + +esproposal.optional_chaining=enable +esproposal.nullish_coalescing=enable + +module.system=haste +module.system.haste.use_name_reducers=true +# get basename +module.system.haste.name_reducers='^.*/\([a-zA-Z0-9$_.-]+\.js\(\.flow\)?\)$' -> '\1' +# strip .js or .js.flow suffix +module.system.haste.name_reducers='^\(.*\)\.js\(\.flow\)?$' -> '\1' +# strip .ios suffix +module.system.haste.name_reducers='^\(.*\)\.ios$' -> '\1' +module.system.haste.name_reducers='^\(.*\)\.android$' -> '\1' +module.system.haste.name_reducers='^\(.*\)\.native$' -> '\1' +module.system.haste.paths.blacklist=.*/__tests__/.* +module.system.haste.paths.blacklist=.*/__mocks__/.* +module.system.haste.paths.blacklist=/node_modules/react-native/Libraries/Animated/src/polyfills/.* +module.system.haste.paths.whitelist=/node_modules/react-native/Libraries/.* + +munge_underscores=true + +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' + +module.file_ext=.js +module.file_ext=.jsx +module.file_ext=.json +module.file_ext=.native.js + +suppress_type=$FlowIssue +suppress_type=$FlowFixMe +suppress_type=$FlowFixMeProps +suppress_type=$FlowFixMeState + +suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) +suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ +suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy +suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError + +[version] +^0.92.0 diff --git a/openvidu-react-native/.gitattributes b/openvidu-react-native/.gitattributes new file mode 100644 index 00000000..d42ff183 --- /dev/null +++ b/openvidu-react-native/.gitattributes @@ -0,0 +1 @@ +*.pbxproj -text diff --git a/openvidu-react-native/.gitignore b/openvidu-react-native/.gitignore new file mode 100644 index 00000000..5d647565 --- /dev/null +++ b/openvidu-react-native/.gitignore @@ -0,0 +1,56 @@ +# OSX +# +.DS_Store + +# Xcode +# +build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +*.xccheckout +*.moved-aside +DerivedData +*.hmap +*.ipa +*.xcuserstate +project.xcworkspace + +# Android/IntelliJ +# +build/ +.idea +.gradle +local.properties +*.iml + +# node.js +# +node_modules/ +npm-debug.log +yarn-error.log + +# BUCK +buck-out/ +\.buckd/ +*.keystore + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/ + +*/fastlane/report.xml +*/fastlane/Preview.html +*/fastlane/screenshots + +# Bundle artifact +*.jsbundle diff --git a/openvidu-react-native/.watchmanconfig b/openvidu-react-native/.watchmanconfig new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/openvidu-react-native/.watchmanconfig @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/openvidu-react-native/App.js b/openvidu-react-native/App.js new file mode 100644 index 00000000..26f7ffb0 --- /dev/null +++ b/openvidu-react-native/App.js @@ -0,0 +1,373 @@ +/** + * Sample React Native App + * https://github.com/facebook/react-native + * + * @format + * @flow + */ + +import React, { Component } from 'react'; +import { ScrollView, Button, Alert, Linking, StyleSheet, Text, View, PermissionsAndroid } from 'react-native'; + +import { OpenVidu } from 'openvidu-browser'; +import { RTCView } from './node_modules/openvidu-browser/node_modules/react-native-webrtc'; + +const OPENVIDU_SERVER_URL = 'https://demos.openvidu.io:4443'; +const OPENVIDU_SERVER_SECRET = 'MY_SECRET'; + +type Props = {}; +export default class App extends Component { + constructor(props) { + super(props); + + this.state = { + mySessionId: '5552200', + myUserName: 'Participant' + Math.floor(Math.random() * 100), + session: undefined, + mainStreamManager: undefined, + publisher: undefined, + subscribers: [], + role: 'PUBLISHER', + }; + } + + componentDidMount() { + this.requestCameraPermission(); + this.joinSession(); + } + + componentWillUnmount() { + this.leaveSession(); + } + + async requestCameraPermission() { + try { + const camera = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.CAMERA, { + title: 'Camera Permission', + message: 'OpenVidu needs access to your camera', + buttonNeutral: 'Ask Me Later', + buttonNegative: 'Cancel', + buttonPositive: 'OK', + }); + const audio = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.RECORD_AUDIO, { + title: 'Aduio Permission', + message: 'OpenVidu needs access to your microphone', + buttonNeutral: 'Ask Me Later', + buttonNegative: 'Cancel', + buttonPositive: 'OK', + }); + const storage = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE, { + title: 'STORAGE', + message: 'OpenVidu needs access to your storage ', + buttonNeutral: 'Ask Me Later', + buttonNegative: 'Cancel', + buttonPositive: 'OK', + }); + if (camera === PermissionsAndroid.RESULTS.GRANTED) { + console.log('You can use the camera'); + } else { + console.log('Camera permission denied'); + } + if (audio === PermissionsAndroid.RESULTS.GRANTED) { + console.log('You can use the audio'); + } else { + console.log('audio permission denied'); + } + if (storage === PermissionsAndroid.RESULTS.GRANTED) { + console.log('You can use the storage'); + } else { + console.log('storage permission denied'); + } + } catch (err) { + console.warn(err); + } + } + + joinSession() { + // --- 1) Get an OpenVidu object --- + + this.OV = new OpenVidu(); + + // --- 2) Init a session --- + + this.setState( + { + session: this.OV.initSession(), + }, + () => { + var mySession = this.state.session; + // --- 3) Specify the actions when events take place in the session --- + + // On every new Stream received... + mySession.on('streamCreated', (event) => { + // Subscribe to the Stream to receive it. Second parameter is undefined + // so OpenVidu doesn't create an HTML video by its own + const subscriber = mySession.subscribe(event.stream, undefined); + console.log('streamCreated EVENT', event.stream); + var subscribers = this.state.subscribers; + subscribers.push(subscriber); + // Update the state with the new subscribers + this.setState({ + subscribers: subscribers, + }); + }); + + // On every Stream destroyed... + mySession.on('streamDestroyed', (event) => { + // Remove the stream from 'subscribers' array + this.deleteSubscriber(event.stream.streamManager); + }); + + // --- 4) Connect to the session with a valid user token --- + // 'getToken' method is simulating what your server-side should do. + // 'token' parameter should be retrieved and returned by your own backend + this.getToken() + .then((token) => { + // First param is the token got from OpenVidu Server. Second param can be retrieved by every user on event + // 'streamCreated' (property Stream.connection.data), and will be appended to DOM as the user's nickname + mySession + .connect(token, { clientData: this.state.myUserName }) + .then(() => { + console.log('SESSION CONECTADA'); + // --- 5) Get your own camera stream --- + if (this.state.role !== 'SUBSCRIBER') { + // Init a publisher passing undefined as targetElement (we don't want OpenVidu to insert a video + // element: we will manage it on our own) and with the desired properties + let publisher = this.OV.initPublisher(undefined, { + audioSource: undefined, // The source of audio. If undefined default microphone + videoSource: undefined, // The source of video. If undefined default webcam + publishAudio: true, // Whether you want to start publishing with your audio unmuted or not + publishVideo: true, // Whether you want to start publishing with your video enabled or not + resolution: '640x480', // The resolution of your video + frameRate: 30, // The frame rate of your video + insertMode: 'APPEND', // How the video is inserted in the target element 'video-container' + mirror: false, // Whether to mirror your local video or not + }); + + console.log('init publisher OK ', publisher); + + // --- 6) Publish your stream --- + + // Set the main video in the page to display our webcam and store our Publisher + this.setState({ + mainStreamManager: publisher, + publisher: publisher, + }); + mySession.publish(publisher); + } + + }) + .catch((error) => { + console.log('There was an error connecting to the session:', error.code, error.message); + }); + }) + .catch((error) => console.log('Error', error)); + }, + ); + } + + deleteSubscriber(streamManager) { + setTimeout(() => { + let subscribers = this.state.subscribers; + const index = subscribers.indexOf(streamManager, 0); + if (index > -1) { + subscribers.splice(index, 1); + this.setState({ + subscribers: subscribers, + }); + } + }); + } + + leaveSession() { + // --- 7) Leave the session by calling 'disconnect' method over the Session object --- + + const mySession = this.state.session; + + if (mySession) { + mySession.disconnect(); + } + + // Empty all properties... + this.OV = null; + this.setState({ + session: undefined, + subscribers: [], + mySessionId: '5552200', + myUserName: 'Participant' + Math.floor(Math.random() * 100), + mainStreamManager: undefined, + publisher: undefined, + }); + } + + addVideoElement(video) { + this.state.mainStreamManager.addVideoElement(video); + } + + toggleCamera(){ + this.state.mainStreamManager.stream.getMediaStream().getVideoTracks()[0]._switchCamera(); + } + + render() { + + return ( + + {this.state.mainStreamManager ? ( + + Local Stream + { + if (!!rtcVideo) { + this.addVideoElement(rtcVideo); + } + }} + style={styles.selfView} + /> +