mcpField
Z
zoom-rtms

zoom-rtms

github.com/anthropics开发33.6k2.1k 次安装1 天前更新
代码仓库

关于 zoom-rtms

zoom-rtms 是面向开发者的技术参考技能,用于构建接收 Zoom 会议、网络研讨会、Video SDK 会话及 Contact Center Voice 实时媒体的后端管道,介绍 SDK、WebSocket、事件和实现限制。

主要功能

  1. 01实时音频、视频、转录、聊天与屏幕共享流
  2. 02由 Webhook 触发的流生命周期
  3. 03SDK 与手动 WebSocket 接入方式
  4. 04支持会议、网络研讨会、Video SDK 和 Contact Center Voice
  5. 05连接、心跳与重连指引

适用场景

  1. 01接收会议音频和转录以供分析
  2. 02采集屏幕共享与视频帧
  3. 03构建 Zoom 会话后端媒体管道

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/anthropics/knowledge-work-plugins --skill zoom-rtms

安装后在 Claude Code 中输入/zoom-rtms确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

RUNBOOK.md
concepts/
connection-architecture.md
lifecycle-flow.md
examples/
ai-integration.md
manual-websocket.md
rtms-bot.md
sdk-quickstart.md
references/
connection.md
data-types.md
environment-variables.md
media-types.md
quickstart.md
webhooks.md
troubleshooting/
common-issues.md

详细介绍

Zoom 实时媒体流(RTMS)

本文档是 Zoom 实时媒体管线的背景参考资料。请先使用 build-zoom-bot,再根据需要使用本 skill 了解流类型、能力以及 RTMS 特定的实现约束。

Zoom 实时媒体流(RTMS)

提供实时访问 Zoom 会议、网络研讨会、Video SDK 会话以及 Zoom 联络中心语音中音频、视频、转录、聊天和屏幕共享数据的专业指导。RTMS 采用基于 WebSocket 的协议,遵循开放标准,捕获媒体平面时无需会议机器人。

请先阅读(重要)

RTMS 主要是一项后端媒体接入服务。

  • 你的后端接收并处理实时媒体:音频、视频、屏幕共享、聊天、转录。
  • RTMS 本身并不是前端 UI SDK。
  • 处理是事件触发的:后端需等待 RTMS 开始 webhook 事件,之后才开始流处理。

可选架构(常见做法):

  • 添加 Zoom App SDK 前端,用于客户端内的 UI 和控件。
  • 通过 WebSocket(或 SSE、gRPC、队列 worker 等)将后端 RTMS 输出推送到前端。

将 RTMS 用于媒体/数据平面,并使用前端框架或 Zoom App 负责展示和用户交互。

官方文档:https://developers.zoom.us/docs/rtms/ SDK 参考(JS):https://zoom.github.io/rtms/js/ SDK 参考(Python):https://zoom.github.io/rtms/py/ 示例仓库:https://github.com/zoom/rtms-samples

快速链接

初次使用 RTMS?请按以下路径操作:

  1. 连接架构 - 两阶段 WebSocket 设计
  2. SDK 快速入门 - 接收媒体最快的方式(推荐)
  3. 手动 WebSocket - 不使用 SDK,完全控制协议
  4. 媒体类型 - 音频、视频、转录、聊天、屏幕共享

完整实现:

参考资料:

遇到问题?

支持的产品

产品Webhook 事件Payload ID应用类型
会议meeting.rtms_started / meeting.rtms_stoppedmeeting_uuid通用应用
网络研讨会webinar.rtms_started / webinar.rtms_stoppedmeeting_uuid(相同!)通用应用
Video SDKsession.rtms_started / session.rtms_stoppedsession_idVideo SDK 应用
Zoom 联络中心语音产品特定的 RTMS/ZCC Voice 事件产品特定的流/会话标识符联络中心 / 已获批准的 RTMS 集成

连接建立后,核心信令/媒体 socket 模型在各产品之间是共享的。会议、网络研讨会和 Video SDK 会话使用熟悉的开始/停止 webhook。Zoom 联络中心语音则有自己的 RTMS/ZCC Voice 事件体系,应视为采用相同的传输模型,但事件载荷因产品而异。

RTMS 概述

RTMS 是一个数据管道,可让你的应用访问 Zoom 会议、网络研讨会和 Video SDK 会话中的实时媒体,无需参会机器人。无需让自动化客户端加入会议,而是直接从 Zoom 基础设施收集媒体数据。

RTMS 提供的功能
媒体类型格式使用场景
音频PCM (L16)、G.711、G.722、Opus转录、语音分析、录制
视频H.264、JPG、PNG录制、AI 视觉、缩略图、活跃参会者选择
屏幕共享H.264、JPG、PNG内容捕获、幻灯片提取
转录文本JSON 文本会议纪要、搜索、合规
聊天JSON 文本存档、情感分析
2026 年 3 月协议变更
  • Zoom Contact Center Voice 支持:RTMS 现已覆盖 Contact Center Voice 的音频和转录文本场景。
  • 转录语言识别控制:转录媒体握手现已支持 src_language 和 enable_lid。默认行为为启用 LID。设置 enable_lid: false 可强制使用固定语言。
  • 单个参会者视频流订阅:当 data_opt 设置为 VIDEO_SINGLE_INDIVIDUAL_STREAM 时,RTMS 现可一次推送一位参会者的摄像头画面。
  • 客户端主动优雅关闭:后端可通过信令套接字发送 STREAM_CLOSE_REQ,并等待 STREAM_CLOSE_RESP。
  • 媒体保活容忍度提高:媒体套接字保活超时现为 65 秒,不再是 35 秒。
两种方式
方式适用场景复杂度
SDK(@zoom/rtms)大多数场景低,已处理 WebSocket 的复杂性
手动 WebSocket自定义协议、其他编程语言高,需完整实现协议

前提条件

  • Node.js 20.3.0+(推荐 24 LTS),用于 JavaScript SDK
  • Python 3.10+,用于 Python SDK
  • Zoom General App(用于会议/网络研讨会)或 Video SDK App(用于 Video SDK),并已启用 RTMS 功能
  • 用于接收 RTMS 事件的 Webhook 端点
  • 用于接收 WebSocket 流的服务器

需要 RTMS 访问权限? 请在 Zoom Developer Forum 发帖,说明你的使用场景并申请 RTMS 访问权限。

快速开始(SDK,推荐)

import rtms from "@zoom/rtms";

// All RTMS start/stop events across products
const RTMS_EVENTS = ["meeting.rtms_started", "webinar.rtms_started", "session.rtms_started"];

// Handle webhook events
rtms.onWebhookEvent(({ event, payload }) => {
  if (!RTMS_EVENTS.includes(event)) return;

  const client = new rtms.Client();

  client.onAudioData((data, timestamp, metadata) => {
    console.log(`Audio from ${metadata.userName}: ${data.length} bytes`);
  });

  client.onTranscriptData((data, timestamp, metadata) => {
    const text = data.toString('utf8');
    console.log(`${metadata.userName}: ${text}`);
  });

  client.onJoinConfirm((reason) => {
    console.log(`Joined session: ${reason}`);
  });

  // SDK handles all WebSocket connections automatically
  // Accepts both meeting_uuid and session_id transparently
  client.join(payload);
});

快速开始(手动 WebSocket)

如需完全控制或使用非 SDK 语言,请实现两阶段 WebSocket 协议:

const WebSocket = require('ws');
const crypto = require('crypto');

const RTMS_EVENTS = ['meeting.rtms_started', 'webinar.rtms_started', 'session.rtms_started'];

// 1. Generate signature
// For meetings/webinars: uses meeting_uuid. For Video SDK: uses session_id.
function generateSignature(clientId, idValue, streamId, clientSecret) {
  const message = `${clientId},${idValue},${streamId}`;
  return crypto.createHmac('sha256', clientSecret).update(message).digest('hex');
}

// 2. Handle webhook
app.post('/webhook', (req, res) => {
  res.status(200).send();  // CRITICAL: Respond immediately!
  
  const { event, payload } = req.body;
  if (RTMS_EVENTS.includes(event)) {
    connectToRTMS(payload);
  }
});

// 3. Connect to signaling WebSocket
function connectToRTMS(payload) {
  const { server_urls, rtms_stream_id } = payload;
  // meeting_uuid for meetings/webinars, session_id for Video SDK
  const idValue = payload.meeting_uuid || payload.session_id;
  const signature = generateSignature(CLIENT_ID, idValue, rtms_stream_id, CLIENT_SECRET);
  
  const signalingWs = new WebSocket(server_urls);
  
  signalingWs.on('open', () => {
    signalingWs.send(JSON.stringify({
      msg_type: 1,  // Handshake request
      protocol_version: 1,
      meeting_uuid: idValue,
      rtms_stream_id,
      signature,
      media_type: 9  // AUDIO(1) | TRANSCRIPT(8)
    }));
  });
  
  // ... handle responses, connect to media WebSocket
}

参见:手动 WebSocket 指南,获取完整实现。

媒体类型位掩码

使用按位或组合类型:

类型值说明
音频1PCM 音频采样
视频2H.264/JPG 视频帧
屏幕共享4与视频分开!
转录文本8实时语音转文字
聊天16会议内聊天消息
全部32所有媒体类型

示例:音频 + 转录文本 = 1 | 8 = 9

关键注意事项

问题解决方案
仅允许 1 个连接新连接会踢掉已有连接。务必跟踪活跃会话!
立即返回 200如果 Webhook 延迟响应,Zoom 会重试,从而产生重复连接
必须发送心跳收到 msg_type 12 时须回复 msg_type 13,否则连接会断开
重连需自行处理RTMS 不会自动重连。媒体保活容忍度现约为 65 秒;信令约为 60 秒
转录语言漂移当你需要固定语言转录而非自动切换语言时,请同时使用 src_language 和 enable_lid: false
仅支持单个参会者视频VIDEO_SINGLE_INDIVIDUAL_STREAM 一次仅支持一位参会者。新的 VIDEO_SUBSCRIPTION_REQ 会覆盖之前的选择
优雅关闭需显式调用当后端需要干净地终止流时,请使用 STREAM_CLOSE_REQ / STREAM_CLOSE_RESP

环境变量

SDK 环境变量
# Required - Authentication
ZM_RTMS_CLIENT=your_client_id          # Zoom OAuth Client ID
ZM_RTMS_SECRET=your_client_secret      # Zoom OAuth Client Secret

# Optional - Webhook server
ZM_RTMS_PORT=8080                      # Default: 8080
ZM_RTMS_PATH=/webhook                  # Default: /

# Optional - Logging
ZM_RTMS_LOG_LEVEL=info                 # error, warn, info, debug, trace
ZM_RTMS_LOG_FORMAT=progressive         # progressive or json
ZM_RTMS_LOG_ENABLED=true
手动实现变量
ZOOM_CLIENT_ID=your_client_id
ZOOM_CLIENT_SECRET=your_client_secret
ZOOM_SECRET_TOKEN=your_webhook_token   # For webhook validation

Zoom 应用设置

会议与网络研讨会(通用应用)
  1. 访问 marketplace.zoom.us -> Develop -> Build App
  2. 选择 General App -> User-Managed
  3. Features -> Access -> 开启 Enable Event Subscription
  4. Add Events -> 搜索 "rtms" -> 选择:
    • meeting.rtms_started
    • meeting.rtms_stopped
    • webinar.rtms_started(如使用网络研讨会)
    • webinar.rtms_stopped(如使用网络研讨会)
  5. Scopes -> Add Scopes -> 搜索 "rtms" -> 添加:
    • meeting:read:meeting_audio
    • meeting:read:meeting_video
    • meeting:read:meeting_transcript
    • meeting:read:meeting_chat
    • webinar:read:webinar_audio(如使用网络研讨会)
    • webinar:read:webinar_video(如使用网络研讨会)
    • webinar:read:webinar_transcript(如使用网络研讨会)
    • webinar:read:webinar_chat(如使用网络研讨会)
Video SDK(Video SDK 应用)
  1. 访问 marketplace.zoom.us -> Develop -> Build App
  2. 选择 Video SDK App
  3. 使用你的 SDK Key 和 SDK Secret(而非 OAuth Client ID/Secret)
  4. Add Events:
    • session.rtms_started
    • session.rtms_stopped

示例仓库

官方示例
仓库描述
rtms-samplesRTMSManager、项目模板、AI 示例
rtms-quickstart-jsJavaScript SDK 快速入门
rtms-quickstart-pyPython SDK 快速入门
rtms-sdk-cppC++ SDK
zoom-rtms主 SDK 仓库
AI 集成示例
示例描述
rtms-meeting-assistant-starter-kit带摘要功能的 AI 会议助手
arlo-meeting-assistant带数据库的生产级会议助手
videosdk-rtms-transcribe-audioWhisper 转录

完整文档

概念
示例
参考
故障排查

资源


需要帮助? 请从下方的综合索引部分开始浏览完整导航。


综合索引

本节内容迁移自 SKILL.md。

RTMS 提供对 Zoom 会议、网络研讨会和 Video SDK 会话中实时音频、视频、转录、聊天及屏幕共享内容的实时访问。

关键定位

将 RTMS 视为用于接收和处理媒体流的后端服务。

  • 后端角色:接收音频/视频/共享屏幕/聊天/转录内容,运行 AI/分析,持久化或转发数据。
  • 可选前端角色:Zoom App SDK 或 Web 仪表板,从后端传输层(WebSocket/SSE/其他)获取已处理的流数据。
  • 启动方式:后端等待 RTMS 开始 webhook 事件,然后开始处理流。

请勿将 RTMS 建模为纯前端 SDK。

快速入门路径

如果你是 RTMS 新手,请按以下顺序操作:

  1. 先运行预检 -> RUNBOOK.md

  2. 了解架构 -> concepts/connection-architecture.md

    • 两阶段 WebSocket:信令 + 媒体
    • 为什么 RTMS 不使用机器人
  3. 选择你的方式 -> SDK 或手动

  4. 了解生命周期 -> concepts/lifecycle-flow.md

    • Webhook -> 信令 -> 媒体 -> 流式传输
  5. 配置媒体类型 -> references/media-types.md

    • 音频、视频、转录、聊天、屏幕共享
  6. 排查问题 -> troubleshooting/common-issues.md

    • 连接问题、重复 webhook、数据缺失

文档结构

rtms/
├── SKILL.md                           # Main skill overview
├── SKILL.md                           # This file - navigation guide
│
├── concepts/                          # Core architectural patterns
│   ├── connection-architecture.md     # Two-phase WebSocket design
│   └── lifecycle-flow.md              # Webhook to streaming flow
│
├── examples/                          # Complete working code
│   ├── sdk-quickstart.md              # Using @zoom/rtms SDK
│   ├── manual-websocket.md            # Raw protocol implementation
│   ├── rtms-bot.md                    # Complete RTMS bot implementation
│   └── ai-integration.md              # Transcription and analysis
│
├── references/                        # Reference documentation
│   ├── media-types.md                 # Audio, video, transcript, chat, share
│   ├── data-types.md                  # All enums and constants
│   ├── connection.md                  # WebSocket protocol details
│   └── webhooks.md                    # Event subscription
│
└── troubleshooting/                   # Problem solving guides
    └── common-issues.md               # FAQ and solutions

按使用场景

我想获取会议转录
  1. SDK 快速入门 - 最快的方式
  2. 媒体类型 - 转录配置
  3. AI 集成 - Whisper、Deepgram、AssemblyAI
我想录制会议
  1. 媒体类型 - 音频 + 视频配置
  2. SDK 快速入门 - 接收媒体
  3. AI 集成 - 填补间隙的录制
我想构建 AI 会议助手
  1. AI 集成 - 完整模式
  2. SDK 快速入门 - 媒体接入
  3. 生命周期流程 - 事件处理
我想构建完整的 RTMS 机器人
  1. RTMS 机器人 - 完整实现指南
  2. 生命周期流程 - 从 webhook 到流式传输的流程
  3. 连接架构 - 两阶段设计
我需要完全掌控协议
  1. 手动 WebSocket - 从这里开始
  2. 连接架构 - 两阶段设计
  3. 数据类型 - 所有消息类型和枚举
  4. 连接 - 协议细节
我遇到连接错误
  1. 常见问题 - 诊断检查清单
  2. 连接架构 - 验证流程
  3. Webhooks - 验证与时序
我想了解架构
  1. 连接架构 - 两阶段 WebSocket
  2. 生命周期流程 - 完整流程图
  3. 数据类型 - 协议常量

按产品

我正在为 Zoom Meetings 开发
我正在为 Zoom Webinars 开发
  • 与会议相同,但 webhook 事件为 webinar.rtms_started。负载仍使用 meeting_uuid(而非 webinar_uuid)。
  • 添加 webinar 权限范围和事件订阅。参见 Webhooks。
  • 目前只确认**主讲人(panelist)**流可用。参会者流可能无法单独获取。
我正在为 Zoom Video SDK 开发
  • Webhook 事件:session.rtms_started。负载使用 session_id(而非 meeting_uuid)。
  • 需要一个带有 SDK Key/Secret 的 Video SDK App(而非 OAuth Client ID/Secret)。
  • 连接之后,协议与会议完全相同。
  • 负载详情请参阅 Webhooks。

核心文档

1. 连接架构(关键)

concepts/connection-architecture.md

RTMS 使用两个独立的 WebSocket 连接:

  • 信令 WebSocket:身份验证、控制、心跳
  • 媒体 WebSocket:实际的音频、视频、转录数据
2. SDK 与手动实现(决策点)

examples/sdk-quickstart.md 对比 examples/manual-websocket.md

SDK手动
处理 WebSocket 的复杂性完全掌控协议
自动重连需自行实现重连
代码更少代码更多
适合大多数场景适合定制需求
3. 关键陷阱(最常见问题)

troubleshooting/common-issues.md

  1. 立即返回 200 - 延迟的 Webhook 响应会导致重复连接
  2. 每个流只允许 1 个连接 - 新连接会踢掉已有连接
  3. 必须发送心跳 - 必须响应保活消息,否则连接会断开
  4. 跟踪活跃会话 - 防止重复的加入尝试

关键经验

重要发现:
  1. 双阶段 WebSocket 设计

    • 信令:控制平面(握手、心跳、启动/停止)
    • 媒体:数据平面(音频、视频、转录、聊天、共享)
    • 参见:连接架构
  2. Webhook 响应时机

    • 必须在进行任何处理之前返回 200
    • 响应延迟 -> Zoom 重试 -> 重复连接
    • 参见:常见问题
  3. 心跳是强制性的

    • 信令:收到 msg_type 12,回复 msg_type 13
    • 媒体:相同模式
    • 未响应则连接关闭
    • 参见:连接
  4. 签名生成

    • 格式:HMAC-SHA256(clientSecret, "clientId,meetingUuid,streamId")
    • 对于 Video SDK,使用 session_id 代替 meetingUuid
    • 研讨会仍使用 meeting_uuid(而非 webinar_uuid)
    • 信令和媒体握手均需要
    • 参见:手动 WebSocket
  5. 媒体类型为位掩码

    • Audio=1、Video=2、Share=4、Transcript=8、Chat=16、All=32
    • 使用按位或组合:Audio+Transcript = 1|8 = 9
    • 参见:媒体类型
  6. 屏幕共享与视频是分开的

    • 不同的 msg_type(16 与 15)
    • 不同的媒体标志(4 与 2)
    • 必须单独订阅
    • 参见:媒体类型

快速参考

"连接失败"

-> 常见问题

"重复连接"

-> Webhook 时机

"没有音频/视频数据"

-> 媒体类型 - 检查配置

"如何手动实现?"

-> 手动 WebSocket

"有哪些消息类型?"

-> 数据类型

"如何集成 AI?"

-> AI 集成


文档版本

基于 Zoom RTMS SDK v1.x 以及截至 2026 年的官方文档。


编码愉快!

请记住:如需最快上手,请从 SDK 快速入门 开始;如需完全掌控,请选择 手动 WebSocket。

评论

支持 Markdown