跳转到内容

会议室

会议室插件(Meeting)为 Monibuca V6 提供 专业视频会议 能力。适用于在线会议、远程协作、培训讲座等场景。

  • 多人视频会议:支持 50+ 并发参与者
  • 会议管理
    • 议程管理(Agenda)
    • 会议计时器与发言计时
    • 举手功能(Raise Hand)
    • 等候室(Lobby)控制入场
  • 实时转写:语音自动转文字(需外部 ASR 服务)
  • AI 智能服务
    • 自动生成会议纪要
    • 从转写内容中提取待办任务
    • 会议决议总结
  • 录制与控制
    • 会议录制(MP4 格式)
    • 屏幕共享
    • 主持人权限控制
  • 参与者管理:踢人、禁言、锁定房间、禁用入场
Cargo.toml
features = ["meeting"]
# Meeting 插件依赖 Room 服务
# room feature 会自动启用
graph TB
subgraph Meeting["MeetingPlugin"]
SM["SessionManager<br/>会议信息、参与者"]
Agenda["AgendaManager<br/>议程控制"]
Trans["TranscriptionManager<br/>实时转写"]
AI["AIService<br/>总结 & 任务提取"]
Record["RecordingManager<br/>录制控制"]
Lobby["LobbyManager<br/>等候室"]
DB["数据持久化<br/>会议、议程、转写"]
end
subgraph RS["Room Service"]
Room["房间管理<br/>主持人 + 参与者"]
WS["WebSocket<br/>信令通信"]
API["RoomApi"]
end
subgraph Media["媒体层"]
WHIP["WebRTC WHIP<br/>推流"]
WHEP["WebRTC WHEP<br/>拉流"]
ASR["ASR Service<br/>语音识别"]
end
Meeting -->|register_callbacks| RS
SM --> DB
Agenda --> DB
Trans --> AI
Trans --> DB
Record --> Media
Lobby --> API
Room --> API
API -->|set_room_locked<br/>set_lobby_enabled| Meeting
WS --> Meeting
WHIP --> Media
WHEP --> Media
Trans -->|实时推送| ASR
Scheduled → Starting → Active → Paused → Ended
状态说明
Scheduled会议已排期,等待开始
Starting等候室接纳参与者中
Active会议进行中
Paused会议暂停
Ended会议已结束
Action方向说明
start_meetingC→S主持人开始会议
end_meetingC→S主持人结束会议
pause_meetingC→S主持人暂停会议
resume_meetingC→S主持人恢复会议
Action方向说明
mute_participantC→S主持人静音参与者
unmute_participantC→S主持人取消静音
kick_participantC→S主持人踢出参与者
raise_handC→S参与者举手
lower_handC→S参与者放下手
participant_mutedS→C参与者被静音通知
participant_kickedS→C参与者被踢出通知
hand_raisedS→C举手通知(广播)
Action方向说明
update_agendaC→S更新当前议程项
next_agendaC→S进入下一个议程项
agenda_changedS→C议程变化通知(广播)
Action方向说明
start_transcriptionC→S启动实时转写
stop_transcriptionC→S停止实时转写
transcription_resultS→C转写结果推送
start_recordingC→S开始录制
stop_recordingC→S停止录制
Action方向说明
toggle_lobbyC→S开关等候室
admit_userC→S允许用户进入
reject_userC→S拒绝用户进入
user_pendingS→C用户在等候室(广播)
Action方向说明
lock_roomC→S锁定房间(禁止新用户加入)
unlock_roomC→S解锁房间
{
"meeting_id": "meeting_001",
"agenda": [
{
"id": "agenda_1",
"title": "开场致辞",
"speaker": "主持人",
"duration": 5, // 分钟
"order": 1
},
{
"id": "agenda_2",
"title": "业务进展汇报",
"speaker": "部门负责人",
"duration": 20,
"order": 2
},
{
"id": "agenda_3",
"title": "Q&A 环节",
"speaker": "全体参与者",
"duration": 10,
"order": 3
}
],
"current_agenda_id": "agenda_2"
}
{
"action": "update_agenda",
"agenda": [
{
"title": "开场致辞",
"speaker": "主持人",
"duration": 5
}
]
}
{
"action": "mute_participant",
"target_user_id": "user_005",
"mute_audio": true, // 静音麦克风
"mute_video": false // 不关闭摄像头
}

主持人具有以下权限:

  • 开始/结束/暂停会议
  • 静音/取消静音参与者
  • 踢出参与者(强制退出)
  • 控制等候室(允许/拒绝进入)
  • 锁定/解锁房间
  • 启动/停止录制
  • 启动/停止转写

参与者可以举手表示想发言,主持人可以看到举手队列:

{
"action": "raise_hand"
}
┌────────────────┐
│ 参与者麦克风 │
└────────┬───────┘
│ RTC Audio
┌─────────────┐ ┌──────────────┐
│ AudioBuffer │────────→│ ASR Service │
└─────────────┘ │ (外部服务) │
└──────┬───────┘
│ 识别结果
┌─────────────────┐
│ TranscriptionDB │
└─────────────────┘
┌────────────────────┐
│ WebSocket 实时推送 │
│ 至所有参与者 │
└────────────────────┘
{
"action": "start_transcription",
"language": "zh-CN" // 语言代码
}
{
"action": "transcription_result",
"speaker_id": "user_003",
"speaker_name": "张三",
"text": "我们上半年的销售额增长了 25%",
"is_final": true, // true: 句子完成, false: 临时结果
"timestamp": "2024-01-15T10:35:00Z"
}

会议结束后,AI 自动生成纪要:

{
"meeting_id": "meeting_001",
"title": "2024 Q1 季度总结会",
"date": "2024-01-15",
"duration": "2小时 15分钟",
"participants": ["主持人", "张三", "李四"],
"summary": "本次会议总结了 Q1 业绩,制定了 Q2 目标...",
"key_points": [
"销售额同比增长 25%",
"市场份额提升 5 个百分点",
"新产品线已上线 3 个"
],
"action_items": [
{
"item": "完成市场调研报告",
"owner": "市场部",
"deadline": "2024-01-31"
},
{
"item": "优化售后服务流程",
"owner": "运营部",
"deadline": "2024-02-15"
}
]
}

从转写内容中自动提取任务项:

转写: "李四,能否在下周五前完成客户需求分析?"
提取的任务:
{
"item": "完成客户需求分析",
"owner": "李四",
"deadline": "2024-01-19", // 下周五
"priority": "high"
}
{
"action": "toggle_lobby",
"enable": true
}
用户尝试加入 → 进入等候室 → 主持人审核 → 允许/拒绝进入
{
"action": "admit_user",
"target_user_id": "user_008"
}
{
"action": "reject_user",
"target_user_id": "user_008"
}
{
"action": "share_screen"
}

参与者通过浏览器 API 选择要共享的屏幕或窗口。系统自动将共享内容作为独立的媒体轨道处理。

会中 开始 / 停止录制WebSocket 房间信令RoomApi 驱动(见上文信令与架构),不提供 POST /meeting/.../recording/start 这类与全局规则不一致的独立 HTTP 路径。

与其它插件相同,Meeting 的 HTTP REST 统一为 /meeting/api/...(引擎挂载前缀 meeting/api)。若只需通过 HTTP 查看录制条目列表:

Terminal window
curl http://localhost:8080/meeting/api/recordings

(持久化录制目录完全接入前,列表可能为空;单条 play / download / DELETEHTTP API — Meeting REST,与仓库 docs/http-api.md §14.2 同步。)

基路径: http(s)://<host>:<port>/meeting/api。请勿使用已废弃的 /room/meeting/...,也勿省略 api 段写成 /meeting/rooms(会与插件顶层路径混淆)。

Terminal window
curl http://localhost:8080/meeting/api/rooms
Terminal window
curl -X POST http://localhost:8080/meeting/api/rooms \
-H "Content-Type: application/json" \
-d '{"room_id":"room-demo-1"}'
Terminal window
curl http://localhost:8080/meeting/api/reservations
Terminal window
curl -X POST http://localhost:8080/meeting/api/reservations \
-H "Content-Type: application/json" \
-d '{
"room_id": "room-1",
"room_name": "周例会",
"host_user_id": "u1",
"host_user_name": "主持人",
"start_time": "2026-04-21T10:00:00+08:00",
"duration_minutes": 60,
"timezone": "Asia/Shanghai",
"participants": ["u2"],
"has_password": false,
"mute_all": false,
"mute_video_all": false
}'
Terminal window
curl http://localhost:8080/meeting/api/templates
Terminal window
curl -X POST http://localhost:8080/meeting/api/templates \
-H "Content-Type: application/json" \
-d '{
"name": "默认模板",
"description": null,
"max_participants": 50,
"default_password": null,
"auto_record": false,
"auto_lock": false,
"enabled": true,
"sort_order": 0
}'
Terminal window
curl http://localhost:8080/meeting/api/stats
curl http://localhost:8080/meeting/api/features

锁定房间、静音、踢人、录制单条 URL 等完整路径表见 HTTP API — Meeting REST(与仓库 docs/http-api.md §14.2 一致)。议程、转写、纪要等能力以 WebSocket 信令与特性扩展 为主,本文档其它章节描述的是协议与数据模型,对应 GET /meeting/meetings/... 这类未在引擎中注册的 REST 路径。

字段类型说明
idstring会议 ID
titlestring会议标题
organizer_idstring组织者 ID
statusenum会议状态
start_timetimestamp开始时间
end_timetimestamp结束时间
participant_countint参与者数
recording_filestring录制文件路径
字段类型说明
idstring议程 ID
meeting_idstring会议 ID
titlestring议程标题
speakerstring发言人
durationint时长(秒)
orderint排序
字段类型说明
idstring转写 ID
meeting_idstring会议 ID
speaker_idstring发言人 ID
texttext转写内容
timestamptimestamp时间戳
languagestring语言
meeting:
# 基本配置
max_participants: 50 # 最大参与者数
session_timeout: 7200 # 会议超时(秒)
# 等候室
enable_lobby: true # 启用等候室
lobby_timeout: 300 # 等候室超时(秒)
# 录制
enable_recording: true # 启用录制
recording_format: "mp4" # 录制格式
recording_dir: "./recordings"
# 转写
enable_transcription: false # 启用转写(需配置 ASR 服务)
asr_service_url: "" # ASR 服务 URL
transcription_language: "zh-CN"
# AI 服务
enable_ai_summary: false # 启用 AI 总结
ai_service_url: "" # AI 服务 URL
# 计时器
timer:
max_duration: 7200 # 会议最大时长(秒)
warning_before_end: 300 # 结束前提醒(秒)
enable_agenda_timer: true # 议程计时
const room = document.getElementById('room') as MbRoom;
const publisher = document.getElementById('publisher') as MbPublisher;
// 连接会议室
room.setAttribute('ws-url', 'ws://localhost:8080/room?type=meeting');
room.setAttribute('room-id', 'meeting_001');
// 开启音视频
await publisher.startCapture({ audio: true, video: true });
await publisher.startPublish();
const room = document.getElementById('room') as MbRoom;
// 启动会议
room.sendMessage({
action: 'start_meeting'
});
// 静音参与者
room.sendMessage({
action: 'mute_participant',
target_user_id: 'user_005',
mute_audio: true
});
// 开启等候室
room.sendMessage({
action: 'toggle_lobby',
enable: true
});
// 启动转写
room.sendMessage({
action: 'start_transcription',
language: 'zh-CN'
});
// 监听转写结果
room.addEventListener('transcription_result', (event) => {
console.log(`${event.speaker_name}: ${event.text}`);
// 实时显示在转写面板
});
const publisher = document.getElementById('publisher') as MbPublisher;
// 启动屏幕共享
await publisher.startScreenShare();
// 停止屏幕共享
await publisher.stopScreenShare();

完整的会议室 Demo 位于 web-sdk/packages/demo/meeting/

meeting/
├── src/
│ ├── pages/
│ │ ├── Lobby/index.tsx # 会议列表
│ │ ├── MeetingRoom/index.tsx # 会议间
│ │ └── Waiting/index.tsx # 等候室
│ ├── components/
│ │ ├── VideoGrid/index.tsx # 视频网格
│ │ ├── Transcription/index.tsx # 实时转写面板
│ │ ├── Agenda/index.tsx # 议程面板
│ │ ├── Participants/index.tsx # 参与者列表
│ │ └── Controls/index.tsx # 控制栏
│ ├── services/api.ts # API 封装
│ └── types/index.ts # 类型定义
├── package.json # port: 5475
└── vite.config.ts
Terminal window
cd web-sdk/packages/demo/meeting
pnpm install
pnpm dev
# 访问 http://localhost:5475
http://localhost:5475?meeting_id=meeting_001&user_id=user_123&role=participant

Demo 自动检测设备类型,移动端采用:

  • 自适应视频网格(最多 4 个视频)
  • 底部固定控制栏
  • 上拉唤出参与者列表
  • 下拉唤出议程面板
  • 转写结果滚动显示

联系我们

微信公众号:不卡科技 微信公众号二维码
腾讯频道:流媒体技术 腾讯频道二维码
QQ 频道:p0qq0crz08 QQ 频道二维码
QQ 群:751639168 QQ 群二维码