From 652c346821f63546aaaa1cf7b677781b87dd87b2 Mon Sep 17 00:00:00 2001 From: HUI Date: Thu, 22 Oct 2020 21:23:36 +0800 Subject: [PATCH] feat: add API example --- example/agora.config.json | 5 + example/android/app/build.gradle | 1 + example/package.json | 9 +- example/src/App.tsx | 99 +- .../src/examples/advanced/MultiChannel.tsx | 255 + example/src/examples/advanced/index.ts | 13 + .../src/examples/basic/JoinChannelAudio.tsx | 158 + .../src/examples/basic/JoinChannelVideo.tsx | 181 + example/src/examples/basic/StringUid.tsx | 137 + example/src/examples/basic/index.ts | 23 + example/yarn.lock | 4473 ----------------- 11 files changed, 861 insertions(+), 4493 deletions(-) create mode 100644 example/agora.config.json create mode 100644 example/src/examples/advanced/MultiChannel.tsx create mode 100644 example/src/examples/advanced/index.ts create mode 100644 example/src/examples/basic/JoinChannelAudio.tsx create mode 100644 example/src/examples/basic/JoinChannelVideo.tsx create mode 100644 example/src/examples/basic/StringUid.tsx create mode 100644 example/src/examples/basic/index.ts delete mode 100644 example/yarn.lock diff --git a/example/agora.config.json b/example/agora.config.json new file mode 100644 index 000000000..f95ac6dcc --- /dev/null +++ b/example/agora.config.json @@ -0,0 +1,5 @@ +{ + "appId": YOUR_APP_ID, + "channelId": "APIExample", + "token": YOUR_TOEKN +} diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index cdc98bab0..e03738298 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -132,6 +132,7 @@ android { targetSdkVersion rootProject.ext.targetSdkVersion versionCode 1 versionName "1.0" + multiDexEnabled true } splits { abi { diff --git a/example/package.json b/example/package.json index 44659bd31..45c1f5394 100644 --- a/example/package.json +++ b/example/package.json @@ -9,8 +9,15 @@ "start": "react-native start" }, "dependencies": { + "@react-native-community/masked-view": "^0.1.10", + "@react-navigation/native": "^5.7.1", + "@react-navigation/stack": "^5.7.1", "react": "16.11.0", - "react-native": "0.62.2" + "react-native": "0.62.2", + "react-native-gesture-handler": "^1.7.0", + "react-native-reanimated": "^1.10.1", + "react-native-safe-area-context": "^3.1.1", + "react-native-screens": "^2.9.0" }, "devDependencies": { "@babel/core": "^7.9.6", diff --git a/example/src/App.tsx b/example/src/App.tsx index 1e12c57c9..d252b2335 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -1,31 +1,92 @@ -import * as React from 'react'; -import { StyleSheet, View, Text } from 'react-native'; -import RtcEngine, { RtcChannel } from 'react-native-agora'; +/** + * Sample React Native App + * https://github.com/facebook/react-native + * + * Generated with the TypeScript template + * https://github.com/react-native-community/react-native-template-typescript + * + * @format + */ -export default function App() { - const [result, setResult] = React.useState(); +import React from 'react'; +import { + SafeAreaView, + StyleSheet, + SectionList, + Text, + View, + TouchableOpacity, +} from 'react-native'; - React.useEffect(() => { - RtcEngine.create('2b4b76e458cf439aa7cd313b9504f0a4').then(() => { - RtcChannel.create('xxx').then((channel: RtcChannel) => { - setResult(channel.channelId); - }); - }); - }, []); +import { NavigationContainer } from '@react-navigation/native'; +import { createStackNavigator } from '@react-navigation/stack'; +import Basic from './examples/basic'; +import Advanced from './examples/advanced'; + +const Stack = createStackNavigator(); + +const DATA = [Basic, Advanced]; + +const App = () => { + return ( + + + + {DATA.map((value) => + // @ts-ignore + value.data.map(({ name, component }) => ( + + )) + )} + + + ); +}; + +// @ts-ignore +const Home = ({ navigation }) => { return ( - - Result: {result} - + + item.name + index} + renderItem={({ item }) => } + renderSectionHeader={({ section: { title } }) => ( + {title} + )} + /> + ); -} +}; + +// @ts-ignore +const Item = ({ item, navigation }) => ( + + navigation.navigate(item.name)}> + {item.name} + + +); const styles = StyleSheet.create({ container: { flex: 1, - justifyContent: 'center', }, - text: { - textAlign: 'center', + header: { + padding: 10, + fontSize: 24, + color: 'white', + backgroundColor: 'grey', + }, + item: { + padding: 15, + }, + title: { + fontSize: 24, + color: 'black', }, }); + +export default App; diff --git a/example/src/examples/advanced/MultiChannel.tsx b/example/src/examples/advanced/MultiChannel.tsx new file mode 100644 index 000000000..0e6b06efc --- /dev/null +++ b/example/src/examples/advanced/MultiChannel.tsx @@ -0,0 +1,255 @@ +import React, { Component } from 'react'; +import { + View, + PermissionsAndroid, + StyleSheet, + Button, + Platform, +} from 'react-native'; + +import RtcEngine, { + RtcChannel, + RtcLocalView, + RtcRemoteView, + ChannelProfile, + ClientRole, + ChannelMediaOptions, +} from 'react-native-agora'; + +const config = require('../../../agora.config.json'); + +interface State { + renderChannelId: string; + isJoined0: boolean; + isJoined1: boolean; + remoteUid0: number | undefined; + remoteUid1: number | undefined; +} + +const channelId0 = 'channel0'; +const channelId1 = 'channel1'; + +export default class MultiChannel extends Component<{}, State, any> { + _engine: RtcEngine | undefined; + _channel0: RtcChannel | undefined; + _channel1: RtcChannel | undefined; + + constructor(props: {}) { + super(props); + this.state = { + renderChannelId: channelId0, + isJoined0: false, + isJoined1: false, + remoteUid0: undefined, + remoteUid1: undefined, + }; + } + + UNSAFE_componentWillMount() { + this._initEngine(); + } + + componentWillUnmount() { + this._engine?.destroy(); + } + + _initEngine = async () => { + this._engine = await RtcEngine.create(config.appId); + + await this._engine.enableVideo(); + await this._engine.startPreview(); + await this._engine.setChannelProfile(ChannelProfile.LiveBroadcasting); + }; + + _joinChannel0 = async () => { + if (Platform.OS === 'android') { + await PermissionsAndroid.requestMultiple([ + PermissionsAndroid.PERMISSIONS.RECORD_AUDIO, + PermissionsAndroid.PERMISSIONS.CAMERA, + ]); + } + + this._channel0 = await RtcChannel.create(channelId0); + this._addListener(this._channel0, channelId0); + + await this._channel0.setClientRole(ClientRole.Broadcaster); + await this._channel0.joinChannel( + null, + null, + 0, + new ChannelMediaOptions(true, true) + ); + }; + + _joinChannel1 = async () => { + if (Platform.OS === 'android') { + await PermissionsAndroid.requestMultiple([ + PermissionsAndroid.PERMISSIONS.RECORD_AUDIO, + PermissionsAndroid.PERMISSIONS.CAMERA, + ]); + } + + this._channel1 = await RtcChannel.create(channelId1); + this._addListener(this._channel1, channelId1); + + await this._channel1.setClientRole(ClientRole.Broadcaster); + await this._channel1.joinChannel( + null, + null, + 0, + new ChannelMediaOptions(true, true) + ); + }; + + _addListener = (channel: RtcChannel, channelId: string) => { + channel.addListener('JoinChannelSuccess', (uid, elapsed) => { + console.info('JoinChannelSuccess', channelId, uid, elapsed); + if (channelId === channelId0) { + this.setState({ isJoined0: true }); + } else if (channelId === channelId1) { + this.setState({ isJoined1: true }); + } + }); + channel.addListener('UserJoined', (uid, elapsed) => { + console.info('UserJoined', channelId, uid, elapsed); + if (channelId === channelId0) { + this.setState({ remoteUid0: uid }); + } else if (channelId === channelId1) { + this.setState({ remoteUid1: uid }); + } + }); + channel.addListener('UserOffline', (uid, reason) => { + console.info('UserOffline', channelId, uid, reason); + if (channelId === channelId0) { + if (uid === this.state.remoteUid0) { + this.setState({ remoteUid0: undefined }); + } + } else if (channelId === channelId1) { + if (uid === this.state.remoteUid1) { + this.setState({ remoteUid1: undefined }); + } + } + }); + channel.addListener('LeaveChannel', (stats) => { + console.info('LeaveChannel', channelId, stats); + if (channelId === channelId0) { + this.setState({ isJoined0: false, remoteUid0: undefined }); + } else if (channelId === channelId1) { + this.setState({ isJoined1: false, remoteUid1: undefined }); + } + }); + }; + + _publishChannel0 = async () => { + await this._channel1?.unpublish(); + await this._channel0?.publish(); + }; + + _publishChannel1 = async () => { + await this._channel0?.unpublish(); + await this._channel1?.publish(); + }; + + _leaveChannel0 = async () => { + await this._channel0?.leaveChannel(); + }; + + _leaveChannel1 = async () => { + await this._channel1?.leaveChannel(); + }; + + render() { + const { isJoined0, isJoined1 } = this.state; + return ( + + +