No description
  • TypeScript 68.1%
  • Go 27.3%
  • CSS 3.5%
  • Python 0.8%
  • JavaScript 0.2%
  • Other 0.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-11-05 16:02:02 +08:00
cmd/e2e Exercise isolated server restart on Windows and Linux 2026-10-03 10:20:40 +08:00
demo feat(demo): group admin navigation and add collapsible themed interface 2026-11-02 09:44:56 +08:00
deploy fix: archive previous frontend after atomic release exchange 2026-11-02 11:09:05 +08:00
docs docs: record admin E2EE permission release and verification 2026-11-03 23:05:23 +08:00
frontend Redesign responsive Hola workspace and meeting controls 2026-11-05 16:02:02 +08:00
.env.example feat: add durable messaging and memory-only E2EE chats 2026-11-05 14:30:14 +08:00
.gitattributes feat: implement Hola 2.0 workspace and meeting controls 2026-11-02 10:51:39 +08:00
.gitignore Implement Go backend with persistent rooms and media moderation 2026-10-03 09:30:01 +08:00
chat_objects.go feat: add durable messaging and memory-only E2EE chats 2026-11-05 14:30:14 +08:00
chat_temporary.go feat: add durable messaging and memory-only E2EE chats 2026-11-05 14:30:14 +08:00
codec_compatibility.go Add per-camera device matrix and H265 with moderator-controlled codecs 2026-10-04 07:52:40 +08:00
control_flow_test.go Confirm media policies before SFU admission and simplify meeting controls 2026-10-05 02:12:19 +08:00
database.go feat: add durable messaging and memory-only E2EE chats 2026-11-05 14:30:14 +08:00
device_scans.go feat: implement Hola 2.0 workspace and meeting controls 2026-11-02 10:51:39 +08:00
device_scans_test.go feat: implement Hola 2.0 workspace and meeting controls 2026-11-02 10:51:39 +08:00
e2ee.go feat: deliver E2EE media with verified devices and rotating epochs 2026-11-02 22:03:38 +08:00
e2ee_test.go feat: restrict E2EE creation to admins and remove raised hands 2026-11-03 23:03:03 +08:00
go.mod feat: add durable messaging and memory-only E2EE chats 2026-11-05 14:30:14 +08:00
go.sum feat: add durable messaging and memory-only E2EE chats 2026-11-05 14:30:14 +08:00
HANDOFF.md docs: record admin E2EE permission release and verification 2026-11-03 23:05:23 +08:00
http.go feat: add durable messaging and memory-only E2EE chats 2026-11-05 14:30:14 +08:00
ice_diagnostics.go Add correlated media and server diagnostics; preserve resolution during network FPS adaptation 2026-10-04 06:35:51 +08:00
logging.go feat: deliver E2EE media with verified devices and rotating epochs 2026-11-02 22:03:38 +08:00
main.go feat: add durable messaging and memory-only E2EE chats 2026-11-05 14:30:14 +08:00
maintenance.go feat: add durable messaging and memory-only E2EE chats 2026-11-05 14:30:14 +08:00
media.go feat: enforce E2EE admission and coordinated media key epochs 2026-11-02 21:02:17 +08:00
media_actions.go Confirm media policies before SFU admission and simplify meeting controls 2026-10-05 02:12:19 +08:00
media_actions_test.go Document the control-first flow and verify durable sync after reload 2026-10-05 02:22:48 +08:00
meeting_policy.go feat: enforce E2EE admission and coordinated media key epochs 2026-11-02 21:02:17 +08:00
meeting_policy_test.go feat: implement Hola 2.0 workspace and meeting controls 2026-11-02 10:51:39 +08:00
messaging.go feat: add durable messaging and memory-only E2EE chats 2026-11-05 14:30:14 +08:00
messaging_test.go feat: add durable messaging and memory-only E2EE chats 2026-11-05 14:30:14 +08:00
permissions.go feat: restrict E2EE creation to admins and remove raised hands 2026-11-03 23:03:03 +08:00
permissions_test.go Restrict codec reports to moderators and decouple meeting audio from video layout 2026-10-05 01:40:49 +08:00
README.md feat: add durable messaging and memory-only E2EE chats 2026-11-05 14:30:14 +08:00
reception.go Report real decode failures and detect paced hardware video sending 2026-10-04 23:36:38 +08:00
reception_test.go Report real decode failures and detect paced hardware video sending 2026-10-04 23:36:38 +08:00
rooms.go feat: restrict E2EE creation to admins and remove raised hands 2026-11-03 23:03:03 +08:00
server_diagnostics.go Add correlated media and server diagnostics; preserve resolution during network FPS adaptation 2026-10-04 06:35:51 +08:00
server_diagnostics_test.go Add per-camera device matrix and H265 with moderator-controlled codecs 2026-10-04 07:52:40 +08:00
server_test.go feat: enforce E2EE admission and coordinated media key epochs 2026-11-02 21:02:17 +08:00
start.sh Remove Python and P2P paths; add browser recovery and isolated Go test runner 2026-10-03 09:44:08 +08:00
V2-PLAN.md docs: record Hola 2.0 deployment and public audio video verification 2026-11-02 11:16:37 +08:00
v2.go feat: deliver E2EE media with verified devices and rotating epochs 2026-11-02 22:03:38 +08:00
v2_test.go feat: implement Hola 2.0 workspace and meeting controls 2026-11-02 10:51:39 +08:00
websocket.go feat: restrict E2EE creation to admins and remove raised hands 2026-11-03 23:03:03 +08:00

Hola 2.1 私人会议

Hola 是面向个人使用的 Web 视频会议,采用 Go、React/TypeScript、SQLite 和 LiveKit。服务器只转发媒体,不进行转码。

  • 入口:meet.cloverdo.cn
  • 仓库:Cloverdo/Hola,开发分支 dev
  • 本次更新:2026-11-03;实际发布版本、验证结果与备份路径见 HANDOFF.md
  • 部署方式:Linux 宿主机 + systemd,暂不使用 Docker;暂不开发 Android APP

聊天模块

消息和会议共用账号与导航。普通单聊、群聊、好友关系和历史保存在 SQLite,普通附件经后端流式转发到私有 S3,单文件最多 200 MiB。配置项见 .env.example,S3 地址必须可从运行 Go 服务的主机访问。

管理员可邀请成员创建 1 小时的临时 E2EE 房。首版每房最多 8 人,内容预算 200 MiB,其中为文字保留 2 MiB。所有临时房状态、密文和封装恢复材料仅驻内存。新设备需核对安全码,刷新可由获准设备协助,或在浏览器本地输入恢复码。到期、结束或进程重启清理房间。

新功能的隔离浏览器回归使用 playwright.messaging.config.ts。真实对象存储回归可在配置 S3 环境变量后运行 HOLA_TEST_RUSTFS=1 go test -run TestMessagingFriendsGroupPermissionsAndAttachments,测试创建并清理独立的测试对象。

2.1.2 E2EE 发起权限

仅平台账号管理员可创建 E2EE 会议,普通用户可通过设备检查和安全码批准后加入。前后端同步限制;主持人、联席身份不会额外获得发起权限。移除会议举手按钮、成员标记及消息处理。

2.1.1 统一开关

所有原勾选框统一为胶囊开关,包括创建会议的 E2EE、私密会议、设备安全码核对和管理员身份设置;支持禁用、键盘操作与亮暗主题。沿用原有权限和确认规则。验证见 QA-2.1.1.md。

2.1.0 E2EE

管理员创建会议时可选 E2EE,默认 H.265,可手动改为 H.264;不支持 AV1。设备检查会静默预检浏览器、Worker 和 Web Crypto,不额外申请摄像头或麦克风权限。只有通过预检且支持所选视频方案的设备能创建或加入 E2EE 会议,不提供邀请链接。

首次加入需要双方通过可信渠道核对 E2EE 安全码,再由主持人或联席主持人的主设备批准。摄像头、麦克风、共享画面与共享声音使用 E2EE,服务器仅转发;名单、文字聊天及控制消息仍由服务器处理。支持状态可以从会中顶栏 E2EE 面板查看。

每分钟、设备成员变化、主持控制权转移或手动点击“立即更新 E2EE”时,生成新的随机媒体材料。更新未完成时暂停媒体,不回退普通传输。设备身份保存在本站 IndexedDB 中,为不可导出的 Web Crypto 私钥,有效期144小时;清除站点数据、换浏览器或过期后需要重新核对。刷新页面可恢复仍有效的同一设备身份。

实现与使用边界见 E2EE.md,验证记录见 QA-2.1.0.md。

2.0.2 会议操作与布局

主持人离会时可选择仅离开当前设备或结束整个会议;会议管理结束操作增加确认。每个视频及预览均有视频信息、旋转、全屏操作。全屏顶栏依次为设备设置、视频信息、画面旋转、切换摄像头、退出全屏;摄像头选择使用单行布局,无备用摄像头时保留禁用按钮。用户管理保留自己账号的灰色停用按钮。首页会议与个人会议卡片等高对齐,三个快捷入口改为较矮的横向按钮。

2.0.1 界面修复

修复自测报告A1–A12并完成B1–B4:控件状态、长标题与窄屏、原会议入口、旋转完整适配、聊天跟随及新消息提示、顶栏提示避让、横屏主视角、弹窗层级、字段分组、重复日程日期和非法日期校验。手机月历使用预约数量,直播人数与设备数区分显示,时长格式统一。

全屏设备设置按需展开,快捷切换摄像头保留;视频信息与设备设置互斥展开。手机横屏采用主画面加侧边滚动预览。

浏览器界面回归:npm run test:ui,使用下方同名HOLA_V2环境变量;测试文件为 frontend/tests/ui-regressions.spec.ts。测试需使用隔离账号/环境,会创建临时会议与预约。

2.0 的变化

  • 采用已确认 Demo 的 Hola 界面,支持亮色/暗色、收起侧边栏与手机导航。
  • 个人空间包含会议大厅、日历日程、本人参与的历史会议;管理员的用户管理、会议管理独立分组。
  • 设备、能力、诊断收进设置;会中成员、聊天、视频统计按需打开,再次点击收起。
  • 下拉选择、确认、弹窗使用应用组件;弹窗四角保留圆角,内容可滚动但不显示滚动条。摄像头授权、系统共享来源和文件选择仍由浏览器/系统管理。
  • 日历预约支持每日/每周重复、编辑、取消、复制预约信息及发起会议。预约不是提前开启的媒体房间,参会链接在实际会议中生成。
  • 历史只展示本人发起或参与的会议,支持搜索、分页、个人备注、收藏和再次发起。备注、收藏和日程按账号隔离。
  • 会议中生成邀请链接;已有账号登录后准备入会,无需再输入房间码和会议密码。链接绑定本次会议,结束或超时后失效,不授予主持权限。
  • 会中聊天最多保留100条,每条最多1000字;只在当前进程内保存,服务重启后清除。
  • 管理员可查看所有进行中的会议,包括私密会议,并一键结束;不自动获得会议主持或设备详情权限。
  • 所有会议单次最长24小时,从创建开始计时,重新加入或重启服务不重置;空房间仍在30分钟后结束。

控制与媒体链路

flowchart LR
  A[登录并上报浏览器能力] --> B[Go 校验账号和会议规则]
  B --> C[WebSocket 下发角色和带版本的媒体策略]
  C --> D[确认规则后申请 SFU 凭证]
  D --> E[按需采集并经 LiveKit 转发]
  E --> F[反馈实际编码与收发状态]

规则、权限、能力和执行反馈走业务接口与 WebSocket。业务状态及待同步媒体操作在同一 SQLite 事务保存,媒体调用在锁外执行;失败可重试,重启后继续处理。权限集中在 permissions.go 与 meeting_policy.go。平台账号管理员、会议主持人、联席主持人和普通成员分别授权。

同一账号可从多台设备加入并选择主设备。主持人/联席的设备管理与高画质资格随主设备转移;普通成员设置主设备不会增加权限。完整能力和兼容性汇总仅向有权限的主持/联席主设备下发,撤销角色后同步收回。

视频与设备规则

项目 当前方案
编码 H.264、H.265、AV1;不支持 VP9,无自动换码或备用编码流
默认 1080p、30帧、H.264;可保存个人创建会议预设,加入已有会议服从主持人方案
摄像头 720p、1080p、2K(2560×1440),目标30/60帧
2K资格 仅主持人、联席主持人的主设备
其他设备 最高1080p60,不再因超过5台设备自动限制720p
网络调节 仅降低发送帧率,最低15帧;保留分辨率,恢复后尝试回到目标帧率
屏幕共享 独立配置720p/1080p/2K/4K、30/60帧与三种编码,最高4K60
实际性能 受摄像头、浏览器、编解码实现和网络影响,目标不等于保证持续达到的性能

首次登录只读取浏览器声明的编解码能力和可枚举设备,不自动打开摄像头、不再运行完整档位排列扫描。能力按账号与浏览器实例缓存 144小时,可从云端恢复,也可手动更新。浏览器标识是本站生成的随机UUID,不是硬件序列号。能力未知时允许音频入会,视频保持关闭。

实际打开摄像头时校验所选采集档位与发布编码;H.265/AV1 的浏览器声明不保证跨设备实际解码。收到数据却解码失败会提示主持/联席手动调整,系统不会自动切换会议编码。CPU型号不能代替浏览器真实媒体链路验证。

PC支持网格/主视角,手机为主画面加可滚动预览;个人选看与主持的一次主画面通知分开。只有一台设备时显示灰色加号,达到两台即隐藏。摄像头竖屏内容仍置于横向预览;全屏另行适配。音频播放独立于视频布局,隐藏的视频可按兴趣暂停订阅。

构建与测试

Go版本要求见 go.mod,前端使用支持当前 Vite 的 Node。直接依赖已固定版本,使用提交的 package-lock.json 安装。

cd frontend
npm ci
npm run check
npm test
npm run build
cd ..
go test ./...
go build -buildvcs=false -ldflags "-X main.version=YOUR_COMMIT" -o bin/hola .

浏览器回归需要独立 Go + LiveKit 实例,环境变量 HOLA_V2_URL、HOLA_V2_USER、HOLA_V2_PASSWORD,Chrome路径可用 HOLA_CHROME_PATH 指定:

cd frontend
npx playwright test --config playwright.v2.config.ts
npx playwright test --config playwright.e2ee.config.ts

测试会创建专用日程、测试账号和测试会议,请在隔离环境运行。虚拟摄像头/共享源验证收发与解码链路,不能代替安卓真机性能与持续帧率验收。

部署与回滚

私密配置放在服务器 .env,参照 .env.example。反向代理指向9009;媒体配置与UDP端口需保持一致。start.sh 和 hola.service 管理进程,应用发布仅重启 Go,不重启 LiveKit。

2.0 数据库迁移为新增表和附加状态,保留现有账号、个人码及会议记录。发布前必须做一致SQLite备份、旧二进制、前端、源码、配置和服务元数据备份,并验证校验和。发布脚本 deploy/deploy-v2.py 验证产物、要求无活动会议、原子替换前端,并在健康检查失败时恢复代码。

备份目录包含 rollback-release.py。执行以下命令恢复旧代码和前端,保留当前SQLite业务数据:

python3 /opt/Hola/backups/EXACT_BACKUP/rollback-release.py --rollback /opt/Hola/backups/EXACT_BACKUP

不要直接覆盖线上数据库;恢复完整旧快照会丢失备份之后的数据,需要单独评估。账号密码、SSH信息、Forgejo令牌不进入Git。

诊断与边界

设置中的故障排查可导出本机Debug和诊断。会中视频信息分别展示摄像头发送、共享发送与各路接收的分辨率、FPS、实际编码、码率及延迟。

服务器日志在 /opt/Hola/logs/:meeting-diagnostics.jsonl、browser-diagnostics.jsonl、server-diagnostics.jsonl。日志过滤密码、令牌及原始SDP,权限0600,每类保留当前文件及3份轮转文件,每份约20MB。

  • H.265 Windows–Android互通、真实1080p60与2K60性能仍需真机实测;不能用能力声明或虚拟源结果承诺。
  • 安卓Chrome网页缺少手机屏幕采集接口,不能发起系统屏幕共享;可以观看他人的共享。
  • 后台/锁屏采集依赖浏览器和系统策略,提供有限恢复与明确失败反馈。
  • 200Mbps服务器带宽不代表任意数量的高画质视频可稳定转发;信令容量测试不等于媒体容量验收。
  • nps不在本次修改范围。
  • E2EE 仅覆盖媒体内容,不能阻止已参会设备录制或被控制的终端访问内容。