Skip to content

Commit

Permalink
feat: complete,hook (#881)
Browse files Browse the repository at this point in the history
  • Loading branch information
player0x3 authored Sep 22, 2022
1 parent 19e8439 commit a9f679b
Showing 1 changed file with 226 additions and 81 deletions.
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
import React, { ReactNode, useEffect, useState } from 'react';
import React, { useEffect, useState } from 'react';
import {
ChannelProfileType,
ErrorCodeType,
ClientRoleType,
createAgoraRtcEngine,
IRtcEngine,
RtcConnection,
RtcStats,
UserOfflineReasonType,
} from 'agora-electron-sdk';

import Config from '../../../config/agora.config';

import RtcSurfaceView from '../../../components/RtcSurfaceView';
import { Card } from 'antd';
import { Card, List } from 'antd';

import {
AgoraButton,
AgoraDivider,
AgoraText,
AgoraTextInput,
AgoraView,
Expand All @@ -23,32 +25,123 @@ import AgoraStyle from '../../config/public.scss';

export default function JoinChannelVideoWithAddlisten() {
const [appId] = useState(Config.appId);
const [enableVideo, setEnableVideo] = useState(true);
const [channelId] = useState(Config.channelId);
const [enableVideo] = useState(true);
const [channelId, setChannelId] = useState(Config.channelId);
const [token] = useState(Config.token);
const [uid] = useState(Config.uid);
const [joinChannelSuccess, setJoinChannelSuccess] = useState(false);
const [engine] = useState(createAgoraRtcEngine());
const [remoteUsers, setRemoteUsers] = useState<number[]>([]);
const [startPreview, setStartPreview] = useState(false);

/**
* Step 1: initRtcEngine
*/
const initRtcEngine = async () => {
if (!appId) {
this.error(`appId is invalid`);
error(`appId is invalid`);
}

engine.registerEventHandler(this);
engine.initialize({
appId,
// Should use ChannelProfileLiveBroadcasting on most of cases
channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting,
});

// Need to enable video on this case
// If you only call `enableAudio`, only relay the audio stream to the target channel
engine.enableVideo();

// Start preview before joinChannel
engine.startPreview();
setStartPreview(true);
};

/**
* Step 2: joinChannel
*/
const joinChannel = () => {
if (!channelId) {
error('channelId is invalid');
return;
}
if (uid < 0) {
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
engine?.joinChannel(token, channelId, uid, {
// Make myself as the broadcaster to send stream to remote
clientRoleType: ClientRoleType.ClientRoleBroadcaster,
});
};

/**
* Step 3: leaveChannel
*/
const leaveChannel = () => {
engine?.leaveChannel();
};

/**
* Step 4: releaseRtcEngine
*/
const releaseRtcEngine = () => {
engine?.unregisterEventHandler(this);
engine?.release();
};

const _logSink = (
level: 'debug' | 'log' | 'info' | 'warn' | 'error',
message?: any,
...optionalParams: any[]
): string => {
console[level](message, optionalParams);
return `${optionalParams.map((v) => JSON.stringify(v))}`;
};

const debug = (message?: any, ...optionalParams: any[]): void => {
alert(`${message}: ${_logSink('debug', message, ...optionalParams)}`);
};

const log = (message?: any, ...optionalParams: any[]): void => {
_logSink('log', message, optionalParams);
};

const info = (message?: any, ...optionalParams: any[]): void => {
_logSink('info', message, optionalParams);
};

const warn = (message?: any, ...optionalParams: any[]): void => {
_logSink('warn', message, optionalParams);
};

const error = (message?: any, ...optionalParams: any[]): void => {
_logSink('error', message, optionalParams);
};

useEffect(() => {
initRtcEngine();

engine.addListener('onError', (err: ErrorCodeType, msg: string) => {
info('onError', 'err', err, 'msg', msg);
});

engine.addListener(
'onJoinChannelSuccess',
(connection: RtcConnection, elapsed: number) => {
info(
'onJoinChannelSuccess',
'connection',
connection,
'elapsed',
elapsed
);
setJoinChannelSuccess(true);
console.log('addListener:onJoinChannelSuccess', {
connection,
Expand All @@ -60,7 +153,10 @@ export default function JoinChannelVideoWithAddlisten() {
engine.addListener(
'onLeaveChannel',
(connection: RtcConnection, stats: RtcStats) => {
info('onLeaveChannel', 'connection', connection, 'stats', stats);
setJoinChannelSuccess(false);
setStartPreview(false);
setRemoteUsers([]);
console.log(
'addListener:onLeaveChannel',
'connection',
Expand All @@ -70,93 +166,142 @@ export default function JoinChannelVideoWithAddlisten() {
);
}
);

engine.addListener(
'onUserJoined',
(connection: RtcConnection, remoteUid: number, elapsed: number) => {
info(
'onUserJoined',
'connection',
connection,
'remoteUid',
remoteUid,
'elapsed',
elapsed
);
if (remoteUsers === undefined) return;
setRemoteUsers([...remoteUsers!, remoteUid]);
}
);

engine.addListener(
'onUserOffline',
(
connection: RtcConnection,
remoteUid: number,
reason: UserOfflineReasonType
) => {
info(
'onUserOffline',
'connection',
connection,
'remoteUid',
remoteUid,
'reason',
reason
);
if (remoteUsers === undefined) return;
setRemoteUsers([...remoteUsers!, remoteUid]);
}
);

return () => {
engine.removeAllListeners('onJoinChannelSuccess');
engine.removeAllListeners('onLeaveChannel');
engine.removeAllListeners('onUserOffline');
engine.removeAllListeners('onUserJoined');
engine.removeAllListeners('onError');
releaseRtcEngine();
};
}, []);

const configuration = renderConfiguration();
return (
<AgoraView className={AgoraStyle.screen}>
<AgoraView className={AgoraStyle.content}>
<RenderVideo
uid={uid}
channelId={channelId}
enableVideo={enableVideo}
/>
</AgoraView>
<AgoraView className={AgoraStyle.content}>{renderUsers()}</AgoraView>
<AgoraView className={AgoraStyle.rightBar}>
<RenderChannel
engine={engine}
uid={uid}
channelId={channelId}
joinChannelSuccess={joinChannelSuccess}
token={token}
/>
{renderChannel()}
{configuration ? (
<>
<AgoraDivider>
The Configuration of JoinChannelVideoWithAddlisten
</AgoraDivider>
{configuration}
</>
) : undefined}
<AgoraDivider />
{renderAction()}
</AgoraView>
</AgoraView>
);
}

function RenderVideo(props: {
uid: number;
channelId: string;
enableVideo: boolean;
}) {
const { uid, channelId, enableVideo } = props;
return (
<Card title={`${uid === 0 ? 'Local' : 'Remote'} Uid: ${uid}`}>
<AgoraText>Click view to mirror</AgoraText>
{enableVideo ? (
<RtcSurfaceView canvas={{ uid }} connection={{ channelId }} />
) : (
<div></div>
)}
{/* <AgoraButton/> */}
</Card>
);
}
function renderConfiguration() {
return undefined;
}

function RenderChannel(props: {
engine: IRtcEngine;
channelId: string;
joinChannelSuccess: boolean;
uid: number;
token: string;
}) {
const { engine, channelId, joinChannelSuccess, uid, token } = props;
const leaveChannel = () => {
engine.leaveChannel();
};
const joinChannel = () => {
if (!channelId) {
this.error('channelId is invalid');
return;
}
if (uid < 0) {
this.error('uid is invalid');
return;
}
engine.joinChannel(token, channelId, uid, {
clientRoleType: ClientRoleType.ClientRoleBroadcaster,
});
};
function renderUsers() {
return (
<>
{startPreview || joinChannelSuccess ? (
<List
style={{ width: '100%' }}
grid={{
gutter: 16,
xs: 1,
sm: 1,
md: 1,
lg: 1,
xl: 1,
xxl: 2,
}}
dataSource={[uid, ...remoteUsers]}
renderItem={renderVideo.bind(window)}
/>
) : undefined}
</>
);
}

return (
<>
<AgoraTextInput
onChangeText={(text) => {
this.setState({ channelId: text });
}}
placeholder={`channelId`}
value={channelId}
/>
<AgoraButton
title={`${joinChannelSuccess ? 'leave' : 'join'} Channe`}
onPress={() => {
joinChannelSuccess ? leaveChannel() : joinChannel();
}}
/>
</>
);
function renderChannel() {
return (
<>
<AgoraTextInput
onChangeText={(text) => {
setChannelId(text);
}}
placeholder={`channelId`}
value={channelId}
/>
<AgoraButton
title={`${joinChannelSuccess ? 'leave' : 'join'} Channel`}
onPress={() => {
joinChannelSuccess ? leaveChannel() : joinChannel();
}}
/>
</>
);
}

function renderAction() {
return undefined;
}

function renderVideo() {
return (
<List.Item>
<Card title={`${uid === 0 ? 'Local' : 'Remote'} Uid: ${uid}`}>
<AgoraText>Click view to mirror</AgoraText>
{enableVideo ? (
<RtcSurfaceView canvas={{ uid }} connection={{ channelId }} />
) : undefined}
<AgoraButton
title={`Append`}
onPress={() => {
setRemoteUsers([...remoteUsers!, uid]);
}}
/>
</Card>
</List.Item>
);
}
}

0 comments on commit a9f679b

Please sign in to comment.