Required - Your Zoom OAuth credentials

The Realtime Media Streams (RTMS) SDK provides bindings to receive real-time audio, video, and transcript streams from Zoom Meetings. The RTMS SDK simplifies the process of connecting to RTMS streams, processing realtime media data, and handling session events.

  • Easily receive structured data from Zoom meetings
  • Process audio, video, and transcript data with simple interfaces
  • Receive participant and session updates with automatic event handling
  • Handle webhook events with simplified event subscription and processing
  • Manage multiple concurrent streams for enterprise-scale applications

Create the .env file

So that the RTMS server can communicate with your app, you need to create a .env file. Create a file called .env and add the following.

# Required - Your Zoom OAuth credentials
ZM_RTMS_CLIENT=your_client_id
ZM_RTMS_SECRET=your_client_secret
# Optional - Webhook server configuration
ZM_RTMS_PORT=8080
ZM_RTMS_PATH=/webhook
# Optional - Logging configuration
ZM_RTMS_LOG_LEVEL=debug          # error, warn, info, debug, trace
ZM_RTMS_LOG_FORMAT=progressive    # progressive or json
ZM_RTMS_LOG_ENABLED=true          # true or false

To get started with the RTMS SDK, choose the language and platform that best fits your needs.

RTMS Node.js SDK

The RTMS Node.js SDK provides access to real-time audio, video, and transcript data from Zoom meetings. It offers webhook integration, client-based, and singleton approaches for connecting to meetings.

Install the SDK

npm install @zoom/rtms

Use the SDK

Webhook integration (Recommended)

Easily respond to webhook events and connect to RTMS using the onWebhookEvent.

import rtms from "@zoom/rtms";
// CommonJS
// const rtms = require('@zoom/rtms').default;
rtms.onWebhookEvent(({ event, payload }) => {
    // Event name varies by product: "meeting.rtms_started", "session.rtms_started", etc.
    if (event !== "meeting.rtms_started") return;
    const client = new rtms.Client();
    client.onAudioData((data, timestamp, metadata) => {
        console.log(
            `Received audio: ${data.length} bytes from ${metadata.userName}`,
        );
    });
    client.join(payload);
});

Class-based approach

If your application requires multiple concurrent connections or advanced control.

import rtms from "@zoom/rtms";
const client = new rtms.Client();
client.onAudioData((data, timestamp, metadata) => {
    console.log(`Received audio: ${data.length} bytes`);
});
client.join({
    meeting_uuid: "your_meeting_uuid",
    rtms_stream_id: "your_stream_id",
    server_urls: "wss://example.zoom.us",
});

Global singleton

For applications that only require a single stream.

import rtms from "@zoom/rtms";
rtms.onAudioData((data, timestamp, metadata) => {
    console.log(`Received audio from ${metadata.userName}`);
});
rtms.join({
    meeting_uuid: "your_meeting_uuid",
    rtms_stream_id: "your_stream_id",
    server_urls: "wss://rtms.zoom.us",
});

RTMS C++ SDK

The RTMS C++ SDK provides high-performance access to RTMS streams with minimal overhead. Use it if your applications require low-latency processing or integration with existing C++ codebases. For more information, see the rtms-sdk-cpp GitHub Repository

Supported Platforms

  • Linux: Dynamic library (.so file)
  • macOS: Framework and dylib files

Installation and Setup

The C++ SDK is distributed as compiled libraries. Contact Zoom Developer Support or connect with us on the Developer Forum for access to the SDK files and detailed integration instructions.

Basic Usage

The following code demonstrates the basic implementation of RTMS for processing audio and transcript data using the C++ SDK.

#include "rtms_sdk.h"
class MyRTMSSink : public rtms_sdk_sink {
public:
    virtual void on_audio_data(unsigned char *data, int size,
                              uint64_t timestamp, struct rtms_metadata *md) {
        printf("Audio from %s: %d bytes at %lu\n",
               md->user_name, size, timestamp);
    }
    virtual void on_transcript_data(unsigned char *data, int size,
                                   uint64_t timestamp, struct rtms_metadata *md) {
        printf("[%s]: %s\n", md->user_name, data);
    }
};
int main() {
    // Initialize SDK
    rtms_sdk_provider::instance()->init("./cert/ca.crt");
    // Create and configure
    MyRTMSSink *sink = new MyRTMSSink;
    rtms_sdk *sdk = rtms_sdk_provider::instance()->create_sdk();
    sdk->config(NULL, SDK_ALL, 0);
    // Connect to meeting
    sdk->open(sink);
    sdk->join(meeting_uuid, stream_id, signature, server_url, 10000);
    // Process data
    while (running) {
        sdk->poll();
    }
    return 0;
}

RTMS Python SDK

The RTMS Python SDK provides access to real-time audio, video, and transcript data from Zoom meetings. It offers webhook integration for connecting to meetings.

Set up the environment

Create a virtual environment and install dependencies.

# Create virtual environment
python3 -m venv .venv
# Activate virtual environment
source .venv/bin/activate  # On Windows: .venv\Scripts\activate
# Install dependencies
pip install python-dotenv

Install the SDK

Check the Python version.

python3 --version

Install from PyPI.

pip install rtms

Use the SDK

Webhook integration

Easily respond to webhook events and connect to RTMS using the onWebhookEvent.

#!/usr/bin/env python3
import rtms
import signal
import sys
from dotenv import load_dotenv
load_dotenv()
client = rtms.Client()
# Graceful shutdown handler
def signal_handler(sig, frame):
    print('\nShutting down gracefully...')
    client.leave()
    sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
# Webhook event handler
@client.on_webhook_event()
def handle_webhook(payload):
    if payload.get('event') == 'meeting.rtms_started':
        rtms_payload = payload.get('payload', {})
        client.join(
            meeting_uuid=rtms_payload.get('meeting_uuid'),
            rtms_stream_id=rtms_payload.get('rtms_stream_id'),
            server_urls=rtms_payload.get('server_urls'),
            signature=rtms_payload.get('signature')
        )
# Callback handlers
@client.onJoinConfirm
def on_join(reason):
    print(f'Joined meeting: {reason}')
@client.onTranscriptData
def on_transcript(data, size, timestamp, metadata):
    text = data.decode('utf-8')
    print(f'[{metadata.userName}]: {text}')
@client.onLeave
def on_leave(reason):
    print(f'Left meeting: {reason}')
if __name__ == '__main__':
    print('Webhook server running on http://localhost:8080')
    import time
    while True:
        # Process queued join requests from webhook thread
        client._process_join_queue()
        # Poll for SDK events
        client._poll_if_needed()
        time.sleep(0.01)