Subchapter 118.3
linux.mdMarkdown11 KBView on GitHub
Embed Zoom meeting capabilities into Linux applications for headless meeting bots and server-side integrations.
Need help with authentication? See the zoom-oauth skill for JWT token generation.
The Linux SDK is a C++ native SDK designed for:
Download from Zoom Marketplace (opens in a new tab):
zoom-meeting-sdk-linux_x86_64-{version}.taryour-project/
demo/
include/h/ # SDK headers
lib/zoom_meeting_sdk/
libmeetingsdk.so
libmeetingsdk.so.1 # symlink
qt_libs/
json/translations.json
meeting_sdk_demo.cpp
CMakeLists.txt
config.txtCopy SDK files:
cp -r h/* demo/include/h/
cp lib*.so demo/lib/zoom_meeting_sdk/
cp -r qt_libs demo/lib/zoom_meeting_sdk/
cp translation.json demo/lib/zoom_meeting_sdk/json/
# Create required symlink
cd demo/lib/zoom_meeting_sdk/
ln -s libmeetingsdk.so libmeetingsdk.so.1Create config.txt:
meeting_number: "1234567890"
token: "YOUR_JWT_TOKEN"
meeting_password: "password123"
recording_token: ""
GetVideoRawData: "true"
GetAudioRawData: "true"
SendVideoRawData: "false"
SendAudioRawData: "false"cd demo
cmake -B build
cd build
make
cd ../bin
./meetingSDKDemo┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ InitSDK │───►│ AuthSDK │───►│ JoinMeeting │───►│ Raw Data │
│ │ │ (JWT) │ │ │ │ Subscribe │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
│ │
▼ ▼
OnAuthComplete onInMeeting
callback callback#include "zoom_sdk.h"
USING_ZOOM_SDK_NAMESPACE
void InitMeetingSDK() {
SDKError err(SDKERR_SUCCESS);
InitParam initParam;
initParam.strWebDomain = "https://zoom.us";
initParam.strSupportUrl = "https://zoom.us";
initParam.emLanguageID = LANGUAGE_English;
initParam.enableLogByDefault = true;
initParam.enableGenerateDump = true;
err = InitSDK(initParam);
if (err != SDKERR_SUCCESS) {
std::cerr << "Init meetingSdk:error" << std::endl;
}
}#include "auth_service_interface.h"
IAuthService* m_pAuthService;
void OnAuthenticationComplete() {
JoinMeeting(); // Called on successful auth
}
void AuthMeetingSDK() {
CreateAuthService(&m_pAuthService);
m_pAuthService->SetEvent(
new AuthServiceEventListener(&OnAuthenticationComplete)
);
AuthContext param;
param.jwt_token = token.c_str(); // Your JWT token
m_pAuthService->SDKAuth(param);
}#include "meeting_service_interface.h"
IMeetingService* m_pMeetingService;
ISettingService* m_pSettingService;
void JoinMeeting() {
CreateMeetingService(&m_pMeetingService);
CreateSettingService(&m_pSettingService);
// Set event listeners
m_pMeetingService->SetEvent(
new MeetingServiceEventListener(&onMeetingJoined, &onMeetingEnds, &onInMeeting)
);
// Prepare join parameters
JoinParam joinParam;
joinParam.userType = SDK_UT_WITHOUT_LOGIN;
JoinParam4WithoutLogin& params = joinParam.param.withoutloginuserJoin;
params.meetingNumber = std::stoull(meeting_number);
params.userName = "BotUser";
params.psw = meeting_password.c_str();
params.isVideoOff = false;
params.isAudioOff = false;
m_pMeetingService->Join(joinParam);
}#include "rawdata/rawdata_renderer_interface.h"
#include "rawdata/zoom_rawdata_api.h"
class ZoomSDKRenderer : public IZoomSDKRendererDelegate {
public:
void onRawDataFrameReceived(YUVRawDataI420* data) override {
// YUV420 (I420) format - contiguous planar data (no strides)
int width = data->GetStreamWidth();
int height = data->GetStreamHeight();
// Y plane: width * height bytes
outputFile.write(data->GetYBuffer(), width * height);
// U plane: (width/2) * (height/2) bytes
outputFile.write(data->GetUBuffer(), (width / 2) * (height / 2));
// V plane: (width/2) * (height/2) bytes
outputFile.write(data->GetVBuffer(), (width / 2) * (height / 2));
}
void onRawDataStatusChanged(RawDataStatus status) override {}
void onRendererBeDestroyed() override {}
};
// Subscribe after joining
IZoomSDKRenderer* videoHelper;
ZoomSDKRenderer* videoSource = new ZoomSDKRenderer();
createRenderer(&videoHelper, videoSource);
videoHelper->setRawDataResolution(ZoomSDKResolution_720P);
videoHelper->subscribe(userID, RAW_DATA_TYPE_VIDEO);#include "rawdata/rawdata_audio_helper_interface.h"
class ZoomSDKAudioRawData : public IZoomSDKAudioRawDataDelegate {
public:
void onMixedAudioRawDataReceived(AudioRawData* data) override {
// Process PCM audio (mixed from all participants)
pcmFile.write((char*)data->GetBuffer(), data->GetBufferLen());
}
void onOneWayAudioRawDataReceived(AudioRawData* data, uint32_t node_id) override {
// Process audio from specific participant
}
};
// Subscribe after joining
IZoomSDKAudioRawDataHelper* audioHelper = GetAudioRawdataHelper();
audioHelper->subscribe(new ZoomSDKAudioRawData());#include <glib.h>
GMainLoop* loop;
gboolean timeout_callback(gpointer data) {
return TRUE; // Keep running
}
int main(int argc, char* argv[]) {
InitMeetingSDK();
AuthMeetingSDK();
loop = g_main_loop_new(NULL, FALSE);
g_timeout_add(1000, timeout_callback, loop);
g_main_loop_run(loop);
return 0;
}| Example | Description |
|---|---|
| SkeletonExample | Minimal join meeting - start here |
| GetRawVideoAndAudioExample | Subscribe to raw audio/video streams |
| GetRawVideoAndAudioAPIExample | API-based raw data access |
| SendRawVideoAndAudioExample | Send custom video/audio as virtual camera/mic |
| ChatExample | In-meeting chat functionality |
| BreakoutExample | Breakout room management |
| AllInOneExample | Complete demo with all features |
| SendRawVideoAndAudioWithRTMSExample | Raw data with RTMS integration |
| Repository | Description |
|---|---|
| meetingsdk-headless-linux-sample (opens in a new tab) | Official headless bot with Docker |
| meetingsdk-linux-raw-recording-sample (opens in a new tab) | Raw audio/video access |
Raw YUV/PCM files have no headers - you must specify format explicitly.
ffplay -video_size 640x360 -pixel_format yuv420p -f rawvideo video.yuvffmpeg -video_size 640x360 -pixel_format yuv420p -f rawvideo -i video.yuv -c:v libx264 output.mp4ffplay -f s16le -ar 32000 -ac 1 audio.pcmffmpeg -f s16le -ar 32000 -ac 1 -i audio.pcm output.wavffmpeg -video_size 640x360 -pixel_format yuv420p -f rawvideo -i video.yuv \
-f s16le -ar 32000 -ac 1 -i audio.pcm \
-c:v libx264 -c:a aac -shortest output.mp4Key flags:
| Flag | Description |
|---|---|
-video_size WxH | Frame dimensions (check output filename) |
-pixel_format yuv420p | I420/YUV420 planar format |
-f rawvideo | Raw video input (no container) |
-f s16le | Signed 16-bit little-endian PCM |
-ar 32000 | Sample rate (Zoom uses 32kHz) |
-ac 1 | Mono (use -ac 2 for stereo) |
Note: These are general patterns - specific methods/types may vary by SDK version.
SDK event listener interfaces (IMeetingServiceEvent, IMeetingParticipantsCtrlEvent, etc.) have many pure virtual methods. You must implement ALL of them, even with empty bodies, or you’ll get “invalid new-expression of abstract class type” errors. Always check the SDK headers for the complete list.
Some SDK headers don’t include their own dependencies. If you encounter undefined type errors (like AudioType or time_t), try:
<ctime>, <cstdint>) before SDK headersReference samples may have outdated method names. Always verify against the actual SDK header files - they are the authoritative source.
Important: Beginning March 2, 2026, apps joining meetings outside their account must be authorized.
Use one of:
app_privilege_token in JoinParam)userZAK in JoinParam)onBehalfToken in JoinParam)