- 音视频
- 即时通讯
- 教育
- 前端
- 桌面应用
【免费下载链接】flat
Project flat is the Web, Windows and macOS client of Agora Flat open source classroom.
本篇文章以 Agora Flat 开源教室客户端的首个公测版本 v1.0.0-beta.1 发布说明 为核心骨架,逐项拆解该版本交付的 21 项核心能力:微信登录、房间管理、三种课堂场景、实时互动、录制回放、课件云盘、设备检测与自动更新。结合仓库内真实源码,你将理解每项功能在前端页面、状态管理(MobX Store)与服务抽象层(flat-services)中的落点,掌握从"登录 → 建课 → 上课 → 回放"的完整技术链路,可作为阅读本项目源码与二次开发的地图。
一、版本背景:第一个面向公测的功能基线
根据仓库根目录的项目描述,Agora Flat 是面向 Web、Windows 与 macOS 三端发布的在线教室客户端。v1.0.0-beta.1 是其版本历史上第一个 beta 发布,标志着项目从内部联调走向公测:登录、房间全生命周期管理、多班型课堂、实时互动与课后回放等主干功能在这一版集中成形。
该版本发布说明以功能清单形式列出 21 项能力,可归纳为五个技术域,下文将逐一结合源码展开:
| 技术域 | 覆盖功能(对应发布说明条目) |
|---|---|
| 账号与登录 | 微信登录 |
| 房间管理 | 房间管理;加入、创建、预定房间;周期性房间;查看历史房间 |
| 课堂场景 | 多场景课堂:大班课、小班课、一对一 |
| 实时互动 | 实时交互;多功能互动白板;RTC 音视频;RTM 即时消息;举手上麦发言 |
| 课后闭环 | 课堂录制回放;白板信令回放;音视频云录制回放;群聊信令回放;多媒体课件云盘 |
| 运行保障 | 设备检测;自动检查更新 |
二、账号登录:微信扫码登录
发布说明的第一项能力是"微信登录"。仓库中对应的实现位于 packages/flat-pages/src/LoginPage/WeChatLogin.tsx,它以二维码扫码方式完成登录(组件对外暴露onLoginResult回调),并在 登录页 通过renderQRCode插槽集成:
renderQRCode={() => <WeChatLogin onLoginResult={onLoginResult} />}同一目录还提供了 githubLogin.ts 与 googleLogin.ts 两种登录执行器,它们与微信登录一起在 state.ts 中被按需分发调用。从源码结构看,登录方式采用"登录执行器 + 登录结果回调"的可扩展设计:后续新增第三方登录只需补充新的LoginExecutor实现。登录态信息随后由flat-server-api的login.ts与用户 Store 统一管理,支撑后续所有房间操作。
三、房间管理:创建、加入与预定
"房间管理"与"加入、创建、预定房间"是 beta.1 的核心业务。客户端首页 MainRoomMenu 以三栏布局(加入房间、创建房间、预定房间)呈现三个入口,对应三个交互组件:JoinRoomBox、CreateRoomBox、ScheduleRoomBox。
底层 API 集中在 packages/flat-server-api/src/room.ts,其调用关系清晰可查:
- 创建房间:createOrdinaryRoom 向
room/create/ordinary提交{ title, type, beginTime, region, pmi? },服务端返回roomUUID与inviteCode(邀请码); - 预定房间:与创建共用同一接口,只是
beginTime为未来时间点; - 加入房间:joinRoom 向
room/join提交uuid(兼容 roomUUID / inviteCode / periodicUUID),一次返回白板房间与 Token、RTC UID 与 Token、屏幕共享 RTC 参数、RTM Token 等全套进房凭证; - 房间列表:listRooms 按
room/list/:type?page=分页拉取; - 取消房间:cancelRoom 根据入参组合分发到"整期取消周期课 / 取消周期课单节 / 取消历史房间 / 取消单次房间"四种内部实现;
- 更新房间:
updateOrdinaryRoom/updatePeriodicRoom/updatePeriodicSubRoom分别对应三类更新场景。
客户端侧的 RoomStore 封装了createOrdinaryRoom与createPeriodicRoom,创建成功后把房间信息写入本地 Store 缓存,并调用preferencesStore.setRegion记录用户常用的服务区域(如cn-hz、us-sv、sg)。
进房前的设备检测拦截
值得注意的细节是:加入房间并不总是直接进课堂。MainRoomMenu 的onJoinRoom逻辑显示,当用户处于 Web 端且未关闭设备检测(globalStore.isTurnOffDeviceTest为 false)时,会先跳转到设备检测页,通过后再由 join-room-handler 完成进房。这条链路正是"设备检测"功能与房间流程的集成点。
四、周期性房间与历史房间
发布说明单独列出"支持周期性房间"与"查看历史房间"两项,可见其在教学场景中的重要性。
周期性房间
周期性房间的创建载荷定义在 room.ts,支持两种排期模型:
periodic: | { weeks: Week[]; rate: number } // 每周按星期重复 | { weeks: Week[]; endTime: number }; // 指定截止时间的重复其中weeks取值来自 Week 枚举(周日到周六)。服务端还会为周期课生成独立的periodicUUID,客户端通过 periodicRoomInfo 拉取整期课表,通过 periodicSubRoomInfo 查看单节课并获取前后相邻课次时间,用于详情页展示。单节周期课的取消/改期则走cancelPeriodicSubRoom/updatePeriodicSubRoom。
历史房间
房间列表类型由 ListRoomsType 枚举 定义,分为All(全部)、Today(今日)、Periodic(周期课)、History(历史)四类。历史房间面板 MainRoomHistoryPanel 在滚动到底部时触发roomStore.fetchMoreRooms(ListRoomsType.History)做分页加载,配合 room-store.ts 中的防重入(isFetchingRooms)与单页大小控制,形成滚动加载的完整闭环。历史房间同时是进入"录制回放"的入口。
五、多场景课堂:大班课、小班课与一对一
"多场景课堂"由三种班型构成,其类型定义集中在 RoomType 枚举:
export enum RoomType { OneToOne = "OneToOne", SmallClass = "SmallClass", BigClass = "BigClass", }该枚举贯穿创建房间载荷、房间信息、进房结果等多个 API 契约,并驱动 flat-pages 下的BigClassPage、SmallClassPage、OneToOnePage三个独立课堂页面进行路由分发。从页面结构与课堂 Store 的实现看,三种班型的差异主要体现在参会人数上限、互动权限策略(如是否全员开麦、举手发言的调度方式)等维度,而底层白板、RTC、RTM 基础设施是三端共享的。
六、实时交互:互动白板、RTC 音视频与 RTM 即时消息
"实时交互"是课堂的引擎,它由三块服务能力组合而成。项目将它们统一抽象为可替换的服务接口层,位于 packages/flat-services/src/services:
多功能互动白板(IServiceWhiteboard)
IServiceWhiteboard 提供白板房间的创建与加入能力;具体实现依赖 fastboard SDK(见 service-providers/fastboard),支撑画笔、图形、课件展示等"多功能"交互。
实时音视频(IServiceVideoChat)
IServiceVideoChat 是 RTC 能力的抽象,接口清单直接对应课堂内的音视频诉求:
- 进房/离房:
joinRoom/leaveRoom; - 角色与头像:
setRole/getAvatar/getTestAvatar(设备检测用测试头像); - 音量监控:
getVolumeLevel; - 设备管理:
setCameraID/setMicID/setSpeakerID与对应的设备枚举方法,是"设备检测"页的数据源。
桌面端与 Web 端分别由 agora-rtc-electron 与 agora-rtc-web 提供实现。
即时消息(IServiceTextChat)
IServiceTextChat 抽象了 RTM 聊天能力:sendRoomMessage群发消息、sendPeerMessage私聊、sendRoomCommand/sendPeerCommand发送指令消息。其中指令通道正是"举手上麦"的底层载体。
七、举手上麦发言:指令驱动的互动闭环
"举手上麦发言"在课堂 Store 中是一套完整的指令闭环,实现在 packages/flat-stores/src/classroom-store/index.ts:
- 学员举手:onToggleHandRaising 通过
rtm.sendPeerCommand("raise-hand", { raiseHand: true })将举手事件点对点发给房主(ownerUUID),并提示"已举手"; - 举手状态汇聚:房主侧监听
raise-hand事件,维护raiseHandUsers用户列表(L282-L300); - 房主上麦:acceptRaiseHand 校验
isCreator后调用onStaging将学员移上舞台(上麦),并同步更新白板共享存储中的onStageUsers; - 统一处理:onCancelAllHandRaising 一键清空举手列表;打开举手面板时通过
flushLazyUsers拉取举手学员的完整资料。
值得注意的是举手状态通过classroomStorage(白板 syncedStore)在多端之间同步,因此同一课堂内的所有客户端都能实时看到举手列表变化。
八、课堂录制与回放:白板信令、音视频云录制与群聊信令
回放是 beta.1 中最具工程含量的一环。发布说明将其细分为"课堂录制回放 / 白板信令回放 / 音视频云录制回放 / 群聊信令回放",对应仓库中的 classroom-replay-store 与 ReplayPage。
多轨同步播放器
回放的核心是多路时间轨的同步。classroom-replay-store/index.ts 展示了完整的装配过程:
- 白板轨:通过
replayFastboard按beginTimestamp + duration载入白板信令回放,并连接onStageUsers同步存储以还原上麦状态; - 视频轨:若录制包含
videoURL,则创建NativeVideoPlayer播放云端音视频录制; - 同步调度:两类播放器统一交给
SyncPlayer({ players })做多轨时钟同步,实现"白板笔迹与教师音视频画面逐帧对齐"。
页面层 ReplayPage 将ReplayVideo(视频区)、ReplayWhiteboard(白板区)与ReplayList(回放控制列表)组装为完整回放界面;桌面端还可通过x-agora-flat-client://replayRoom?roomUUID=...&ownerUUID=...&roomType=...协议唤起客户端回放(L32-L35)。
云录制与回放服务
录制能力由两个层面支撑:
- 服务端侧:声网云录制集成位于 service-providers/agora-cloud-recording/src/cloud-recording.ts,负责把课堂音视频写入云端;
- 客户端侧:IServiceRecording 抽象了
startRecording/stopRecording/checkIsRecording等录制控制与状态查询接口,房主可随时开始/停止录制。
"群聊信令回放"则依赖聊天消息记录与上述多轨同步框架,在回放时间轴上还原课堂中的群聊内容。
九、多媒体课件云盘
"多媒体课件云盘"提供课件的上传、管理与课堂内插入能力。客户端入口为 CloudStoragePanel,底层服务定义在 packages/flat-services/src/services/file,并配套两套工具链:
- upload-task-manager:断点续传式的上传任务调度;
- courseware-converting:课件转码状态管理,配合 file-convert-h5 与 file-convert-netless 服务,将 PPT/PDF 等课件转换为可在白板中展示的格式,完成"云盘 → 转码 → 课堂插入"的完整链路。
十、设备检测与自动检查更新
设备检测
DevicesTestPage 在进房前对摄像头、麦克风、扬声器三路设备做检测:通过getCameraDevices/getMicDevices/getSpeakerDevices(RTC 服务提供)枚举设备,并支持切换设备 ID 与音量自测(L106-L131)。用户可选择"关闭设备检测直接进房"(isTurnOffDeviceTest),该偏好由全局 Store 持久化。桌面端由于 Electron 环境进房链路可靠,可跳过该页(见上文onJoinRoom判断)。
自动检查更新
桌面端的自动更新由 electron-updater 驱动,实现在 desktop/main-app/src/utils/update-service.ts:
- 检查更新:
check()设置autoDownload = false,仅探测最新版本并通过事件回调update-available/update-not-available通知界面(L10-L66); - 执行更新:
update()开启autoDownload,监听download-progress上报进度、update-downloaded后调用quitAndInstall完成安装重启(L68-L135); - 版本源配置:
setFeedURL将更新源指向${UPDATE_DOMAIN}/latest/${prereleaseTag}/${osName},按平台与预发布标签区分更新通道(L137-L148),这是 beta 版能够"自动检查更新"的基础设施。
十一、总结:beta.1 功能源码地图
v1.0.0-beta.1 的 21 项功能并非孤立特性,而是一条贯穿"登录 → 建课 → 上课 → 回放"的完整产品链路,其工程落点可归纳如下:
| 功能域 | 前端页面 | 业务逻辑 | 服务/API |
|---|---|---|---|
| 微信登录 | LoginPage | LoginPage/utils | flat-server-api/src/login.ts |
| 创建/加入/预定/周期/历史房间 | HomePage/MainRoomMenu | room-store.ts | flat-server-api/src/room.ts |
| 三种班型课堂 | BigClass / SmallClass / OneToOne 页面 | classroom-store | RoomType 枚举 |
| 白板 / RTC / RTM | 课堂页组件 | flat-stores 课堂 Store | flat-services/services 及 service-providers |
| 举手上麦 | 课堂举手面板 | classroom-store L1242-L1272 | RTMraise-hand指令 |
| 录制回放 | ReplayPage | classroom-replay-store | agora-cloud-recording |
| 课件云盘 | CloudStoragePage | upload-task-manager / courseware-converting | flat-services/services/file |
| 设备检测 | DevicesTestPage | 全局 Store 偏好 | IServiceVideoChat 设备接口 |
| 自动更新 | 桌面端更新弹窗 | update-service.ts | electron-updater |
如果你正打算为 Flat 做二次开发或扩展课堂能力,建议按此地图从flat-services的抽象接口切入:接口层定义了能力边界,service-providers提供具体实现,替换或新增服务提供商即可在不动上层页面的前提下切换底层 SDK,这正是该版本为后续功能迭代打下的架构基础。
- 音视频
- 即时通讯
- 教育
- 前端
- 桌面应用
【免费下载链接】flat
Project flat is the Web, Windows and macOS client of Agora Flat open source classroom.
相关推荐
Agora Flat v1.0.0-beta.1 功能解析:开源在线课堂首个 Beta 里程碑
Agora Flat v1.0.0 beta.1 功能解析:开源在线课堂首个 Beta 里程碑 Agora Flat 是声网推出的开源在线互动教室客户端,覆盖
音视频即时通讯教育前端桌面应用Agora Flat v1.0.0-beta.5 版本解析:房间类型 UI 重构与课堂稳定性修复
Agora Flat v1.0.0 beta.5 版本解析:房间类型 UI 重构与课堂稳定性修复 Agora Flat 是声网开源的跨平台在线互动课堂客户端,支
音视频即时通讯教育前端桌面应用Agora Flat v1.6.0 版本全解析:课件无感切换、Agora 登录与回放交互升级
Agora Flat v1.6.0 版本全解析:课件无感切换、Agora 登录与回放交互升级 本文以 Agora Flat 开源教室项目 v1.6.0 版本的官
音视频即时通讯教育前端桌面应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考