This sample receives RTMS media through the official @zoom/rtms Node.js SDK and exposes an HTTP webhook endpoint for RTMS lifecycle events.
⚠️ Note: This workaround is temporary. The documentation is being updated, and this process will be simplified in the near future.
Follow these steps to get the app running manually for now:
-
Ensure CMake version 3.25.1 is installed on your development machine.
- This guide assumes Ubuntu, but macOS should be similar.
-
Clone the developer preview app:
git clone https://github.com/zoom/rtms-developer-preview-js
-
Inside that directory, manually create the following folder:
mkdir -p node_modules/@zoom
-
Navigate into the new folder and clone the SDK:
cd node_modules/@zoom git clone https://github.com/zoom/rtms -
Compile the SDK:
cd rtms npm install -
Go back to the root of the developer preview app and start it:
cd ../../../ node index.js
This simple app demonstrates integration with the Zoom Realtime Media Streams SDK for Node.js.
Important
Confidential under NDA - Do not distribute during developer preview
This document contains confidential information that requires an NDA. It is intended only for partners in the Zoom RTMS developer preview.
Participation in the RTMS Developer Preview, including access to and use of these materials, is subject to Zoom's Beta Program - Terms of Use.
Install the SDK from GitHub:
npm install github:zoom/rtmsThe Node.js SDK requires prebuilt binaries from the underlying C SDK:
npm run fetch -- your-token-goes-hereCopy the example environment file and fill in your credentials:
cp .env.example .envStart the application:
npm startTo receive webhooks from Zoom, expose your local server using ngrok:
ngrok http 8080Use the generated ngrok URL as your Zoom Marketplace webhook endpoint.
The SDK provides detailed control over audio and video processing. Use these parameters with setAudioParameters() and setVideoParameters() to match the naming scheme in our documentation:
client.setAudioParameters({
contentType: rtms.AudioContentType.RAW_AUDIO,
codec: rtms.AudioCodec.OPUS,
sampleRate: 16000,
channel: rtms.AudioChannel.MONO,
dataOpt: rtms.AudioDataOption.AUDIO_MIXED_STREAM,
duration: 20,
frameSize: 320
});client.setVideoParams({
contentType: rtms.VideoContentType.RAW_VIDEO,
codec: rtms.VideoCodec.H264,
resolution: rtms.VideoResolution.HD,
dataOpt: rtms.VideoDataOption.VIDEO_MIXED_GALLERY_VIEW,
fps: 30
});- ContentType: UNDEFINED, RTP, RAW_AUDIO, FILE_STREAM, TEXT
- Codec: UNDEFINED, L16, G711, G722, OPUS
- SampleRate: SR_8K, SR_16K, SR_32K, SR_48K
- Channel: MONO, STEREO
- DataOption: UNDEFINED, AUDIO_MIXED_STREAM, AUDIO_MULTI_STREAMS
- ContentType: UNDEFINED, RTP, RAW_VIDEO, FILE_STREAM, TEXT
- Codec: UNDEFINED, JPG, PNG, H264
- Resolution: SD, HD, FHD, QHD
- DataOption: UNDEFINED, VIDEO_SINGLE_ACTIVE_STREAM, VIDEO_MIXED_SPEAKER_VIEW, VIDEO_MIXED_GALLERY_VIEW
The project runs the official JavaScript RTMS SDK boilerplate. Its multi-stage Dockerfile keeps build tooling out of the final runtime image and does not hard-code a CPU architecture.
Build and run it from the rtms-samples repository root:
docker build -f boilerplate/working_sdk/Dockerfile -t rtms-boilerplate-working_sdk .
docker run --rm --env-file boilerplate/working_sdk/.env -e ZM_RTMS_PORT=8080 -p 8080:8080 rtms-boilerplate-working_sdkRun the build from the repository root because the Dockerfile uses repository-relative paths. Runtime secrets are supplied with --env-file and are excluded from the image build context.
Normal Zoom webhook deliveries are verified against the exact raw request body using
x-zm-signature and x-zm-request-timestamp. Configure ZM_RTMS_SECRET_TOKEN with the
Marketplace app's webhook Secret Token. Requests with missing, invalid, or stale
signatures are rejected; the default replay window is 300 seconds and can be changed
with WEBHOOK_TIMESTAMP_TOLERANCE_SECONDS.