fix(meeting): 优化会议房间学生列表排序和视频播放逻辑
- 重构学生列表排序逻辑,使用更高效的 map 映射和数组排序方法 - 移除冗余的用户遍历和映射操作,提升性能 - 在会议开始时确保获取学生信息列表,添加明确的注释标识 - 改进声网视频播放逻辑,实现立即播放和重试机制 - 添加视频播放失败时的重试逻辑,最多重试10次间隔100ms - 增强视频播放错误处理和调试信息输出
This commit is contained in:
@ -177,24 +177,18 @@
|
|||||||
|
|
||||||
// 按照 studentListForSort 中的顺序重新排列
|
// 按照 studentListForSort 中的顺序重新排列
|
||||||
if (studentListForSort.value.length > 0) {
|
if (studentListForSort.value.length > 0) {
|
||||||
// 创建 shortId -> user 的映射
|
// 创建 shortId -> student 的映射 (用于排序)
|
||||||
const userMap = new Map<number, typeof filteredUsers[0]>();
|
const studentOrderMap = new Map<number, number>();
|
||||||
filteredUsers.forEach((user) => {
|
studentListForSort.value.forEach((student, index) => {
|
||||||
userMap.set(Number(user.uid), user);
|
studentOrderMap.set(student.shortId, index);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 按照 studentListForSort 的顺序重新排列
|
// 按照 studentListForSort 的顺序排序,但只包含实际存在的用户
|
||||||
const sortedUsers: typeof filteredUsers = [];
|
return [...filteredUsers].sort((a, b) => {
|
||||||
studentListForSort.value.forEach((student) => {
|
const aIndex = studentOrderMap.get(Number(a.uid)) ?? Number.MAX_SAFE_INTEGER;
|
||||||
const user = userMap.get(student.shortId);
|
const bIndex = studentOrderMap.get(Number(b.uid)) ?? Number.MAX_SAFE_INTEGER;
|
||||||
if (user) {
|
return aIndex - bIndex;
|
||||||
sortedUsers.push(user);
|
|
||||||
userMap.delete(student.shortId);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 添加 studentListForSort 中没有的用户 (新加入的学生)
|
|
||||||
return [...sortedUsers, ...Array.from(userMap.values())];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return filteredUsers;
|
return filteredUsers;
|
||||||
@ -371,7 +365,8 @@
|
|||||||
if (classStatus.value === 'in_class') {
|
if (classStatus.value === 'in_class') {
|
||||||
console.log('[监控端] 课程已开始,初始化 Agora...');
|
console.log('[监控端] 课程已开始,初始化 Agora...');
|
||||||
await meeting.initAndJoin(roomData);
|
await meeting.initAndJoin(roomData);
|
||||||
// 获取学生信息列表
|
|
||||||
|
// ✅ 获取学生信息列表
|
||||||
await fetchStudentList();
|
await fetchStudentList();
|
||||||
} else {
|
} else {
|
||||||
console.log('[监控端] 等待老师上课...');
|
console.log('[监控端] 等待老师上课...');
|
||||||
@ -433,6 +428,8 @@
|
|||||||
shortUid.value = roomData.shortUid;
|
shortUid.value = roomData.shortUid;
|
||||||
teacherUid.value = roomData.teacherUid;
|
teacherUid.value = roomData.teacherUid;
|
||||||
await meeting.initAndJoin(roomData);
|
await meeting.initAndJoin(roomData);
|
||||||
|
|
||||||
|
// ✅ 获取学生信息列表
|
||||||
await fetchStudentList();
|
await fetchStudentList();
|
||||||
console.log('[监控端] Agora 初始化完成');
|
console.log('[监控端] Agora 初始化完成');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@ -225,9 +225,11 @@ export function useAgoraMeeting(
|
|||||||
*/
|
*/
|
||||||
const playRemoteVideo = (user: IAgoraRTCRemoteUser, playerId: string) => {
|
const playRemoteVideo = (user: IAgoraRTCRemoteUser, playerId: string) => {
|
||||||
console.log(`【声网】准备播放远程视频 ${playerId}:`, user.uid);
|
console.log(`【声网】准备播放远程视频 ${playerId}:`, user.uid);
|
||||||
setTimeout(() => {
|
|
||||||
|
// 立即尝试播放
|
||||||
|
const tryPlay = (retryCount = 0) => {
|
||||||
const playerDiv = document.getElementById(playerId);
|
const playerDiv = document.getElementById(playerId);
|
||||||
console.log('【声网】视频播放元素:', playerDiv, 'videoTrack:', user.videoTrack);
|
console.log('【声网】视频播放元素:', playerDiv, 'videoTrack:', user.videoTrack, '重试次数:', retryCount);
|
||||||
if (playerDiv && user.videoTrack) {
|
if (playerDiv && user.videoTrack) {
|
||||||
try {
|
try {
|
||||||
user.videoTrack.play(playerDiv);
|
user.videoTrack.play(playerDiv);
|
||||||
@ -236,9 +238,17 @@ export function useAgoraMeeting(
|
|||||||
console.warn('【声网】远程视频播放异常:', error);
|
console.warn('【声网】远程视频播放异常:', error);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.warn('【声网】视频播放失败:元素或轨道不存在');
|
// 如果元素不存在,延迟 100ms 重试,最多重试 10 次
|
||||||
|
if (retryCount < 10) {
|
||||||
|
console.warn(`【声网】视频播放失败:元素或轨道不存在,100ms 后重试 (${retryCount + 1}/10)`);
|
||||||
|
setTimeout(() => tryPlay(retryCount + 1), 100);
|
||||||
|
} else {
|
||||||
|
console.error('【声网】视频播放失败:超过最大重试次数');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, 100);
|
};
|
||||||
|
|
||||||
|
tryPlay();
|
||||||
};
|
};
|
||||||
|
|
||||||
client.value.on('user-published', async (user: IAgoraRTCRemoteUser, mediaType: 'audio' | 'video') => {
|
client.value.on('user-published', async (user: IAgoraRTCRemoteUser, mediaType: 'audio' | 'video') => {
|
||||||
|
|||||||
Reference in New Issue
Block a user