本文へ移動
cccskills
無料GitHub で公開

zoom-rtms

Zoom Realtime Media Streams (RTMS) for accessing live audio, video, transcript, chat, and screen share from Zoom meetings, webinars, Video SDK sessions, and Zoom Contact Center Voice. WebSocket-based protocol using open web standards. Use when building AI/ML applications, live transcription, recording, streaming, or real-time meeting/webinar/session/contact-center analysis.

日本語の概要は準備中です。原文の説明を表示しています。

zoom/skillsスター 85(GitHub 85 + cccskills 0)
連携ツールZoom

実行スコア 未検証

インストール方法を見る

含まれるファイル(16)

  • SKILL.md26.7 KB
  • CHANGELOG.md543 B
  • concepts/connection-architecture.md8.9 KB
  • concepts/lifecycle-flow.md15.6 KB
  • examples/ai-integration.md11.4 KB
  • examples/manual-websocket.md19.6 KB
  • examples/rtms-bot.md26.8 KB
  • examples/sdk-quickstart.md9.8 KB
  • references/connection.md10.9 KB
  • references/data-types.md14.1 KB
  • references/environment-variables.md1.7 KB
  • references/media-types.md9.7 KB
  • references/quickstart.md7.0 KB
  • references/webhooks.md9.5 KB
  • RUNBOOK.md3.4 KB
  • troubleshooting/common-issues.md13.6 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Zoom Realtime Media Streams (RTMS)

Expert guidance for accessing live audio, video, transcript, chat, and screen share data from Zoom meetings, webinars, Video SDK sessions, and Zoom Contact Center Voice in real-time. RTMS uses a WebSocket-based protocol with open standards and does not require a meeting bot to capture the media plane.

Read This First (Critical)

RTMS is primarily a backend media ingestion service.

  • Your backend receives and processes live media: audio, video, screen share, chat, transcript.
  • RTMS is not a frontend UI SDK by itself.
  • Processing is event-triggered: backend waits for RTMS start webhook events before stream handling begins.

Optional architecture (common):

  • Add a Zoom App SDK frontend for in-client UI/controls.
  • Stream backend RTMS outputs to frontend via WebSocket (or SSE, gRPC, queue workers, etc.).

Use RTMS for media/data plane, and use frontend frameworks/Zoom Apps for presentation + user interactions.

Official Documentation: https://developers.zoom.us/docs/rtms/ SDK Reference (JS): https://zoom.github.io/rtms/js/ SDK Reference (Python): https://zoom.github.io/rtms/py/ Sample Repository: https://github.com/zoom/rtms-samples

Quick Links

New to RTMS? Follow this path:

  1. Connection Architecture - Two-phase WebSocket design
  2. SDK Quickstart - Fastest way to receive media (recommended)
  3. Manual WebSocket - Full protocol control without SDK
  4. Media Types - Audio, video, transcript, chat, screen share

Complete Implementation:

  • RTMS Bot - End-to-end bot implementation guide

Reference:

Having issues?

Supported Products

ProductWebhook EventPayload IDApp Type
Meetingsmeeting.rtms_started / meeting.rtms_stoppedmeeting_uuidUser-managed General App
Webinarswebinar.rtms_started / webinar.rtms_stoppedmeeting_uuid (same!)User-managed General App
Video SDKsession.rtms_started / session.rtms_stoppedsession_idVideo SDK App
Zoom Contact Center Voicecontact_center.voice_rtms_started / contact_center.voice_rtms_stoppedProduct-specific stream/session identifiersGeneral user/admin or S2S, based on scopes

Once connected, the core signaling/media socket model is shared across products. Meetings, webinars, and Video SDK sessions use the familiar start/stop webhooks. Zoom Contact Center Voice adds its own RTMS/ZCC Voice event family and should be treated as the same transport model with product-specific event payloads.

RTMS Overview

RTMS is a data pipeline that gives your app access to live media from Zoom meetings, webinars, and Video SDK sessions without participant bots. Instead of having automated clients join meetings, use RTMS to collect media data directly from Zoom's infrastructure.

What RTMS Provides

Media TypeFormatUse Cases
AudioPCM (L16), G.711, G.722, OpusTranscription, voice analysis, recording
VideoH.264, JPG, PNGRecording, AI vision, thumbnails, active participant selection
Screen ShareH.264, JPG, PNGContent capture, slide extraction
TranscriptJSON textMeeting notes, search, compliance
ChatJSON textArchive, sentiment analysis

Recent Protocol Changes

  • Zoom Contact Center Voice support: RTMS now covers Contact Center Voice audio and transcript scenarios.
  • Transcript Language Identification control: transcript media handshakes now support src_language and enable_lid. Default behavior is LID enabled. Set enable_lid: false to force a fixed language.
  • Single individual video stream subscription: RTMS can now stream one participant's camera feed at a time when data_opt is set to VIDEO_SINGLE_INDIVIDUAL_STREAM.
  • Graceful client-initiated shutdown: backends can send STREAM_CLOSE_REQ over the signaling socket and wait for STREAM_CLOSE_RESP.
  • Media keep-alive tolerance increased: media socket keep-alive timeout is now 65 seconds, not 35.
  • Audio buffer control in signaling handshake: signaling handshakes now support optional buffer_data. Default is true, which delivers up to 60 seconds of initial audio buffered while signaling/media sockets are established. For live streaming pipelines, set buffer_data: false to drop the startup backlog and start from live audio once connected.
  • Media payload length field: audio, video, and screen share media data events can include content.length, the original binary length before base64 encoding.
  • ZCC Voice enum update: CONFERENCE_PARTICIPANT_LEFT = 29 was added to RTMS_ZCC_VOICE_EVENT_TYPE.

Media Socket Deprecation

Deprecated: Unified media socket mode and media_type: 32 must not be used. Open a separate data connection for each required media type and send exactly one concrete media type per data handshake: audio (1), video (2), screen share (4), transcript (8), or chat (16). Do not send combined values such as 3, 5, or 9 on the wire.

Two Approaches

ApproachBest ForComplexity
SDK (@zoom/rtms)Most use casesLow - handles WebSocket complexity
Manual WebSocketCustom protocols, other languagesHigh - full protocol implementation

Prerequisites

  • Node.js 20.3.0+ (24 LTS recommended) for JavaScript SDK
  • Python 3.10+ for Python SDK
  • User-managed General App (meetings/webinars), General or S2S app (Contact Center Voice), or Video SDK App (Video SDK) with RTMS enabled
  • Webhook endpoint for RTMS events
  • Server to receive WebSocket streams

Need to create/configure the Marketplace app first? Use Marketplace app management before RTMS implementation. It documents General App manifests, event subscription API behavior, app-owned client_credentials, and RTMS event validation drift. Use the user-managed Meeting/Webinar RTMS template, or the General App or S2S Contact Center Voice templates in the template selector.

Need RTMS access? Post in Zoom Developer Forum requesting RTMS access with your use case.

Quick Start (SDK - Recommended)

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);
});

Quick Start (Manual WebSocket)

For full control or non-SDK languages, implement the two-phase WebSocket protocol:

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,
      buffer_data: false // Use false for live streaming; true preserves startup audio
    }));
  });
  
  // ... handle responses, connect to media WebSocket
}

See: Manual WebSocket Guide for complete implementation.

Media Data Connections

Select the media needed by the application, then open one data WebSocket for each selected type using the matching URL from the signaling response:

TypeWire valueServer URL
Audio1server_urls.audio
Video2server_urls.video
Screen Share4server_urls.deskshare
Transcript8server_urls.transcript
Chat16server_urls.chat

For generic sample configuration, prefer readable names such as RTMS_MEDIA_TYPES=audio,video,transcript. An SDK or library may accept an internal selection bitmask, but it must expand that selection into separate connections. Never send a selection mask, a combined value, or 32 as the data-handshake media_type.

Critical Gotchas

IssueSolution
Only 1 signaling session allowedA duplicate signaling connection can kick out the existing session. Track active sessions; each session still needs one media socket per selected type
Split media sockets requiredUse one data WebSocket per concrete media type. Unified mode, server_urls.all, combined media_type values, and media_type: 32 are deprecated
Respond 200 immediatelyIf webhook delays, Zoom retries creating duplicate connections
Heartbeat mandatoryRespond to msg_type 12 with msg_type 13, or connection dies
Reconnection is YOUR jobRTMS doesn't auto-reconnect. Media keep-alive tolerance is now about 65s; signaling remains around 60s
Transcript language driftUse src_language plus enable_lid: false when you want fixed-language transcription instead of automatic language switching
Audio params must match the support matrixDo not mix arbitrary content_type, codec, sample_rate, channel, and send_rate. The media server rejects unsupported combinations
Single participant video onlyVIDEO_SINGLE_INDIVIDUAL_STREAM supports one participant at a time. A new VIDEO_SUBSCRIPTION_REQ overrides the previous selection
Graceful close is explicit nowUse STREAM_CLOSE_REQ / STREAM_CLOSE_RESP when your backend wants to terminate the stream cleanly
RTMS manifest validation can driftCreate-time validation can reject RTMS event names that PUT /manifest persists on an existing draft app. Confirm with GET /manifest after updates

Environment Variables

SDK Environment Variables

# 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

Manual Implementation Variables

ZOOM_CLIENT_ID=your_client_id
ZOOM_CLIENT_SECRET=your_client_secret
ZOOM_SECRET_TOKEN=your_webhook_token   # For webhook validation

Zoom App Setup

For Meetings and Webinars (General App)

  1. Go to marketplace.zoom.us -> Develop -> Build App
  2. Choose General App -> User-Managed
  3. Features -> Access -> Enable Event Subscription
  4. Add Events -> Search "rtms" -> Select:
    • meeting.rtms_started
    • meeting.rtms_stopped
    • webinar.rtms_started (if using webinars)
    • webinar.rtms_stopped (if using webinars)
  5. Scopes -> Add Scopes -> Search "rtms" -> Add:
    • meeting:read:meeting_audio
    • meeting:read:meeting_video
    • meeting:read:meeting_transcript
    • meeting:read:meeting_chat
    • webinar:read:webinar_audio (if using webinars)
    • webinar:read:webinar_video (if using webinars)
    • webinar:read:webinar_transcript (if using webinars)
    • webinar:read:webinar_chat (if using webinars)

For Video SDK (Video SDK App)

  1. Go to marketplace.zoom.us -> Develop -> Build App
  2. Choose Video SDK App
  3. Use your SDK Key and SDK Secret (not OAuth Client ID/Secret)
  4. Add Events:
    • session.rtms_started
    • session.rtms_stopped

Sample Repositories

Official Samples

RepositoryDescription
rtms-samplesRTMSManager, boilerplates, AI samples
rtms-quickstart-jsJavaScript SDK quickstart
rtms-quickstart-pyPython SDK quickstart
rtms-sdk-cppC++ SDK
zoom-rtmsMain SDK repository

AI Integration Samples

SampleDescription
rtms-meeting-assistant-starter-kitAI meeting assistant with summaries
arlo-meeting-assistantProduction meeting assistant with DB
videosdk-rtms-transcribe-audioWhisper transcription

Complete Documentation

Concepts

Examples

References

Troubleshooting

Resources


Need help? Start with Integrated Index section below for complete navigation.


Integrated Index

This section was migrated from SKILL.md.

RTMS provides real-time access to live audio, video, transcript, chat, and screen share from Zoom meetings, webinars, and Video SDK sessions.

Critical Positioning

Treat RTMS as a backend service for receiving and processing media streams.

  • Backend role: ingest audio/video/share/chat/transcript, run AI/analytics, persist/forward data.
  • Optional frontend role: Zoom App SDK or web dashboard that consumes processed stream data from backend transport (WebSocket/SSE/other).
  • Kickoff model: backend waits for RTMS start webhook events, then starts stream processing.

Do not model RTMS as a frontend-only SDK.

Quick Start Path

If you're new to RTMS, follow this order:

  1. Run preflight checks first -> RUNBOOK.md

  2. Understand the architecture -> concepts/connection-architecture.md

    • Two-phase WebSocket: Signaling + Media
    • Why RTMS doesn't use bots
  3. Choose your approach -> SDK or Manual

  4. Understand the lifecycle -> concepts/lifecycle-flow.md

    • Webhook -> Signaling -> Media -> Streaming
  5. Configure media types -> references/media-types.md

    • Audio, video, transcript, chat, screen share
  6. Troubleshoot issues -> troubleshooting/common-issues.md

    • Connection problems, duplicate webhooks, missing data

Documentation Structure

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

By Use Case

I want to get meeting transcripts

  1. SDK Quickstart - Fastest approach
  2. Media Types - Transcript configuration
  3. AI Integration - Whisper, Deepgram, AssemblyAI

I want to record meetings

  1. Media Types - Audio + Video configuration
  2. SDK Quickstart - Receiving media
  3. AI Integration - Gap-filled recording

I want to build an AI meeting assistant

  1. AI Integration - Complete patterns
  2. SDK Quickstart - Media ingestion
  3. Lifecycle Flow - Event handling

I want to build a complete RTMS bot

  1. RTMS Bot - Complete implementation guide
  2. Lifecycle Flow - Webhook to streaming flow
  3. Connection Architecture - Two-phase design

I need full protocol control

  1. Manual WebSocket - START HERE
  2. Connection Architecture - Two-phase design
  3. Data Types - All message types and enums
  4. Connection - Protocol details

I'm getting connection errors

  1. Common Issues - Diagnostic checklist
  2. Connection Architecture - Verify flow
  3. Webhooks - Validation and timing

I want to understand the architecture

  1. Connection Architecture - Two-phase WebSocket
  2. Lifecycle Flow - Complete flow diagram
  3. Data Types - Protocol constants

By Product

I'm building for Zoom Meetings

I'm building for Zoom Webinars

  • Same as meetings, but webhook event is webinar.rtms_started. Payload still uses meeting_uuid (NOT webinar_uuid).
  • Add webinar scopes and event subscriptions. See Webhooks.
  • Only panelist streams are confirmed available. Attendee streams may not be individual.

I'm building for Zoom Video SDK

  • Webhook event: session.rtms_started. Payload uses session_id (NOT meeting_uuid).
  • Requires a Video SDK App with SDK Key/Secret (not OAuth Client ID/Secret).
  • Once connected, the protocol is identical to meetings.
  • See Webhooks for payload details.

Key Documents

1. Connection Architecture (CRITICAL)

concepts/connection-architecture.md

RTMS uses one signaling WebSocket plus one media WebSocket per selected media type:

  • Signaling WebSocket: Authentication, control, heartbeats
  • Media WebSockets: Separate audio/video/share/transcript/chat data connections

2. SDK vs Manual (DECISION POINT)

examples/sdk-quickstart.md vs examples/manual-websocket.md

SDKManual
Handles WebSocket complexityFull protocol control
Automatic reconnectionDIY reconnection
Less codeMore code
Best for most use casesBest for custom requirements

3. Critical Gotchas (MOST COMMON ISSUES)

troubleshooting/common-issues.md

  1. Respond 200 immediately - Delayed webhook responses cause duplicates
  2. Only 1 signaling session per stream - Duplicate signaling joins can kick out the existing session; split media sockets are still required
  3. Heartbeat required - Must respond to keep-alive or connection dies
  4. Track active sessions - Prevent duplicate join attempts

Key Learnings

Critical Discoveries:

  1. Two-Phase WebSocket Design

    • Signaling: Control plane (handshake, heartbeat, start/stop)
    • Media: Data plane (audio, video, transcript, chat, share)
    • See: Connection Architecture
  2. Webhook Response Timing

    • MUST respond 200 BEFORE any processing
    • Delayed response -> Zoom retries -> duplicate connections
    • See: Common Issues
  3. Heartbeat is Mandatory

    • Signaling: Receive msg_type 12, respond with msg_type 13
    • Media: Same pattern
    • Failure to respond = connection closed
    • See: Connection
  4. Signature Generation

    • Format: HMAC-SHA256(clientSecret, "clientId,meetingUuid,streamId")
    • For Video SDK, use session_id in place of meetingUuid
    • Webinars still use meeting_uuid (not webinar_uuid)
    • Required for both signaling and media handshakes
    • See: Manual WebSocket
  5. Media Uses Split Data Connections

    • Audio=1, Video=2, Share=4, Transcript=8, Chat=16
    • Open one data WebSocket per selected media type using its matching URL
    • Never send combined values or the deprecated media_type: 32 in a data handshake
    • See: Media Types
  6. Startup Audio Buffering is a Signaling Choice

    • buffer_data belongs in SIGNALING_HAND_SHAKE_REQ
    • default true can replay up to 60s of startup audio
    • set false for live streaming or live-only startup behavior
    • See: Connection
  7. Screen Share is SEPARATE from Video

    • Different msg_type (16 vs 15)
    • Different media flag (4 vs 2)
    • Must subscribe separately
    • See: Media Types

Quick Reference

"Connection fails"

-> Common Issues

"Duplicate connections"

-> Webhook timing

"No audio/video data"

-> Media Types - Check configuration

"How do I implement manually?"

-> Manual WebSocket

"What message types exist?"

-> Data Types

"How do I integrate AI?"

-> AI Integration


Document Version

Based on Zoom RTMS SDK v1.x and official documentation as of 2026.


Happy coding!

Remember: Start with SDK Quickstart for the fastest path, or Manual WebSocket if you need full control.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

コメント

ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。

まだコメントはありません。最初のコメントを書いてみませんか。

送信するとすぐに公開されます。メールアドレスや電話番号などの個人情報は書かないでください。URL は 2 つまでです。

0 / 1000 文字

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

同じリポジトリのスキル

Zoom Contact Center skill pack for Contact Center apps, web embeds, and native mobile SDK integrations. Use for lifecycle patterns, engagement context/state handling, campaigns, callbacks, and version-drift troubleshooting.

日本語の概要は準備中です。原文の説明を表示しています。

zoom/skills852026年10月20日 更新

Zoom Contact Center SDK for Android. Use for native Android chat/video/ZVA/scheduled callback integrations, campaign mode, service lifecycle, and rejoin handling.

日本語の概要は準備中です。原文の説明を表示しています。

zoom/skills852026年10月20日 更新

Zoom Contact Center SDK for iOS. Use for native iOS chat/video/ZVA/scheduled callback integrations, app lifecycle bridging, rejoin flow, and callback handling.

日本語の概要は準備中です。原文の説明を表示しています。

zoom/skills852026年10月20日 更新

Zoom Contact Center SDK for Web. Use for web chat/video/campaign embeds, engagement event handling, app-context integrations, and Smart Embed postMessage workflows.

日本語の概要は準備中です。原文の説明を表示しています。

zoom/skills852026年10月20日 更新

decisions

無料

Zoom AI Services Decisions for typed predicates, constrained classification, ordered scoring, probability-aware routing, and inline image comparison. Use when building or debugging Decisions requests, production x-api-key authentication, standard/pro model selection, Boolean choices, or score-label normalization.

日本語の概要は準備中です。原文の説明を表示しています。

zoom/skills852026年10月20日 更新

Zoom Meeting SDK for Linux - C++ headless meeting bots with raw audio/video access, transcription, recording, and AI integration for server-side automation

日本語の概要は準備中です。原文の説明を表示しています。

zoom/skills852026年10月20日 更新

zoom のスキルをすべて見る

このスキルの問題を報告する