Skill 126 · Zoom Meeting SDK Windows
Subchapter 126.3
references/windows-reference.mdMarkdown23 KBView on GitHub
Complete reference for Zoom Meeting SDK on Windows including dependencies, Visual Studio setup, and troubleshooting.
# Install vcpkg (package manager for C++)
git clone https://github.com/Microsoft/vcpkg.git C:\vcpkg
cd C:\vcpkg
.\bootstrap-vcpkg.bat
.\vcpkg integrate install# For x64
.\vcpkg install jsoncpp:x64-windows
.\vcpkg install curl:x64-windows
# For x86
.\vcpkg install jsoncpp:x86-windows
.\vcpkg install curl:x86-windows
# Set default triplet (optional)
$env:VCPKG_DEFAULT_TRIPLET = "x64-windows"Required workloads in Visual Studio Installer:
Create a new C++ Console Application, then configure:
General → Additional Include Directories:
$(SolutionDir)SDK\$(PlatformTarget)\h
$(SolutionDir)SDK\$(PlatformTarget)\h\meeting_service_components
$(SolutionDir)SDK\$(PlatformTarget)\h\rawdata
C:\vcpkg\packages\jsoncpp_$(PlatformTarget)-windows\include
C:\vcpkg\packages\curl_$(PlatformTarget)-windows\includePreprocessor → Preprocessor Definitions:
WIN32
_DEBUG (for Debug config)
_CONSOLE
_UNICODE
UNICODE
%(PreprocessorDefinitions)Code Generation → Runtime Library:
General → Additional Library Directories:
$(SolutionDir)SDK\$(PlatformTarget)\lib
C:\vcpkg\packages\jsoncpp_$(PlatformTarget)-windows\lib
C:\vcpkg\packages\curl_$(PlatformTarget)-windows\libInput → Additional Dependencies:
sdk.lib
ws2_32.lib
%(AdditionalDependencies)Post-Build Event → Command Line:
xcopy /Y /D "$(SolutionDir)SDK\$(PlatformTarget)\bin\*.*" "$(OutDir)"
xcopy /Y /D "$(ProjectDir)config.json" "$(OutDir)"This copies all SDK DLLs and config.json to your output directory.
cmake_minimum_required(VERSION 3.16)
project(ZoomMeetingSDK CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Set output directories
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
# Find vcpkg packages
find_package(jsoncpp CONFIG REQUIRED)
find_package(CURL REQUIRED)
# Include directories
include_directories(
${CMAKE_SOURCE_DIR}/SDK/x64/h
${CMAKE_SOURCE_DIR}/SDK/x64/h/meeting_service_components
${CMAKE_SOURCE_DIR}/SDK/x64/h/rawdata
)
# Link directories
link_directories(
${CMAKE_SOURCE_DIR}/SDK/x64/lib
${CMAKE_SOURCE_DIR}/SDK/x64/bin
)
# Source files
add_executable(YourApp
YourApp.cpp
AuthServiceEventListener.cpp
MeetingServiceEventListener.cpp
NetworkConnectionHandler.cpp
WebService.cpp
# Add more source files as needed
)
# Link libraries
target_link_libraries(YourApp
sdk.lib
JsonCpp::JsonCpp
CURL::libcurl
)
# Copy DLLs to output directory
add_custom_command(TARGET YourApp POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${CMAKE_SOURCE_DIR}/SDK/x64/bin"
$<TARGET_FILE_DIR:YourApp>
)
# Copy config.json
configure_file(
${CMAKE_SOURCE_DIR}/config.json
${CMAKE_SOURCE_DIR}/bin/config.json
COPYONLY
){
"sdk_jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"meeting_number": "1234567890",
"passcode": "abc123",
"video_source": "Big_Buck_Bunny_720_10s_1MB.mp4",
"zak": ""
}#include <fstream>
#include <json/json.h>
void LoadConfig() {
std::ifstream f("config.json");
Json::Value config;
if (f.is_open()) {
try {
f >> config;
// Extract values
std::string jwt = config["sdk_jwt"].asString();
std::string meetingNum = config["meeting_number"].asString();
std::string passcode = config["passcode"].asString();
// Convert to wstring for SDK
sdk_jwt = std::wstring(jwt.begin(), jwt.end());
meeting_number = std::stoull(meetingNum);
// ...
} catch (const std::exception& e) {
std::cerr << "Error parsing config.json: " << e.what() << std::endl;
}
} else {
std::cerr << "config.json not found" << std::endl;
}
}#include "AuthServiceEventListener.h"
#include <iostream>
AuthServiceEventListener::AuthServiceEventListener(void (*onComplete)())
: onAuthComplete(onComplete) {}
void AuthServiceEventListener::onAuthenticationReturn(AuthResult ret) {
switch (ret) {
case AUTHRET_SUCCESS:
std::cout << "Authentication successful" << std::endl;
if (onAuthComplete) onAuthComplete();
break;
case AUTHRET_KEYORSECRETEMPTY:
std::cerr << "SDK Key or Secret is empty" << std::endl;
break;
case AUTHRET_JWTTOKENWRONG:
std::cerr << "JWT token is invalid" << std::endl;
break;
case AUTHRET_OVERTIME:
std::cerr << "Authentication timeout" << std::endl;
break;
default:
std::cerr << "Authentication failed: " << ret << std::endl;
}
}
void AuthServiceEventListener::onLoginReturnWithReason(
LOGINSTATUS ret,
IAccountInfo* info,
LoginFailReason reason) {
// Handle login status
}
void AuthServiceEventListener::onLogout() {
std::cout << "Logged out" << std::endl;
}
void AuthServiceEventListener::onZoomIdentityExpired() {
std::cout << "Zoom identity expired" << std::endl;
}
void AuthServiceEventListener::onZoomAuthIdentityExpired() {
std::cout << "Zoom auth identity expired - need to re-authenticate" << std::endl;
}#include "MeetingServiceEventListener.h"
#include <iostream>
MeetingServiceEventListener::MeetingServiceEventListener(
void (*onJoined)(),
void (*onEnded)(),
void (*onInMeeting)()
) : onMeetingJoined(onJoined),
onMeetingEnded(onEnded),
onInMeetingCallback(onInMeeting) {}
void MeetingServiceEventListener::onMeetingStatusChanged(
MeetingStatus status,
int iResult) {
switch (status) {
case MEETING_STATUS_IDLE:
std::cout << "Meeting status: IDLE" << std::endl;
break;
case MEETING_STATUS_CONNECTING:
std::cout << "Meeting status: CONNECTING" << std::endl;
if (onMeetingJoined) onMeetingJoined();
break;
case MEETING_STATUS_WAITINGFORHOST:
std::cout << "Meeting status: WAITING FOR HOST" << std::endl;
break;
case MEETING_STATUS_INMEETING:
std::cout << "Meeting status: IN MEETING" << std::endl;
if (onInMeetingCallback) onInMeetingCallback();
break;
case MEETING_STATUS_DISCONNECTING:
std::cout << "Meeting status: DISCONNECTING" << std::endl;
break;
case MEETING_STATUS_RECONNECTING:
std::cout << "Meeting status: RECONNECTING" << std::endl;
break;
case MEETING_STATUS_FAILED:
std::cerr << "Meeting status: FAILED (code: " << iResult << ")" << std::endl;
if (onMeetingEnded) onMeetingEnded();
break;
case MEETING_STATUS_ENDED:
std::cout << "Meeting status: ENDED" << std::endl;
if (onMeetingEnded) onMeetingEnded();
break;
default:
std::cout << "Meeting status: UNKNOWN (" << status << ")" << std::endl;
}
}
void MeetingServiceEventListener::onMeetingStatisticsWarningNotification(
StatisticsWarningType type) {
std::cout << "Meeting statistics warning: " << type << std::endl;
}
void MeetingServiceEventListener::onMeetingParameterNotification(
const MeetingParameter* param) {
if (param) {
std::cout << "Meeting parameter notification" << std::endl;
}
}
void MeetingServiceEventListener::onSuspendParticipantsActivities() {
std::cout << "Participants activities suspended" << std::endl;
}
void MeetingServiceEventListener::onAICompanionActiveChangeNotice(bool isActive) {
std::cout << "AI Companion " << (isActive ? "activated" : "deactivated") << std::endl;
}#include "MeetingRecordingCtrlEventListener.h"
#include <iostream>
void MeetingRecordingCtrlEventListener::onRecordingStatus(RecordingStatus status) {
switch (status) {
case Recording_Start:
std::cout << "Recording started" << std::endl;
break;
case Recording_Stop:
std::cout << "Recording stopped" << std::endl;
break;
case Recording_DiskFull:
std::cerr << "Recording stopped - disk full" << std::endl;
break;
case Recording_Pause:
std::cout << "Recording paused" << std::endl;
break;
case Recording_Connecting:
std::cout << "Recording connecting" << std::endl;
break;
default:
std::cout << "Recording status: " << status << std::endl;
}
}
void MeetingRecordingCtrlEventListener::onRecordPrivilegeChanged(bool bCanRec) {
std::cout << "Recording privilege: " << (bCanRec ? "granted" : "revoked") << std::endl;
}
void MeetingRecordingCtrlEventListener::onCloudRecordingStatus(RecordingStatus status) {
std::cout << "Cloud recording status: " << status << std::endl;
}
void MeetingRecordingCtrlEventListener::onRecordingPrivilegeRequestStatus(
RequestRecPrivilegeStatus status) {
std::cout << "Recording privilege request status: " << status << std::endl;
}
void MeetingRecordingCtrlEventListener::onLocalRecordingPrivilegeRequestStatus(
RequestLocalRecordingStatus status) {
std::cout << "Local recording privilege request status: " << status << std::endl;
}
void MeetingRecordingCtrlEventListener::onLocalRecordingPrivilegeResponse(
bool bAccept) {
std::cout << "Local recording privilege "
<< (bAccept ? "accepted" : "denied") << std::endl;
}
void MeetingRecordingCtrlEventListener::onCustomizedLocalRecordingSourceNotification(
ICustomizedLocalRecordingLayoutHelper* layout_helper) {
std::cout << "Customized local recording source notification" << std::endl;
}Raw data access requires one of:
bool CheckAndStartRawRecording() {
IMeetingRecordingController* recordCtrl =
meetingService->GetMeetingRecordingController();
if (!recordCtrl) {
std::cerr << "Failed to get recording controller" << std::endl;
return false;
}
SDKError canStart = recordCtrl->CanStartRecording(false, 0);
if (canStart == SDKERR_SUCCESS) {
SDKError err = recordCtrl->StartRawRecording();
if (err == SDKERR_SUCCESS) {
std::cout << "Raw recording started" << std::endl;
return true;
} else {
std::cerr << "StartRawRecording failed: " << err << std::endl;
return false;
}
} else {
std::cout << "Need host/cohost/recording permission" << std::endl;
std::cout << "Requesting recording privilege..." << std::endl;
recordCtrl->RequestLocalRecordingPrivilege();
return false;
}
}// Available resolutions
videoHelper->setRawDataResolution(ZoomSDKResolution_90P); // 160x90
videoHelper->setRawDataResolution(ZoomSDKResolution_180P); // 320x180
videoHelper->setRawDataResolution(ZoomSDKResolution_360P); // 640x360
videoHelper->setRawDataResolution(ZoomSDKResolution_720P); // 1280x720
videoHelper->setRawDataResolution(ZoomSDKResolution_1080P); // 1920x1080struct tagInitParam {
const wchar_t* strWebDomain; // "https://zoom.us"
const wchar_t* strSupportUrl; // Support URL
SDK_LANGUAGE_ID emLanguageID; // LANGUAGE_English, etc.
bool enableGenerateDump; // Enable crash dump
bool enableLogByDefault; // Enable logging
unsigned int uiLogFileSize; // Log file size (MB, default: 5)
const wchar_t* strLogFileFolder; // Custom log folder path
RawDataOptions rawdataOpts; // Raw data options
ConfigurableOptions obConfigOpts; // Config options
};| Method | Description | Returns |
|---|---|---|
SetEvent(IAuthServiceEvent*) | Set auth callback | SDKError |
SDKAuth(AuthContext&) | Authenticate with JWT | SDKError |
GetAuthResult() | Get auth status | AuthResult |
LogOut() | Logout | SDKError |
GetAccountInfo() | Get account info | IAccountInfo* |
| Method | Description | Returns |
|---|---|---|
SetEvent(IMeetingServiceEvent*) | Set meeting callback | SDKError |
Join(JoinParam&) | Join meeting | SDKError |
Start(StartParam&) | Start meeting | SDKError |
Leave(LeaveMeetingCmd) | Leave meeting | SDKError |
GetMeetingStatus() | Get status | MeetingStatus |
GetMeetingInfo() | Get meeting info | IMeetingInfo* |
GetMeetingVideoController() | Video control | IMeetingVideoController* |
GetMeetingAudioController() | Audio control | IMeetingAudioController* |
GetMeetingRecordingController() | Recording control | IMeetingRecordingController* |
GetMeetingParticipantsController() | Participants | IMeetingParticipantsController* |
GetMeetingChatController() | Chat control | IMeetingChatController* |
struct JoinParam4WithoutLogin {
UINT64 meetingNumber; // Meeting number
const wchar_t* userName; // Display name
const wchar_t* psw; // Meeting password
const wchar_t* vanityID; // Personal link name
const wchar_t* customer_key; // Customer key
const wchar_t* webinarToken; // Webinar token
const wchar_t* userZAK; // Zoom Access Key
const wchar_t* app_privilege_token; // App privilege token (for raw data)
const wchar_t* onBehalfToken; // On behalf token
bool isVideoOff; // Start with video off
bool isAudioOff; // Start with audio off
bool isDirectShareDesktop; // Share desktop directly
bool isAudioAutoConnect; // Auto-connect to audio
bool isAutoRecording; // Auto-start recording
};| Method | Description | Returns |
|---|---|---|
setRawDataResolution(ZoomSDKResolution) | Set resolution | SDKError |
subscribe(uint32_t userId, ZoomSDKRawDataType) | Subscribe to video | SDKError |
unSubscribe() | Unsubscribe | SDKError |
getResolution() | Get resolution | ZoomSDKResolution |
getSubscribeId() | Get user ID | uint32_t |
| Method | Description | Returns |
|---|---|---|
GetStreamWidth() | Video width | uint32_t |
GetStreamHeight() | Video height | uint32_t |
GetYBuffer() | Y plane buffer | char* |
GetUBuffer() | U plane buffer | char* |
GetVBuffer() | V plane buffer | char* |
GetBufferLen() | Total buffer length | uint32_t |
GetRotation() | Rotation angle | int |
Video Format:
width * height bytes(width/2) * (height/2) bytes(width/2) * (height/2) byteswidth * height * 1.5 bytes| Method | Description | Returns |
|---|---|---|
GetBuffer() | Audio buffer | char* |
GetBufferLen() | Buffer length (bytes) | uint32_t |
GetSampleRate() | Sample rate (Hz) | uint32_t |
GetChannelNum() | Number of channels | uint32_t |
| Code | Description |
|---|---|
SDKERR_SUCCESS | Success |
SDKERR_INVALID_PARAMETER | Invalid parameter |
SDKERR_UNINITIALIZE | SDK not initialized |
SDKERR_UNAUTHENTICATION | Not authenticated |
SDKERR_NO_PERMISSION | No permission |
SDKERR_NO_AUDIODEVICE_ISFOUND | No audio device |
SDKERR_NO_VIDEODEVICE_ISFOUND | No video device |
SDKERR_INTERNAL_ERROR | Internal error |
SDKERR_SERVICE_FAILED | Service failed |
SDKERR_MEMORY_FAILED | Memory allocation failed |
SDKERR_TOO_FREQUENT_CALL | API called too frequently |
SDKERR_WRONG_USAGE | Wrong API usage |
| Result | Description |
|---|---|
AUTHRET_SUCCESS | Authentication successful |
AUTHRET_KEYORSECRETEMPTY | Key or secret empty |
AUTHRET_JWTTOKENWRONG | JWT token invalid |
AUTHRET_OVERTIME | Operation timed out |
| Status | Description |
|---|---|
MEETING_STATUS_IDLE | No meeting |
MEETING_STATUS_CONNECTING | Connecting |
MEETING_STATUS_INMEETING | In meeting |
MEETING_STATUS_RECONNECTING | Reconnecting |
MEETING_STATUS_FAILED | Failed |
MEETING_STATUS_ENDED | Meeting ended |
MEETING_STATUS_WAITINGFORHOST | Waiting for host |
MEETING_STATUS_DISCONNECTING | Disconnecting |
Cause: jsoncpp include path not configured
Fix:
.\vcpkg install jsoncpp:x64-windowsC:\vcpkg\packages\jsoncpp_x64-windows\includeCause: sdk.lib not linked
Fix:
$(SolutionDir)SDK\$(PlatformTarget)\libsdk.libCause: DLLs not copied to output directory
Fix: Add Post-Build Event:
xcopy /Y /D "$(SolutionDir)SDK\$(PlatformTarget)\bin\*.*" "$(OutDir)"Cause: Invalid SDK initialization parameters or missing DLLs
Fix:
Cause: Invalid JWT token
Fix:
Cause: Invalid join parameters
Fix:
std::wstring userName = L"Bot User";
params.userName = userName.c_str();Cause: No recording permission
Fix:
RequestLocalRecordingPrivilege() to request permissionapp_privilege_token in JoinParam:
params.app_privilege_token = recording_token.c_str();onBehalfTokenCause: Mixed resolutions or incorrect parameters
Fix:
ffmpeg -video_size 1280x720 -pixel_format yuv420p -f rawvideo -i output.yuv output.mp4Cause: Wrong audio format parameters
Fix:
data->GetSampleRate()data->GetChannelNum()ffplay -f s16le -ar 32000 -ac 1 audio.pcmCause: Not in meeting or no recording permission
Fix:
MEETING_STATUS_INMEETING)StartRawRecording()CanStartRecording()void CleanSDK() {
// Unsubscribe from raw data
if (videoHelper) {
videoHelper->unSubscribe();
videoHelper = nullptr;
}
if (audioHelper) {
audioHelper->unSubscribe();
audioHelper = nullptr;
}
// Destroy services
if (authService) {
DestroyAuthService(authService);
authService = nullptr;
}
if (meetingService) {
DestroyMeetingService(meetingService);
meetingService = nullptr;
}
// Clean up SDK
CleanUPSDK();
}# Use Windows Server Core
FROM mcr.microsoft.com/windows/servercore:ltsc2022
# Install Visual C++ Redistributables
ADD https://aka.ms/vs/17/release/vc_redist.x64.exe C:\vcredist.exe
RUN C:\vcredist.exe /install /quiet /norestart
# Copy your application
WORKDIR C:\app
COPY SDK C:\app\SDK
COPY x64\Release\YourApp.exe C:\app\
COPY config.json C:\app\
CMD ["C:\\app\\YourApp.exe"]Note: Windows containers require Windows-based Docker host. GUI applications are supported but won’t display UI.
Important: Beginning March 2, 2026, apps joining meetings outside their account must be authorized.
Options:
app_privilege_token)userZAK)onBehalfToken)See bot-authentication.md (opens in a new tab) for details.
This file