fix(meeting): 优化会议房间学生列表排序和视频播放逻辑

- 重构学生列表排序逻辑,使用更高效的 map 映射和数组排序方法
- 移除冗余的用户遍历和映射操作,提升性能
- 在会议开始时确保获取学生信息列表,添加明确的注释标识
- 改进声网视频播放逻辑,实现立即播放和重试机制
- 添加视频播放失败时的重试逻辑,最多重试10次间隔100ms
- 增强视频播放错误处理和调试信息输出
This commit is contained in:
2026-03-14 22:54:39 +08:00
parent 525281e3f8
commit 50532079cf
2 changed files with 27 additions and 20 deletions

View File

@ -177,24 +177,18 @@
// 按照 studentListForSort 中的顺序重新排列
if (studentListForSort.value.length > 0) {
// 创建 shortId -> user 的映射
const userMap = new Map<number, typeof filteredUsers[0]>();
filteredUsers.forEach((user) => {
userMap.set(Number(user.uid), user);
// 创建 shortId -> student 的映射 (用于排序)
const studentOrderMap = new Map<number, number>();
studentListForSort.value.forEach((student, index) => {
studentOrderMap.set(student.shortId, index);
});
// 按照 studentListForSort 的顺序重新排列
const sortedUsers: typeof filteredUsers = [];
studentListForSort.value.forEach((student) => {
const user = userMap.get(student.shortId);
if (user) {
sortedUsers.push(user);
userMap.delete(student.shortId);
}
// 按照 studentListForSort 的顺序排序,但只包含实际存在的用户
return [...filteredUsers].sort((a, b) => {
const aIndex = studentOrderMap.get(Number(a.uid)) ?? Number.MAX_SAFE_INTEGER;
const bIndex = studentOrderMap.get(Number(b.uid)) ?? Number.MAX_SAFE_INTEGER;
return aIndex - bIndex;
});
// 添加 studentListForSort 中没有的用户 (新加入的学生)
return [...sortedUsers, ...Array.from(userMap.values())];
}
return filteredUsers;
@ -371,7 +365,8 @@
if (classStatus.value === 'in_class') {
console.log('[监控端] 课程已开始,初始化 Agora...');
await meeting.initAndJoin(roomData);
// 获取学生信息列表
// ✅ 获取学生信息列表
await fetchStudentList();
} else {
console.log('[监控端] 等待老师上课...');
@ -433,6 +428,8 @@
shortUid.value = roomData.shortUid;
teacherUid.value = roomData.teacherUid;
await meeting.initAndJoin(roomData);
// ✅ 获取学生信息列表
await fetchStudentList();
console.log('[监控端] Agora 初始化完成');
} catch (error) {

View File

@ -225,9 +225,11 @@ export function useAgoraMeeting(
*/
const playRemoteVideo = (user: IAgoraRTCRemoteUser, playerId: string) => {
console.log(`【声网】准备播放远程视频 ${playerId}:`, user.uid);
setTimeout(() => {
// 立即尝试播放
const tryPlay = (retryCount = 0) => {
const playerDiv = document.getElementById(playerId);
console.log('【声网】视频播放元素:', playerDiv, 'videoTrack:', user.videoTrack);
console.log('【声网】视频播放元素:', playerDiv, 'videoTrack:', user.videoTrack, '重试次数:', retryCount);
if (playerDiv && user.videoTrack) {
try {
user.videoTrack.play(playerDiv);
@ -236,9 +238,17 @@ export function useAgoraMeeting(
console.warn('【声网】远程视频播放异常:', error);
}
} 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') => {