# 我正在参加「寻声 2.0」征文活动, https://www.rtcdeveloper.cn/cn/community/discussion/57/25892
背景目标
随着AI技术、Web技术和远程视频会议技术的发展,传统的考试场景也有出现了AI智能导题、AI快速出卷、线上学生答题、AI标准化成绩分析等发展方向,从根本上杜绝了泄题漏题的问题。但是,考试作为一个严肃而认真的场合,监考过程还是需要老师人为参与,以保证考试的严肃与公正。那么,老师监考这个场景就需要运用到RTC技术。
设计思路
计划设计考试场景是1名监考老师,对应多名学生的场景,模拟实际的教室考场监考的场景。
- 监考老师:推单路音频流,用于广播通知考试要求,并且可以及时与学生沟通交流;拉多名学生的视频流,用于监督学生行为。为了降低老师的电脑性能和网络带宽要求,平时拉流只拉小分辨率的视频;在1v1交流时,动态更新学生的视频尺寸。
- 考试学生:推单路音视频流,用于被监考。按老师要求,可以推屏幕共享的视频,同时,老师的声音可以传递到学生端,用于1v1 RTC通讯。
老师端
初始化SDK,代码如下:
import { createAgoraRtcEngine } from 'agora-electron-sdk';
const engine = createAgoraRtcEngine();
engine.initialize({
appId,
logConfig: { filePath: Config.SDKLogPath },
channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting,
});
单路音频推流,老师上传1路声音,代码如下:
engine.enableAudio();
engine.joinChannel(token, channelId, uid, {
clientRoleType: ClientRoleType.ClientRoleBroadcaster,
});
多路视频拉流,老师同时拉多名学生的画面,入会后选择小尺寸画面,为了改善多路播放的性能问题:
engine.joinChannel(token, channelId, uid, {
clientRoleType: ClientRoleType.ClientRoleBroadcaster,
});
// onUserJoined 回调入会成功后
engine.setRemoteDefaultVideoStreamType(VideoStreamLow);
engine.setupRemoteVideo(canvas);
单路1v1交流时,老师单独看单个学生画面,画面尺寸变大:
engine.setRemoteVideoStreamType(uid, VideoStreamHigh);
学生端
单路音视频推流,入会上传音视频,代码如下:
engine.joinChannel(token, channelId, uid, {
clientRoleType: ClientRoleType.ClientRoleBroadcaster,
});
engine.enableAudio();
engine.enableVideo();
// 开启视频预览
engine.startPreview();
音频拉流,订阅老师的音频流,不订阅其他学生的音视频,代码如下:
engine.joinChannel(token, channelId, uid, {
clientRoleType: ClientRoleType.ClientRoleBroadcaster,
});
// 取消订阅其他学生的音视频
engine.muteRemoteAudioStream(uid, true);
engine.muteRemoteVideoStream(uid, true);
屏幕共享,代码如下:
// 配置
const sources = engine.getScreenCaptureSources(
{ width: 1920, height: 1080 },
{ width: 64, height: 64 },
true
);
// 采集
this.engine?.startScreenCaptureByDisplayId(
sources.at(0).sourceId,
{},
{
dimensions: { width, height },
frameRate,
bitrate,
captureMouseCursor,
excludeWindowList,
excludeWindowCount: excludeWindowList.length,
highLightWidth,
highLightColor,
enableHighLight,
}
);
// 共享,用uid2和token2实现
engine.joinChannelEx(
token2,
{ channelId, localUid: uid2 },
{
autoSubscribeAudio: false,
autoSubscribeVideo: false,
publishMicrophoneTrack: false,
publishCameraTrack: false,
clientRoleType: ClientRoleType.ClientRoleBroadcaster,
publishScreenTrack: true,
}
);
验证分析
本地通过模拟实现多路预览,观察CPU、内存和网络可以扛得住,基本符合预期。
看SDK内部通过Buffer.alloc提前分配了yuv内存,减少了yuv的拷贝,优化了性能消耗。
最终效果如下
后续开发
增加巡查老师的角色,用于巡查多个考场。
增加学生AI行为分析能力,协助老师及时发现有作弊嫌疑的学生。
增加学生端录制的场景,用于回放归档。
增加转推rtmp直播的能力,便于社会与公众监督。
增加IM接入的能力,便于文字通知和学生留言。