Skip to content

Commit

Permalink
feat: example support render multi remote-videos
Browse files Browse the repository at this point in the history
  • Loading branch information
LichKing-2234 committed Dec 18, 2020
1 parent 8661116 commit 3ff1430
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 68 deletions.
92 changes: 57 additions & 35 deletions example/src/examples/advanced/MultiChannel.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import React, { Component } from 'react';
import {
View,
PermissionsAndroid,
StyleSheet,
Button,
PermissionsAndroid,
Platform,
ScrollView,
StyleSheet,
View,
} from 'react-native';

import RtcEngine, {
ChannelMediaOptions,
ChannelProfile,
ClientRole,
RtcChannel,
RtcLocalView,
RtcRemoteView,
ChannelProfile,
ClientRole,
ChannelMediaOptions,
VideoRemoteState,
} from 'react-native-agora';

const config = require('../../../agora.config.json');
Expand All @@ -22,8 +24,8 @@ interface State {
renderChannelId: string;
isJoined0: boolean;
isJoined1: boolean;
remoteUid0: number | undefined;
remoteUid1: number | undefined;
remoteUid0: number[];
remoteUid1: number[];
}

const channelId0 = 'channel0';
Expand All @@ -40,8 +42,8 @@ export default class MultiChannel extends Component<{}, State, any> {
renderChannelId: channelId0,
isJoined0: false,
isJoined1: false,
remoteUid0: undefined,
remoteUid1: undefined,
remoteUid0: [],
remoteUid1: [],
};
}

Expand All @@ -59,6 +61,7 @@ export default class MultiChannel extends Component<{}, State, any> {
await this._engine.enableVideo();
await this._engine.startPreview();
await this._engine.setChannelProfile(ChannelProfile.LiveBroadcasting);
await this._engine.setClientRole(ClientRole.Broadcaster);
};

_joinChannel0 = async () => {
Expand Down Expand Up @@ -113,32 +116,45 @@ export default class MultiChannel extends Component<{}, State, any> {
});
rtcChannel.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 });
}
});
rtcChannel.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 });
}
}
});
rtcChannel.addListener('LeaveChannel', (stats) => {
console.info('LeaveChannel', channelId, stats);
if (channelId === channelId0) {
this.setState({ isJoined0: false, remoteUid0: undefined });
this.setState({ isJoined0: false, remoteUid0: [] });
} else if (channelId === channelId1) {
this.setState({ isJoined1: false, remoteUid1: undefined });
this.setState({ isJoined1: false, remoteUid1: [] });
}
});
rtcChannel.addListener(
'RemoteVideoStateChanged',
(uid, state, reason, elapsed) => {
console.info('RemoteVideoStateChanged', uid, state, reason, elapsed);
if (state === VideoRemoteState.Starting) {
if (channelId === channelId0) {
this.setState({ remoteUid0: [...this.state.remoteUid0, uid] });
} else if (channelId === channelId1) {
this.setState({ remoteUid1: [...this.state.remoteUid1, uid] });
}
} else if (state === VideoRemoteState.Stopped) {
if (channelId === channelId0) {
this.setState({
remoteUid0: this.state.remoteUid0.filter(
(value) => value !== uid
),
});
} else if (channelId === channelId1) {
this.setState({
remoteUid1: this.state.remoteUid1.filter(
(value) => value !== uid
),
});
}
}
}
);
};

_publishChannel0 = async () => {
Expand Down Expand Up @@ -202,7 +218,7 @@ export default class MultiChannel extends Component<{}, State, any> {

_renderVideo = () => {
const { renderChannelId, remoteUid0, remoteUid1 } = this.state;
let remoteUid: number | undefined;
let remoteUid: number[] | undefined;
if (renderChannelId === channelId0) {
remoteUid = remoteUid0;
} else if (renderChannelId === channelId1) {
Expand All @@ -215,11 +231,15 @@ export default class MultiChannel extends Component<{}, State, any> {
channelId={renderChannelId}
/>
{remoteUid !== undefined && (
<RtcRemoteView.SurfaceView
style={styles.remote}
channelId={renderChannelId}
uid={remoteUid}
/>
<ScrollView horizontal={true} style={styles.remoteContainer}>
{remoteUid.map((value) => (
<RtcRemoteView.SurfaceView
style={styles.remote}
channelId={renderChannelId}
uid={value}
/>
))}
</ScrollView>
)}
</View>
);
Expand All @@ -241,11 +261,13 @@ const styles = StyleSheet.create({
local: {
flex: 1,
},
remote: {
width: 200,
height: 200,
remoteContainer: {
position: 'absolute',
left: 0,
top: 0,
},
remote: {
width: 120,
height: 120,
},
});
68 changes: 35 additions & 33 deletions example/src/examples/basic/JoinChannelVideo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
Button,
PermissionsAndroid,
Platform,
ScrollView,
StyleSheet,
TextInput,
TouchableOpacity,
Expand All @@ -21,7 +22,7 @@ const config = require('../../../agora.config.json');
interface State {
channelId: string;
isJoined: boolean;
remoteUid: number | undefined;
remoteUid: number[];
switchCamera: boolean;
switchRender: boolean;
}
Expand All @@ -34,7 +35,7 @@ export default class JoinChannelAudio extends Component<{}, State, any> {
this.state = {
channelId: config.channelId,
isJoined: false,
remoteUid: undefined,
remoteUid: [],
switchCamera: true,
switchRender: true,
};
Expand Down Expand Up @@ -65,17 +66,17 @@ export default class JoinChannelAudio extends Component<{}, State, any> {
});
this._engine?.addListener('UserJoined', (uid, elapsed) => {
console.info('UserJoined', uid, elapsed);
this.setState({ remoteUid: uid });
this.setState({ remoteUid: [...this.state.remoteUid, uid] });
});
this._engine?.addListener('UserOffline', (uid, reason) => {
console.info('UserOffline', uid, reason);
if (uid === this.state.remoteUid) {
this.setState({ remoteUid: undefined });
}
this.setState({
remoteUid: this.state.remoteUid.filter((value) => value !== uid),
});
});
this._engine?.addListener('LeaveChannel', (stats) => {
console.info('LeaveChannel', stats);
this.setState({ isJoined: false, remoteUid: undefined });
this.setState({ isJoined: false, remoteUid: [] });
});
};

Expand Down Expand Up @@ -111,8 +112,11 @@ export default class JoinChannelAudio extends Component<{}, State, any> {
};

_switchRender = () => {
const { switchRender } = this.state;
this.setState({ switchRender: !switchRender });
const { switchRender, remoteUid } = this.state;
this.setState({
switchRender: !switchRender,
remoteUid: remoteUid.reverse(),
});
};

render() {
Expand Down Expand Up @@ -143,30 +147,26 @@ export default class JoinChannelAudio extends Component<{}, State, any> {
}

_renderVideo = () => {
const { remoteUid, switchRender } = this.state;
const { remoteUid } = this.state;
return (
<View style={styles.container}>
{switchRender ? (
<RtcLocalView.SurfaceView style={styles.local} />
) : (
<RtcRemoteView.SurfaceView
style={styles.local}
uid={remoteUid!}
zOrderMediaOverlay={true}
/>
)}
<RtcLocalView.SurfaceView style={styles.local} />
{remoteUid !== undefined && (
<TouchableOpacity style={styles.remote} onPress={this._switchRender}>
{switchRender ? (
<RtcRemoteView.SurfaceView
style={styles.container}
uid={remoteUid}
zOrderMediaOverlay={true}
/>
) : (
<RtcLocalView.SurfaceView style={styles.container} />
)}
</TouchableOpacity>
<ScrollView horizontal={true} style={styles.remoteContainer}>
{remoteUid.map((value, index) => (
<TouchableOpacity
key={index}
style={styles.remote}
onPress={this._switchRender}
>
<RtcRemoteView.SurfaceView
style={styles.container}
uid={value}
zOrderMediaOverlay={true}
/>
</TouchableOpacity>
))}
</ScrollView>
)}
</View>
);
Expand All @@ -192,11 +192,13 @@ const styles = StyleSheet.create({
local: {
flex: 1,
},
remote: {
width: 200,
height: 200,
remoteContainer: {
position: 'absolute',
left: 0,
top: 0,
},
remote: {
width: 120,
height: 120,
},
});

0 comments on commit 3ff1430

Please sign in to comment.