1 Star 0 Fork 0

agoraio-community/Electron-SDK

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
.githooks
.github
ci
example
assets
extraResources
scripts
src
main
renderer
components
config
examples
advanced
AgoraALD
AudioMixing
AudioSpectrum
BeautyEffect
ChannelMediaRelay
ContentInspect
DeviceManager
DirectCdnStreaming
Encryption
Extension
JoinMultipleChannel
JoinMultipleChannel.tsx
LocalSpatialAudioEngine
LocalVideoTranscoder
MediaPlayer
MediaRecorder
Meet
MusicContentCenter
PlayEffect
ProcessVideoRawData
PushVideoFrame
RTMPStreaming
RhythmPlayer
ScreenShare
SendMetadata
SendMultiVideoStream
Simulcast
SpatialAudio
StreamMessage
TakeSnapshot
VideoEncoderConfiguration
VirtualBackground
VoiceChanger
index.ts
basic
config/AuthInfoScreen
hook
utils
App.global.scss
App.global.scss.d.ts
App.tsx
global.d.ts
index.tsx
renderer.d.ts
.gitattributes
.gitignore
.yarnclean
.yarnrc
README.md
electron-webpack.json
package.json
tsconfig.json
webpack.renderer.additions.js
yarn.lock
patches
resources
scripts
source_code
ts
.clang-format
.editorconfig
.eslintignore
.eslintrc
.gitattributes
.gitignore
.gitleaks.toml
.nvmrc
.prettierignore
.prettierrc
.yarnrc
CHANGELOG.md
CMakeLists.txt
Jenkinsfile_bitbucket.groovy
LICENSE
README.md
babel.config.js
gulpfile.js
lefthook.yml
package.json
tsconfig.build.json
tsconfig.json
yarn.lock
克隆/下载
JoinMultipleChannel.tsx 11.99 KB
一键复制 编辑 原始数据 按行查看 历史
import {
ChannelProfileType,
ClientRoleType,
IRtcEngineEventHandler,
IRtcEngineEx,
RemoteVideoState,
RemoteVideoStateReason,
RtcConnection,
RtcStats,
UserOfflineReasonType,
createAgoraRtcEngine,
} from 'agora-electron-sdk';
import React, { ReactElement } from 'react';
import {
BaseComponent,
BaseVideoComponentState,
} from '../../../components/BaseComponent';
import { AgoraButton, AgoraList, AgoraTextInput } from '../../../components/ui';
import Config from '../../../config/agora.config';
import { askMediaAccess } from '../../../utils/permissions';
interface State extends BaseVideoComponentState {
channelId2: string;
token2: string;
uid2: number;
joinChannelSuccess2: boolean;
remoteUsers2: number[];
}
export default class JoinMultipleChannel
extends BaseComponent<{}, State>
implements IRtcEngineEventHandler
{
// @ts-ignore
protected engine?: IRtcEngineEx;
protected createState(): State {
return {
appId: Config.appId,
enableVideo: true,
channelId: Config.channelId,
token: Config.token,
uid: Config.uid,
joinChannelSuccess: false,
remoteUsers: [],
startPreview: false,
channelId2: '',
token2: '',
uid2: 0,
joinChannelSuccess2: false,
remoteUsers2: [],
};
}
/**
* Step 1: initRtcEngine
*/
protected async initRtcEngine() {
const { appId } = this.state;
if (!appId) {
this.error(`appId is invalid`);
}
this.engine = createAgoraRtcEngine() as IRtcEngineEx;
this.engine.initialize({
appId,
logConfig: { filePath: Config.logFilePath },
// Should use ChannelProfileLiveBroadcasting on most of cases
channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting,
});
this.engine.registerEventHandler(this);
// Need granted the microphone and camera permission
await askMediaAccess(['microphone', 'camera']);
// Need to enable video on this case
// If you only call `enableAudio`, only relay the audio stream to the target channel
this.engine.enableVideo();
// Need to startPreview before joinChannelEx
this.engine.startPreview();
this.setState({ startPreview: true });
}
/**
* Step 2-1: joinChannel
*/
protected joinChannel() {
const { channelId, token, uid } = this.state;
if (!channelId) {
this.error('channelId is invalid');
return;
}
if (uid <= 0) {
this.error('uid is invalid');
return;
}
// start joining channel
// 1. Users can only see each other after they join the
// same channel successfully using the same app id.
// 2. If app certificate is turned on at dashboard, token is needed
// when joining channel. The channel name and uid used to calculate
// the token has to match the ones used for channel join
this.engine?.joinChannelEx(
token,
{
channelId,
localUid: uid,
},
{
// Make myself as the broadcaster to send stream to remote
clientRoleType: ClientRoleType.ClientRoleBroadcaster,
publishMicrophoneTrack: false,
publishCameraTrack: false,
}
);
}
/**
* Step 2-2: joinChannel2
*/
protected joinChannel2() {
const { channelId2, token2, uid2 } = this.state;
if (!channelId2) {
this.error('channelId2 is invalid');
return;
}
if (uid2 <= 0) {
this.error('uid2 is invalid');
return;
}
// start joining channel
// 1. Users can only see each other after they join the
// same channel successfully using the same app id.
// 2. If app certificate is turned on at dashboard, token is needed
// when joining channel. The channel name and uid used to calculate
// the token has to match the ones used for channel join
this.engine?.joinChannelEx(
token2,
{
channelId: channelId2,
localUid: uid2,
},
{
// Make myself as the broadcaster to send stream to remote
clientRoleType: ClientRoleType.ClientRoleBroadcaster,
publishMicrophoneTrack: false,
publishCameraTrack: false,
}
);
}
/**
* Step 3-1: publishStreamToChannel
*/
publishStreamToChannel = () => {
const { channelId, channelId2, uid, uid2 } = this.state;
this.engine?.updateChannelMediaOptionsEx(
{ publishMicrophoneTrack: false, publishCameraTrack: false },
{
channelId: channelId2,
localUid: uid2,
}
);
this.engine?.updateChannelMediaOptionsEx(
{ publishMicrophoneTrack: true, publishCameraTrack: true },
{
channelId,
localUid: uid,
}
);
};
/**
* Step 3-2: publishStreamToChannel2
*/
publishStreamToChannel2 = () => {
const { channelId, channelId2, uid, uid2 } = this.state;
this.engine?.updateChannelMediaOptionsEx(
{ publishMicrophoneTrack: false, publishCameraTrack: false },
{
channelId,
localUid: uid,
}
);
this.engine?.updateChannelMediaOptionsEx(
{ publishMicrophoneTrack: true, publishCameraTrack: true },
{
channelId: channelId2,
localUid: uid2,
}
);
};
/**
* Step 4-1: leaveChannel
*/
protected leaveChannel() {
const { channelId, uid } = this.state;
this.engine?.leaveChannelEx({
channelId,
localUid: uid,
});
}
/**
* Step 4-2: leaveChannel2
*/
protected leaveChannel2() {
const { channelId2, uid2 } = this.state;
this.engine?.leaveChannelEx({
channelId: channelId2,
localUid: uid2,
});
}
/**
* Step 5: releaseRtcEngine
*/
protected releaseRtcEngine() {
this.engine?.unregisterEventHandler(this);
this.engine?.release();
}
onJoinChannelSuccess(connection: RtcConnection, elapsed: number) {
this.info(
'onJoinChannelSuccess',
'connection',
connection,
'elapsed',
elapsed
);
const { channelId, channelId2, uid, uid2 } = this.state;
if (connection.channelId === channelId && connection.localUid === uid) {
this.setState({
joinChannelSuccess: true,
});
} else if (
connection.channelId === channelId2 &&
connection.localUid === uid2
) {
this.setState({
joinChannelSuccess2: true,
});
}
}
onLeaveChannel(connection: RtcConnection, stats: RtcStats) {
this.info('onLeaveChannel', 'connection', connection, 'stats', stats);
const { channelId, channelId2, uid, uid2 } = this.state;
if (connection.channelId === channelId && connection.localUid === uid) {
this.setState({
joinChannelSuccess: false,
remoteUsers: [],
});
} else if (
connection.channelId === channelId2 &&
connection.localUid === uid2
) {
this.setState({
joinChannelSuccess2: false,
remoteUsers2: [],
});
}
// Keep preview after leave channel
this.engine?.startPreview();
}
onUserJoined(connection: RtcConnection, remoteUid: number, elapsed: number) {
this.info(
'onUserJoined',
'connection',
connection,
'remoteUid',
remoteUid,
'elapsed',
elapsed
);
}
onUserOffline(
connection: RtcConnection,
remoteUid: number,
reason: UserOfflineReasonType
) {
this.info(
'onUserOffline',
'connection',
connection,
'remoteUid',
remoteUid,
'reason',
reason
);
}
onRemoteVideoStateChanged(
connection: RtcConnection,
remoteUid: number,
state: RemoteVideoState,
reason: RemoteVideoStateReason,
elapsed: number
) {
this.info(
'onRemoteVideoStateChanged',
'connection',
connection,
'remoteUid',
remoteUid,
'state',
state,
'reason',
reason,
'elapsed',
elapsed
);
const { channelId, channelId2, uid, uid2 } = this.state;
if (state === RemoteVideoState.RemoteVideoStateStarting) {
if (connection.channelId === channelId && connection.localUid === uid) {
this.setState((preState) => {
return { remoteUsers: [...preState.remoteUsers, remoteUid] };
});
} else if (
connection.channelId === channelId2 &&
connection.localUid === uid2
) {
this.setState((preState) => {
return { remoteUsers2: [...preState.remoteUsers2, remoteUid] };
});
}
} else if (state === RemoteVideoState.RemoteVideoStateStopped) {
if (connection.channelId === channelId && connection.localUid === uid) {
this.setState((preState) => {
return {
remoteUsers: preState.remoteUsers.filter(
(value) => value !== remoteUid
),
};
});
} else if (
connection.channelId === channelId2 &&
connection.localUid === uid2
) {
this.setState((preState) => {
return {
remoteUsers2: preState.remoteUsers2.filter(
(value) => value !== remoteUid
),
};
});
}
}
}
protected renderChannel(): ReactElement | undefined {
const {
channelId,
channelId2,
uid,
uid2,
joinChannelSuccess,
joinChannelSuccess2,
} = this.state;
return (
<>
<AgoraTextInput
onChangeText={(text) => {
this.setState({ channelId: text });
}}
placeholder={`channelId`}
value={channelId}
/>
<AgoraTextInput
onChangeText={(text) => {
if (isNaN(+text)) return;
this.setState({
uid: text === '' ? this.createState().uid : +text,
});
}}
numberKeyboard={true}
placeholder={`uid (must > 0)`}
value={uid > 0 ? uid.toString() : ''}
/>
<AgoraButton
title={`${joinChannelSuccess ? 'leave' : 'join'} Channel`}
onPress={() => {
joinChannelSuccess ? this.leaveChannel() : this.joinChannel();
}}
/>
<AgoraTextInput
onChangeText={(text) => {
this.setState({ channelId2: text });
}}
placeholder={`channelId2`}
value={channelId2}
/>
<AgoraTextInput
onChangeText={(text) => {
if (isNaN(+text)) return;
this.setState({
uid2: text === '' ? this.createState().uid2 : +text,
});
}}
numberKeyboard={true}
placeholder={`uid2 (must > 0)`}
value={uid2 > 0 ? uid2.toString() : ''}
/>
<AgoraButton
title={`${joinChannelSuccess2 ? 'leave' : 'join'} Channel2`}
onPress={() => {
joinChannelSuccess2 ? this.leaveChannel2() : this.joinChannel2();
}}
/>
</>
);
}
protected renderUsers(): ReactElement | undefined {
const {
startPreview,
channelId,
channelId2,
uid,
uid2,
joinChannelSuccess,
joinChannelSuccess2,
remoteUsers,
remoteUsers2,
} = this.state;
return (
<>
{startPreview || joinChannelSuccess || joinChannelSuccess2 ? (
<AgoraList
data={[0, ...remoteUsers, ...remoteUsers2]}
renderItem={(item) => {
return this.renderVideo(
{ uid: item },
{
channelId:
remoteUsers2.indexOf(item) === -1 ? channelId : channelId2,
localUid: remoteUsers2.indexOf(item) === -1 ? uid : uid2,
}
);
}}
/>
) : undefined}
</>
);
}
protected renderAction(): ReactElement | undefined {
const { joinChannelSuccess, joinChannelSuccess2 } = this.state;
return (
<>
<AgoraButton
disabled={!joinChannelSuccess}
title={`publish Stream To Channel`}
onPress={this.publishStreamToChannel}
/>
<AgoraButton
disabled={!joinChannelSuccess2}
title={`publish Stream To Channel2`}
onPress={this.publishStreamToChannel2}
/>
</>
);
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
JavaScript
1
https://gitee.com/agoraio-community/Electron-SDK.git
git@gitee.com:agoraio-community/Electron-SDK.git
agoraio-community
Electron-SDK
Electron-SDK
main

搜索帮助