news 2026/11/2 23:04:50

Agora Flat v1.0.0-beta.1 功能全景解读:从微信登录、房间管理到课堂回放的完整开源在线教室实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Agora Flat v1.0.0-beta.1 功能全景解读:从微信登录、房间管理到课堂回放的完整开源在线教室实现
  • 音视频
  • 即时通讯
  • 教育
  • 前端
  • 桌面应用

【免费下载链接】flat

Project flat is the Web, Windows and macOS client of Agora Flat open source classroom.

项目地址:https://gitcode.com/gh_mirrors/fl/flat
点击查看免费下载

本篇文章以 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:

  1. 学员举手:onToggleHandRaising 通过rtm.sendPeerCommand("raise-hand", { raiseHand: true })将举手事件点对点发给房主(ownerUUID),并提示"已举手";
  2. 举手状态汇聚:房主侧监听raise-hand事件,维护raiseHandUsers用户列表(L282-L300);
  3. 房主上麦:acceptRaiseHand 校验isCreator后调用onStaging将学员移上舞台(上麦),并同步更新白板共享存储中的onStageUsers;
  4. 统一处理: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
微信登录LoginPageLoginPage/utilsflat-server-api/src/login.ts
创建/加入/预定/周期/历史房间HomePage/MainRoomMenuroom-store.tsflat-server-api/src/room.ts
三种班型课堂BigClass / SmallClass / OneToOne 页面classroom-storeRoomType 枚举
白板 / RTC / RTM课堂页组件flat-stores 课堂 Storeflat-services/services 及 service-providers
举手上麦课堂举手面板classroom-store L1242-L1272RTMraise-hand指令
录制回放ReplayPageclassroom-replay-storeagora-cloud-recording
课件云盘CloudStoragePageupload-task-manager / courseware-convertingflat-services/services/file
设备检测DevicesTestPage全局 Store 偏好IServiceVideoChat 设备接口
自动更新桌面端更新弹窗update-service.tselectron-updater

如果你正打算为 Flat 做二次开发或扩展课堂能力,建议按此地图从flat-services的抽象接口切入:接口层定义了能力边界,service-providers提供具体实现,替换或新增服务提供商即可在不动上层页面的前提下切换底层 SDK,这正是该版本为后续功能迭代打下的架构基础。

  • 音视频
  • 即时通讯
  • 教育
  • 前端
  • 桌面应用

【免费下载链接】flat

Project flat is the Web, Windows and macOS client of Agora Flat open source classroom.

项目地址:https://gitcode.com/gh_mirrors/fl/flat
点击查看免费下载

相关推荐

上一篇:whu-thesis模板的LaTeX底层实现:深入理解文档类设计与源码架构
下一篇:推荐开源项目:Vagga - 开发环境的轻量级容器引擎

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/20 1:51:49

STM32+FPGA双核架构设计与实战:从通信选型到联调排错

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/11/2 23:04:26

OpenCV模板匹配车牌识别:从原理到Python实战的完整毕业设计路线

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/19 20:31:43

RTSPClient拉流实战:从live555编译到海康摄像头接入与排错

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/20 2:12:12

Unet天文图像降噪实战:PyTorch实现与细节解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/20 4:02:52

Linux内核wakeup source框架解析:从唤醒源到系统睡眠管理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华