跳转到内容

自建视频会议 - Monibuca Meeting 插件

会议室插件(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:8180/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(会与插件顶层路径混淆)。

快速示例(完整字段与错误码以“HTTP API 详细参数与返回”为准):

Terminal window
curl -X POST http://localhost:8180/meeting/api/rooms \
-H "Content-Type: application/json" \
-d '{"room_id":"room-demo-1"}'

默认基地址:http://localhost:8180,前缀:/meeting/api

POST /meeting/api/rooms
Content-Type: application/json

请求体:

{
"room_id": "room-demo-1"
}

响应(示例):

{
"code": 0,
"message": "success",
"data": {
"room_id": "room-demo-1",
"created": true
}
}
字段类型必填说明
room_idstring会议室唯一 ID
GET /meeting/api/rooms

响应字段:

字段类型说明
roomsarray会议室列表
countint总数
GET /meeting/api/rooms/{room_id}
参数类型必填说明
room_idstring会议室 ID
POST /meeting/api/reservations
Content-Type: application/json
字段类型必填说明
room_idstring会议室 ID
room_namestring展示名称
host_user_idstring主持人 ID
start_timestring(RFC3339)开始时间
duration_minutesint会议时长(分钟)
participantsstring[]初始参会者
POST /meeting/api/control/mute
Content-Type: application/json
{
"room_id": "room-demo-1",
"user_id": "u100"
}
POST /meeting/api/templates
Content-Type: application/json

关键字段:namemax_participantsauto_recordauto_lockenabled

GET /meeting/api/stats
GET /meeting/api/features
HTTP 状态码场景
400参数校验失败
404会议室/模板不存在
409会议室冲突或重复创建
字段类型说明
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:8180/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
  1. 启用 meeting + webrtc + room Feature,参考 安装部署
  2. Docker 启动 Monibuca(开放 8180、UDP 端口段用于 WebRTC ICE)
  3. 配置 TURN/STUN(公网会议必备),见 WebRTC 插件配置
  4. 使用 Web SDK 会议 Demo 或自有前端调用 Room/Meeting API
维度Monibuca 自建声网 / 即构等 SaaS
许可费用开源版 + 可选商业授权按分钟/并发计费
数据合规数据不出机房依赖云厂商区域
协议扩展RTMP/HLS/GB28181 同源站以实时互动 SDK 为主
运维需自建运维与监控(内置 Admin)托管运维

详细迁移路径见 从声网/即构迁移;引擎选型见 流媒体服务器选型

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

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

联系我们

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