Commit 036cb24e authored by liujiaxin's avatar liujiaxin

教师位置挪到第一位

parent 70b53f47
......@@ -38,10 +38,17 @@ const useStyles = makeStyles({
const CourseWareFrame: React.FC = () => {
const classes = useStyles();
// `${ENDPOINT}/airclass_ol?token=${this.userToken}`;
const src = endPoint.getCourseUrl();
let src = endPoint.getCourseUrl();
useEffect(() => {
return () => {
src = 'about:blank'
console.log('iframe to blank');
}
}, []);
return (
<div className={classes.style1}>
<iframe src={src} className={classes.frm}></iframe>
<iframe id="cwFrame" src={src} className={classes.frm}></iframe>
</div>
)
}
......
......@@ -371,7 +371,30 @@ const items = [
useEffect(() => {
if (!rtmState.joined) return;
// debugger
if (!lock.current && !whiteboard.state.room) {
console.log('do join whiteboard room');
lock.current = true;
whiteboard.join({
rid: roomStore.state.course.rid,
uid: roomStore.state.course.boardId, // me.boardId,
userPayload: {
userId: roomStore.state.me.uid,
identity: roomStore.state.me.role === 'teacher' ? 'host' : 'guest'
}
})
.then(() => {
console.log("join whiteboard success");
}).catch(console.warn)
.finally(() => {
lock.current = false;
})
}
/*
if (!lock.current && !whiteboard.state.room) {
console.log('do join whiteboard room');
lock.current = true;
whiteboard.join({
rid: roomStore.state.course.rid,
......@@ -391,6 +414,7 @@ const items = [
if (!lock.current && course.boardId && me.boardId !== course.boardId && whiteboard.state.room) {
lock.current = true;
console.log('do rejoin whiteboard room');
whiteboard.join({
rid: roomStore.state.course.rid,
uid: course.boardId,
......@@ -406,7 +430,7 @@ const items = [
lock.current = false;
})
}
*/
}, [rtmState.joined, me.boardId, course.boardId]);
const [uploadPhase, updateUploadPhase] = useState<string>('');
......
......@@ -179,11 +179,7 @@ useEffect(() => {
}
if (stream.isPlaying()) {
// debugger
try{
stream.stop();
} catch (e) {
// console.log(e);
}
// stream.stop();
}
local && stream && stream.close();
......
......@@ -165,7 +165,8 @@ export const RootProvider: React.FC<any> = ({children}) => {
useEffect(() => {
if (location.pathname === '/') {
GlobalStorage.clear('agora_room');
// alert('clear1')
// GlobalStorage.clear('agora_room');
return;
}
const room = value.roomState;
......
......@@ -158,12 +158,15 @@ export default function useStream () {
const uid = studentIds.find((it: number) => `${ouid}` == `${it}`);
if (uid) {
sids.push(uid);
roomStore.releaseWaitStreamHandle(+uid);
} else {
// find in channel
const usr = userAttrs.get(`${ouid}`)
console.log('channel has ', ouid, usr)
if (usr) {
sids.push(-usr.uid/*+usr.uid*/);
sids.push(-usr.uid);
console.log('add waiting handle', usr.uid)
roomStore.lockWaitStreamHandle(+usr.uid);
} else {
// sids.push(-1);
sids[orderIdx] = 0;
......@@ -190,7 +193,7 @@ export default function useStream () {
// capture all remote streams
for (let studentId of /*studentIds*/sids) {
console.log('*****************', studentId)
// console.log('*****************', studentId)
if (studentId == undefined) {
continue
......
......@@ -158,7 +158,7 @@ export function RoomPage({ children }: any) {
}, [me.role, location.pathname, course.linkId]);
useEffect(() => {
useEffect( () => {
const webClient = roomStore.rtcClient as AgoraWebClient;
if (!rtcJoined) {
webClient.unpublishLocalStream()
......@@ -167,10 +167,16 @@ export function RoomPage({ children }: any) {
if (!rtcJoined || rtc.current) return;
if (platform === 'web') {
roomStore.rtmClient.getChannelAttributeBy(roomStore.state.course.rid).then((channelMeta: any) => {
console.log('check user publish stream, channelMeta', channelMeta);
console.log('check user publish stream, user orders', roomStore.state.studentsOrder);
console.log('check user publish stream, user info', roomStore.state.me);
const studentsOrder = channelMeta.studentsOrder || roomStore.state.studentsOrder;
// const webClient = roomStore.rtcClient as AgoraWebClient;
const uid = +roomStore.state.me.uid as number;
const video = roomStore.state.studentsOrder.includes(uid) ? 1 : roomStore.state.me.video;
const audio = roomStore.state.studentsOrder.includes(uid) ? 1 : roomStore.state.me.audio;
const video = studentsOrder.includes(uid) ? 1 : roomStore.state.me.video;
const audio = studentsOrder.includes(uid) ? 1 : roomStore.state.me.audio;
const streamSpec: AgoraStreamSpec = {
streamID: uid,
video: !!video,
......@@ -196,6 +202,8 @@ export function RoomPage({ children }: any) {
publishLock.current = false;
})
}
});
}
if (platform === 'electron' && rtcJoined) {
......
......@@ -48,7 +48,7 @@ function canJoin({uid, onlineStatus, roomType, channelCount, role}: { uid: any,
return result;
}
const WaitStreamPool = new Map();
export interface AgoraUser {
uid: string
......@@ -219,6 +219,30 @@ export class RoomStore {
...this.defaultState
};
const webClient = this.rtcClient as AgoraWebClient;
webClient.rtc.on('stream-reconnect-start', (evt: any) => {
console.log('[agora-web] stream-reconnect-start', evt);
});
webClient.rtc.on('connection-state-change', (evt: any) => {
console.log('[agora-web] connection-state-change', evt);
});
webClient.rtc.on('reconnect', (evt: any) => {
console.log('[agora-web] reconnect', evt);
});
webClient.rtc.on('connected', (evt: any) => {
console.log('[agora-web] connected', evt);
});
webClient.rtc.on('stream-fallback', (evt: any) => {
console.log('[agora-web] stream-fallback', evt);
});
webClient.rtc.on('stream-updated', (evt: any) => {
console.log('[agora-web] stream-updated', evt);
});
webClient.rtc.on('exception', (evt: any) => {
console.log('[agora-web] exception', evt);
});
// const location = useLocation();
webClient.rtc.on('onTokenPrivilegeWillExpire', (evt: any) => {
// you need obtain the `newToken` token from server side
......@@ -358,70 +382,8 @@ export class RoomStore {
data['studentsOrder'] = studentsOrder;
await this.rtmClient.addOrUpdateChannelAttributes(data);
}
async stageUp3333(uid: string) {
let studentsOrder: any[] = [...this.state.studentsOrder];
const data: any = {};
const emptyIndex = studentsOrder.indexOf(0);
if (emptyIndex > -1) {
studentsOrder[emptyIndex] = +uid;
const upUser: AgoraUser | undefined = this.state.users.get(`${uid}`);
if (upUser) {
upUser.video = 1;
upUser.audio = 1;
data[upUser.uid] = upUser;
}
} else {
studentsOrder.unshift(+uid);
let lastUid = studentsOrder[studentsOrder.length - 1];
const lastUser: AgoraUser | undefined = this.state.users.get(`${lastUid}`);
if (lastUser) {
lastUser.video = 0;
lastUser.audio = 0;
data[lastUser.uid] = lastUser;
}
const upUser: AgoraUser | undefined = this.state.users.get(`${uid}`);
if (upUser) {
upUser.video = 1;
upUser.audio = 1;
data[upUser.uid] = upUser;
}
if (!lastUser || !upUser) {
return
}
if (studentsOrder.length > STAGE_NUM) {
studentsOrder.length = STAGE_NUM
}
}
data['studentsOrder'] = studentsOrder;
await this.rtmClient.addOrUpdateChannelAttributes(data);
// this.state = {
// ...this.state,
// users
// }
// this.commit(this.state);
}
async randomStageUp() {
const users = roomStore.state.users;
const studentsOrder = roomStore.state.studentsOrder || [];
......@@ -574,8 +536,8 @@ export class RoomStore {
// 如果一个流退了,检测是否是台上人员,移除掉,其实就是下台
// await this.stageDown(`${uid}`)
const orders = [...this.state.studentsOrder];
const checkIdx1 = orders.indexOf(+uid)
const checkIdx2 = orders.indexOf(-uid)
const checkIdx1 = orders.indexOf(+uid); // 在台上
const checkIdx2 = orders.indexOf(-uid); // 等待中
if (checkIdx1 > 0) {
orders.splice(checkIdx1, 1, 0)
}
......@@ -589,7 +551,7 @@ export class RoomStore {
remoteStream.stream.isPlaying() && remoteStream.stream.stop();
}
}
if (checkIdx1 > 0 || checkIdx2 > 0) {
if (checkIdx1 >= 0 || checkIdx2 >= 0) {
await this.rtmClient.addOrUpdateChannelAttributes({studentsOrder: orders});
}
......@@ -606,13 +568,24 @@ export class RoomStore {
}
async addRemoteStream(stream: AgoraStream) {
// const sod = this.state.studentsOrder;
// const hasMe = sod.indexOf(stream.streamID);
// if (!hasMe && stream.streamID > 0) {
// const emptyIndex = sod.indexOf(0);
// sod.splice(emptyIndex, 1, stream.streamID)
// }
if (stream.streamID > 0 && +stream.streamID != +this.state.course.teacherId) {
this.stageUp(''+stream.streamID)
}
console.log('remoteStreams added',5 , stream.streamID, this.state.users)
this.state = {
...this.state,
rtc: {
...this.state.rtc,
remoteStreams: this.state.rtc.remoteStreams.set(stream.streamID, stream)
}
},
// studentsOrder: sod
}
await this.commit(this.state);
}
......@@ -875,10 +848,12 @@ export class RoomStore {
}
async loginAndJoin(payload: any, pass: boolean = false) {
// payload.rid = `channel_${payload.rid}`
console.log('channel:', payload.rid);
const {roomType, role, uid, rid, token} = payload;
await this.rtmClient.logout();
try{await this.rtmClient.logout();} catch(e){}
await this.rtmClient.login(uid, token);
const channelMemberCount = await this.rtmClient.getChannelMemberCount([rid]);
const channelCount = channelMemberCount[rid];
......@@ -1152,6 +1127,72 @@ export class RoomStore {
await this.rtmClient.addOrUpdateChannelAttributes(data);
}
}
async _removeWaitingStream(streamId: number) {
console.log('_removeWaitingStream', streamId);
let handle = WaitStreamPool.get(streamId);
clearTimeout(handle);
handle = null;
WaitStreamPool.set(streamId, null);
WaitStreamPool.delete(streamId);
// 从orders里移除,那是直接移除orders还是直接删除?
// 先移除orders吧
// const newInfo: any = await this.syncStageStudentByTeacherOrder2(users.toArray(), currentRoomUsers);
// console.log('newInfo', newInfo)
// if (newInfo) {
// await this.rtmClient.clearChannelAttributesByKeys([`${streamId}`]);
// }
if (streamId < 0) {
streamId = Math.abs(streamId)
}
if (streamId && `${streamId}` !== `${this.state.course.teacherId}`) {
// console.log('remove user from channel', streamId);
// await this.rtmClient.clearChannelAttributesByKeys([`${streamId}`]);
// 这里不应该移除直播间,应该从rtc.users移除
// 因为,从频道里移出去后,app没做相应处理,就会教师看不到他,而他还在直播间内
this.state = {
...this.state,
rtc: {
...this.state.rtc,
users: this.state.rtc.users.delete(streamId),
},
}
await this.commit(this.state);
this.stageDown(`${streamId}`)
}
// this.stageUp(`${streamId}`)
}
async releaseWaitStreamHandle(streamId: number) {
let handle = WaitStreamPool.get(streamId);
if (handle) {
console.log('releaseWaitStreamHandle has handle', streamId);
let handle = WaitStreamPool.get(streamId);
clearTimeout(handle);
handle = null;
WaitStreamPool.set(streamId, null);
WaitStreamPool.delete(streamId);
}
}
async lockWaitStreamHandle(streamId: number) {
// console.log('waitStreamHandle', streamId);
let handle = WaitStreamPool.get(streamId);
console.log('waitStreamHandle', handle);
if (handle) {
console.log('waitStreamHandle has handle', streamId);
return
// this._removeWaitingStream(streamId);
} else {
console.log('waitStreamHandle add new handle', streamId);
handle = setTimeout(() => {
this._removeWaitingStream(streamId);
}, 5000);
WaitStreamPool.set(streamId, handle);
}
}
async updateMe(user: any, studentsOrder: number[] = []) {
const {role, uid, account, rid, video, audio, chat, boardId, linkId, sharedId, muteChat, muteAudio, grantBoard} = user;
......@@ -1177,7 +1218,7 @@ export class RoomStore {
last_stage_ts: Date.now()
});
console.log('users', user);
console.log('updateMe in', user);
if (grantBoard !== undefined) {
Object.assign(attrs, {
grant_board: grantBoard,
......@@ -1221,16 +1262,16 @@ export class RoomStore {
const userIndex = studentsOrder.indexOf(+memberId);
if (userIndex > -1) {
studentsOrder.splice(userIndex, 1, 0)
this.state = {
...this.state,
studentsOrder
}
await this.commit(this.state);
// const data: any = {};
// data['studentsOrder'] = studentsOrder;
// console.log('update me', data);
// this.state = {
// ...this.state,
// studentsOrder
// }
// await this.commit(this.state);
const data: any = {};
data['studentsOrder'] = studentsOrder;
console.log('rtmLeaveUser', data);
// await this.rtmClient.addOrUpdateChannelAttributes(data);
await this.rtmClient.clearChannelAttributesByKeys([`${memberId}`]);
// await this.rtmClient.clearChannelAttributesByKeys([`${memberId}`]);
}
}
......@@ -1260,13 +1301,13 @@ export class RoomStore {
}
}
if (needUpdate) {
this.state = {
...this.state,
studentsOrder
}
// this.state = {
// ...this.state,
// studentsOrder
// }
// this.state.studentsOrder = studentsOrder;
await this.commit(this.state);
// await this.commit(this.state);
// await this.rtmClient.addOrUpdateChannelAttributes({'studentsOrder': studentsOrder});
}
console.log('加入完登录学生后', this.state.studentsOrder);
}
......@@ -1284,8 +1325,8 @@ export class RoomStore {
}
});
let shouldOut = channelStudentsOrder.filter(x => !tSOrder.includes(x) && x !== 0);
let shouldIn = tSOrder.filter(x => !channelStudentsOrder.includes(x) && x !== 0);
let shouldOut = channelStudentsOrder.filter(x => !tSOrder.includes(x) && x !== 0 && x !== -1);
let shouldIn = tSOrder.filter(x => !channelStudentsOrder.includes(x) && x !== 0 && x !== -1);
console.log('shouldOut', shouldOut);
shouldOut.forEach(o => {
const oi = tSOrder.indexOf(o);
......@@ -1405,12 +1446,79 @@ export class RoomStore {
return data
}
}
async syncStageStudentByTeacherOrder2(newUsers: any[], oldUsers: any[]){
// debugger
console.log('new users', newUsers);
console.log('current users', oldUsers);
console.log('teacher keep studentsOrder', this.state.studentsOrder);
const data: any = {};
const newAccData: any = {};
const newUids: number[] = []
newUsers.forEach(([uid, userInfo]) =>{
if (userInfo.role != 'teacher') {
newAccData[uid] = userInfo;
newUids.push(+uid);
}
});
const oldUids: number[] = []
oldUsers.forEach( ([uid, userInfo]) => {
if (userInfo.role != 'teacher') {
oldUids.push(+uid)
}
});
const tSOrder = [...this.state.studentsOrder];
const _to1 = [...tSOrder]
_to1.sort((a, b) => a - b)
const tSOrderStr1 = JSON.stringify(_to1)
let shouldOut = oldUids.filter(x => !newUids.includes(x) && x > 0);
let shouldIn = newUids.filter(x => !oldUids.includes(x) && x > 0);
console.log('shouldOut', shouldOut);
console.log('shouldIn', shouldIn);
shouldOut.forEach(o => {
const oi = tSOrder.indexOf(o);
if (oi > -1) {
tSOrder.splice(oi, 1, 0)
}
})
shouldIn.forEach(o => {
if(!tSOrder.includes(o)) {
const ii = tSOrder.indexOf(0);
if (ii > -1) {
tSOrder.splice(ii, 1, o)
const user = newAccData[o];
if (user) {
user.audio = 1;
user.video = 1;
data[o] = user;
}
}
}
})
const _to2 = [...tSOrder]
_to2.sort((a, b) => a - b)
const tSOrderStr2 = JSON.stringify(_to2)
console.log(tSOrderStr1, tSOrderStr2);
if (tSOrderStr1 != tSOrderStr2) {
data['studentsOrder'] = [...tSOrder];
console.log('new channel attr to every one');
return data
}
// if (shouldIn.length || shouldOut.length) {
// data['studentsOrder'] = [...tSOrder];
// return data
// }
}
async updateRoomAttrs ({teacher, accounts, room, studentsOrder}: {teacher: any, accounts: any, room: any, studentsOrder: number[]}) {
console.log("[agora-board], room: ",teacher, accounts, room, studentsOrder);
const currentRoomUsers = this.state.users.toArray();
const exitUserIds = [];
const users: OrderedMap<string, AgoraUser> = accounts.reduce((acc: OrderedMap<string, AgoraUser>, it: any) => {
roomStore.releaseWaitStreamHandle(it.uid);
return acc.set(it.uid, {
role: it.role,
account: it.account,
......@@ -1467,6 +1575,7 @@ export class RoomStore {
let newStudentsOrder = studentsOrder;
console.log('频道StudentsOrder', newStudentsOrder);
console.log('用户保存StudentsOrder', this.state.studentsOrder);
if (me.role === 'teacher') {
/*
// remove exist user from studentsOrder
......@@ -1494,7 +1603,10 @@ export class RoomStore {
this.syncStudentsOrderTimer = null;
}
//教师维护学生顺序,仅保留STAGE_NUM个,并更新到频道属性
const newInfo: any = await this.syncStageStudentByTeacherOrder(JSON.parse(JSON.stringify(accounts)), [...studentsOrder/*this.state.studentsOrder*/]);
// const newInfo: any = await this.syncStageStudentByTeacherOrder(JSON.parse(JSON.stringify(accounts)), [...newStudentsOrder/*this.state.studentsOrder*/]);
const newInfo: any = await this.syncStageStudentByTeacherOrder2(users.toArray(), currentRoomUsers);
console.log('newInfo', newInfo)
// debugger
if (newInfo) {
......@@ -1575,7 +1687,7 @@ export class RoomStore {
// @ts-ignore
ifm.contentWindow.location.href='about:blank'
// @ts-ignore
ifm.contentWindow.document.write('')
ifm.remove()
})
}
const events = [
......@@ -1591,9 +1703,10 @@ export class RoomStore {
'stream-fallback'
]
const webClient = roomStore.rtcClient as AgoraWebClient;
for (let eventName of events) {
webClient.rtc.off(eventName, () => {});
}
// for (let eventName of events) {
// webClient.rtc.off(eventName, () => {});
// }
webClient.rtc.removeAllListeners();
console.log("[agora-web] rtmClient logout");
await roomStore.rtmClient.logout();
console.log("[agora-web] remove event listener");
......@@ -1614,9 +1727,15 @@ export class RoomStore {
} else {
await this.rtmClient.clearChannelAttributesByKeys([`${this.state.me.uid}`]);
}
try{
await this.rtmClient.logout();
} catch(e) {}
const webClient = roomStore.rtcClient as AgoraWebClient;
setTimeout(()=>{
// alert('clear2')
GlobalStorage.clear('agora_room');
})
await this.removeRtcListener();
// await this.rtcClient.exit();
......
......@@ -284,6 +284,8 @@ class Whiteboard extends EventEmitter {
}
async join({rid, uid, userPayload}: JoinParams) {
console.log(1111111)
console.log(GlobalStorage.read('agora_room'))
await this.leave();
const {uuid, roomToken} = await this.connect(rid, uid);
const identity = userPayload.identity === 'host' ? 'host' : 'guest';
......
......@@ -46,7 +46,7 @@ const clientEvents: string[] = [
export const APP_ID = process.env.REACT_APP_AGORA_APP_ID as string;
export const APP_TOKEN = process.env.REACT_APP_AGORA_APP_TOKEN as string;
export const ENABLE_LOG = process.env.REACT_APP_AGORA_LOG as string === "true";
export const SHARE_ID = 999;
export const SHARE_ID = 9999999999999;
class AgoraRTCClient {
......@@ -178,7 +178,7 @@ class AgoraRTCClient {
}
if (this._localStream ) {
if (this._localStream._enableBeauty) {
this._localStream.setBeautyEffectOptions(false);
// this._localStream.setBeautyEffectOptions(false);
this._localStream._enableBeauty = false
}
}
......@@ -205,12 +205,30 @@ class AgoraRTCClient {
createLocalStream(data: AgoraStreamSpec): Promise<any> {
this._localStream = AgoraRTC.createStream({...data, mirror: false});
this._localStream.setVideoEncoderConfiguration({
// 视频分辨率
resolution: {
width: 160,
height: 120
},
// 视频编码帧率。通常建议是 15 帧,不超过 30 帧
frameRate: {
min: 15,
max: 30
},
// 码率。一般情况下推荐使用标准码率
bitrate: {
min: 100,
max: 150
}
});
return new Promise((resolve, reject) => {
this._localStream.init(async () => {
this.streamID = data.streamID;
this.subscribeLocalStreamEvents();
// debugger
/*if (roomStore.state.me.role == 'teacher') {
/*
if (roomStore.state.me.role == 'teacher') {
const result = await this._localStream.setBeautyEffectOptions(true, {
lighteningContrastLevel: 2,
lighteningLevel: 0.9,
......@@ -221,7 +239,7 @@ class AgoraRTCClient {
// this._enableBeauty = true;
console.log('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%', result)
}*/
this.subscribeLocalStreamEvents();
if (data.audioOutput && data.audioOutput.deviceId) {
this.setAudioOutput(data.audioOutput.deviceId).then(() => {
resolve();
......
......@@ -3,7 +3,7 @@ export class CustomStorage {
private storage: Storage;
constructor() {
this.storage = window.sessionStorage;
this.storage = window.localStorage; // window.sessionStorage;
}
read(key: string): any {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment