Setting the file. One moment.
Session Join Pattern · Video Sdk/windows · anthropics/knowledge-work-plugins · Skills Docs
Complete working code for initializing the SDK and joining a session.
ContentsBack to the top of the page 22
Validate Data
Tech Debt
62
Recruiting Pipeline
71
Vendor Check
125
Zoom Meeting SDK Web
88
Vendor Review
181
Create An Asset
Video Sdk/web
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ InitSDK │───►│ AddListener│───►│ JoinSession │───►│ onSessionJoin│
│ │ │ (delegate) │ │ (JWT) │ │ callback │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
Then connect audio in the callback:
The IZoomVideoSDKDelegate interface has 80+ pure virtual methods. All must be implemented , even if empty.
TL;DR : Initialize → Add delegate → Join with audioOption.connect = false → Run message loop → Connect audio in onSessionJoin.
examples/session-join-pattern.md
nullptr
;
bool g_inSession = false ;
bool g_exit = false ;
// Configuration
std ::wstring g_jwt;
std ::wstring g_sessionName;
std ::wstring g_sessionPassword;
std ::wstring g_userName;
//─────────────────────────────────────────────────────────────────────────────
// DELEGATE IMPLEMENTATION
//─────────────────────────────────────────────────────────────────────────────
class MyDelegate : public IZoomVideoSDKDelegate {
public:
// === SESSION LIFECYCLE ===
void onSessionJoin () override {
std ::cout << "[EVENT] Session joined successfully!" << std ::endl;
g_inSession = true ;
// Connect audio
IZoomVideoSDKAudioHelper * audioHelper = g_sdk-> getAudioHelper ();
if (audioHelper) {
audioHelper-> startAudio ();
std ::cout << "[ACTION] Audio connected" << std ::endl;
}
// Start video
IZoomVideoSDKVideoHelper * videoHelper = g_sdk-> getVideoHelper ();
if (videoHelper) {
videoHelper-> startVideo ();
std ::cout << "[ACTION] Video started" << std ::endl;
}
}
void onSessionLeave () override {
std ::cout << "[EVENT] Session left" << std ::endl;
g_inSession = false ;
g_exit = true ;
}
void onError ( ZoomVideoSDKErrors errorCode , int detailErrorCode ) override {
std ::cout << "[ERROR] Code: " << errorCode
<< ", Detail: " << detailErrorCode << std ::endl;
}
// === USER EVENTS ===
void onUserJoin ( IZoomVideoSDKUserHelper * helper ,
IVideoSDKVector < IZoomVideoSDKUser * > * userList ) override {
for ( int i = 0 ; i < userList-> GetCount (); i ++ ) {
IZoomVideoSDKUser * user = userList-> GetItem (i);
std ::wcout << L"[EVENT] User joined: " << user-> getUserName () << std ::endl;
}
}
void onUserLeave ( IZoomVideoSDKUserHelper * helper ,
IVideoSDKVector < IZoomVideoSDKUser * > * userList ) override {
for ( int i = 0 ; i < userList-> GetCount (); i ++ ) {
IZoomVideoSDKUser * user = userList-> GetItem (i);
std ::wcout << L"[EVENT] User left: " << user-> getUserName () << std ::endl;
}
}
void onUserVideoStatusChanged ( IZoomVideoSDKVideoHelper * helper ,
IVideoSDKVector < IZoomVideoSDKUser * > * userList ) override {
for ( int i = 0 ; i < userList-> GetCount (); i ++ ) {
IZoomVideoSDKUser * user = userList-> GetItem (i);
bool isOn = user-> GetVideoPipe ()-> getVideoStatus ().isOn;
std ::wcout << L"[EVENT] Video " << (isOn ? L"ON" : L"OFF" )
<< L": " << user-> getUserName () << std ::endl;
}
}
void onUserAudioStatusChanged ( IZoomVideoSDKAudioHelper * helper ,
IVideoSDKVector < IZoomVideoSDKUser * > * userList ) override {
for ( int i = 0 ; i < userList-> GetCount (); i ++ ) {
IZoomVideoSDKUser * user = userList-> GetItem (i);
bool isMuted = user-> getAudioStatus ().isMuted;
std ::wcout << L"[EVENT] Audio " << (isMuted ? L"muted" : L"unmuted" )
<< L": " << user-> getUserName () << std ::endl;
}
}
// === CHAT ===
void onChatNewMessageNotify ( IZoomVideoSDKChatHelper * helper ,
IZoomVideoSDKChatMessage * msg ) override {
std ::wcout << L"[CHAT] " << msg-> getSendUser ()-> getUserName ()
<< L": " << msg-> getContent () << std ::endl;
}
// === REQUIRED EMPTY IMPLEMENTATIONS ===
// (All pure virtual methods must be implemented)
void onSessionLeave ( ZoomVideoSDKSessionLeaveReason reason ) override {}
void onSessionNeedPassword ( IZoomVideoSDKPasswordHandler * handler ) override {}
void onSessionPasswordWrong ( IZoomVideoSDKPasswordHandler * handler ) override {}
void onUserHostChanged ( IZoomVideoSDKUserHelper * helper , IZoomVideoSDKUser * user ) override {}
void onUserManagerChanged ( IZoomVideoSDKUser * user ) override {}
void onUserNameChanged ( IZoomVideoSDKUser * user ) override {}
void onUserActiveAudioChanged ( IZoomVideoSDKAudioHelper * helper , IVideoSDKVector < IZoomVideoSDKUser * > * list ) override {}
void onMixedAudioRawDataReceived ( AudioRawData * data ) override {}
void onOneWayAudioRawDataReceived ( AudioRawData * data , IZoomVideoSDKUser * user ) override {}
void onSharedAudioRawDataReceived ( AudioRawData * data ) override {}
void onUserShareStatusChanged ( IZoomVideoSDKShareHelper * helper , IZoomVideoSDKUser * user , IZoomVideoSDKShareAction * action ) override {}
void onShareContentChanged ( IZoomVideoSDKShareHelper * helper , IZoomVideoSDKUser * user , IZoomVideoSDKShareAction * action ) override {}
void onFailedToStartShare ( IZoomVideoSDKShareHelper * helper , IZoomVideoSDKUser * user ) override {}
void onShareContentSizeChanged ( IZoomVideoSDKShareHelper * helper , IZoomVideoSDKUser * user , IZoomVideoSDKShareAction * action ) override {}
void onLiveStreamStatusChanged ( IZoomVideoSDKLiveStreamHelper * helper , ZoomVideoSDKLiveStreamStatus status ) override {}
void onChatMsgDeleteNotification ( IZoomVideoSDKChatHelper * helper , const zchar_t * msgID , ZoomVideoSDKChatMessageDeleteType type ) override {}
void onChatPrivilegeChanged ( IZoomVideoSDKChatHelper * helper , ZoomVideoSDKChatPrivilegeType privilege ) override {}
void onLiveTranscriptionStatus ( ZoomVideoSDKLiveTranscriptionStatus status ) override {}
void onLiveTranscriptionMsgInfoReceived ( ILiveTranscriptionMessageInfo * info ) override {}
void onOriginalLanguageMsgReceived ( ILiveTranscriptionMessageInfo * info ) override {}
void onLiveTranscriptionMsgError ( ILiveTranscriptionLanguage * spoken , ILiveTranscriptionLanguage * transcript ) override {}
void onProxyDetectComplete () override {}
void onProxySettingNotification ( IZoomVideoSDKProxySettingHandler * handler ) override {}
void onSSLCertVerifiedFailNotification ( IZoomVideoSDKSSLCertificateInfo * info ) override {}
void onUserVideoNetworkStatusChanged ( ZoomVideoSDKNetworkStatus status , IZoomVideoSDKUser * user ) override {}
void onCallCRCDeviceStatusChanged ( ZoomVideoSDKCRCCallStatus status ) override {}
void onVideoCanvasSubscribeFail ( ZoomVideoSDKSubscribeFailReason reason , IZoomVideoSDKUser * user , void* handle ) override {}
void onShareCanvasSubscribeFail ( IZoomVideoSDKUser * user , void* handle , IZoomVideoSDKShareAction * action ) override {}
void onAnnotationHelperCleanUp ( IZoomVideoSDKAnnotationHelper * helper ) override {}
void onAnnotationPrivilegeChange ( IZoomVideoSDKUser * user , IZoomVideoSDKShareAction * action ) override {}
void onAnnotationHelperActived ( void* handle ) override {}
void onSendFileStatus ( IZoomVideoSDKSendFile * file , const FileTransferStatus & status ) override {}
void onReceiveFileStatus ( IZoomVideoSDKReceiveFile * file , const FileTransferStatus & status ) override {}
void onInviteByPhoneStatus ( PhoneStatus status , PhoneFailedReason reason ) override {}
void onCalloutJoinSuccess ( IZoomVideoSDKUser * user , const zchar_t * phoneNumber ) override {}
void onCameraControlRequestResult ( IZoomVideoSDKUser * user , bool approved ) override {}
void onCameraControlRequestReceived ( IZoomVideoSDKUser * user , ZoomVideoSDKCameraControlRequestType type , IZoomVideoSDKCameraControlRequestHandler * handler ) override {}
void onCommandReceived ( IZoomVideoSDKUser * sender , const zchar_t * cmd ) override {}
void onCommandChannelConnectResult ( bool success ) override {}
void onCloudRecordingStatus ( RecordingStatus status , IZoomVideoSDKRecordingConsentHandler * handler ) override {}
void onHostAskUnmute () override {}
void onUserRecordingConsent ( IZoomVideoSDKUser * user ) override {}
void onMultiCameraStreamStatusChanged ( ZoomVideoSDKMultiCameraStreamStatus status , IZoomVideoSDKUser * user , IZoomVideoSDKRawDataPipe * pipe ) override {}
void onMicSpeakerVolumeChanged ( unsigned int micVol , unsigned int speakerVol ) override {}
void onAudioDeviceStatusChanged ( ZoomVideoSDKAudioDeviceType type , ZoomVideoSDKAudioDeviceStatus status ) override {}
void onTestMicStatusChanged ( ZoomVideoSDK_TESTMIC_STATUS status ) override {}
void onSelectedAudioDeviceChanged () override {}
void onCameraListChanged () override {}
void onSpotlightVideoChanged ( IZoomVideoSDKVideoHelper * helper , IVideoSDKVector < IZoomVideoSDKUser * > * list ) override {}
void onVideoAlphaChannelStatusChanged ( bool isOn ) override {}
void onRemoteControlStatus ( IZoomVideoSDKUser * user , IZoomVideoSDKShareAction * action , ZoomVideoSDKRemoteControlStatus status ) override {}
void onRemoteControlRequestReceived ( IZoomVideoSDKUser * user , IZoomVideoSDKShareAction * action , IZoomVideoSDKRemoteControlRequestHandler * handler ) override {}
void onRemoteControlServiceInstallResult ( bool success ) override {}
void onBindIncomingLiveStreamResponse ( bool success , const zchar_t * streamKeyID ) override {}
void onUnbindIncomingLiveStreamResponse ( bool success , const zchar_t * streamKeyID ) override {}
void onIncomingLiveStreamStatusResponse ( bool success , IVideoSDKVector < IncomingLiveStreamStatus > * list ) override {}
void onStartIncomingLiveStreamResponse ( bool success , const zchar_t * streamKeyID ) override {}
void onStopIncomingLiveStreamResponse ( bool success , const zchar_t * streamKeyID ) override {}
void onUserWhiteboardShareStatusChanged ( IZoomVideoSDKUser * user , IZoomVideoSDKWhiteboardHelper * helper ) override {}
};
//─────────────────────────────────────────────────────────────────────────────
// CONFIGURATION
//─────────────────────────────────────────────────────────────────────────────
bool LoadConfig ( const std :: string & filename ) {
std :: ifstream file (filename);
if ( ! file. is_open ()) {
std ::cerr << "Cannot open " << filename << std ::endl;
return false ;
}
Json :: Value config;
file >> config;
std :: string jwt = config[ "jwt" ]. asString ();
std :: string sessionName = config[ "session_name" ]. asString ();
std :: string password = config. get ( "password" , "" ). asString ();
std :: string userName = config. get ( "user_name" , "Bot" ). asString ();
g_jwt = std :: wstring (jwt. begin (), jwt. end ());
g_sessionName = std :: wstring (sessionName. begin (), sessionName. end ());
g_sessionPassword = std :: wstring (password. begin (), password. end ());
g_userName = std :: wstring (userName. begin (), userName. end ());
return true ;
}
//─────────────────────────────────────────────────────────────────────────────
// SDK OPERATIONS
//─────────────────────────────────────────────────────────────────────────────
bool InitializeSDK () {
g_sdk = CreateZoomVideoSDKObj ();
if ( ! g_sdk) {
std ::cerr << "Failed to create SDK object" << std ::endl;
return false ;
}
ZoomVideoSDKInitParams params;
params.domain = L"https://zoom.us" ;
params.enableLog = true ;
params.logFilePrefix = L"zoom_video_sdk" ;
params.videoRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap;
params.shareRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap;
params.audioRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap;
ZoomVideoSDKErrors err = g_sdk-> initialize (params);
if (err != ZoomVideoSDKErrors_Success) {
std ::cerr << "SDK initialize failed: " << err << std ::endl;
return false ;
}
std ::cout << "SDK initialized successfully" << std ::endl;
return true ;
}
bool JoinSession () {
// Register delegate BEFORE joining
g_sdk-> addListener ( new MyDelegate ());
ZoomVideoSDKSessionContext context;
context.sessionName = g_sessionName. c_str ();
context.userName = g_userName. c_str ();
context.token = g_jwt. c_str ();
context.sessionPassword = g_sessionPassword. c_str ();
// IMPORTANT: Connect audio in onSessionJoin callback
context.audioOption.connect = false ;
context.audioOption.mute = true ;
context.videoOption.localVideoOn = false ;
IZoomVideoSDKSession * session = g_sdk-> joinSession (context);
if ( ! session) {
std ::cerr << "joinSession returned null" << std ::endl;
return false ;
}
std ::cout << "Join session initiated..." << std ::endl;
return true ;
}
void Cleanup () {
if (g_sdk) {
if (g_inSession) {
g_sdk-> leaveSession ( false );
}
g_sdk-> cleanup ();
DestroyZoomVideoSDKObj ();
g_sdk = nullptr ;
}
}
//─────────────────────────────────────────────────────────────────────────────
// MAIN
//─────────────────────────────────────────────────────────────────────────────
int main () {
// Initialize COM (required for some SDK features)
CoInitialize ( NULL );
// Load configuration
if ( ! LoadConfig ( "config.json" )) {
return 1 ;
}
// Initialize SDK
if ( ! InitializeSDK ()) {
return 1 ;
}
// Join session
if ( ! JoinSession ()) {
Cleanup ();
return 1 ;
}
// ═══════════════════════════════════════════════════════════════════════
// CRITICAL: Windows message loop
// Without this, callbacks will NEVER fire!
// ═══════════════════════════════════════════════════════════════════════
std ::cout << "Running message loop (Ctrl+C to exit)..." << std ::endl;
MSG msg;
while ( ! g_exit) {
// Process all pending Windows messages
while ( PeekMessage ( & msg, NULL , 0 , 0 , PM_REMOVE)) {
if (msg.message == WM_QUIT) {
g_exit = true ;
break ;
}
TranslateMessage ( & msg);
DispatchMessage ( & msg);
}
// Small sleep to avoid busy-waiting
std :: this_thread :: sleep_for ( std :: chrono :: milliseconds ( 10 ));
}
// Cleanup
Cleanup ();
CoUninitialize ();
std ::cout << "Exited cleanly" << std ::endl;
return 0 ;
}