Hi @jon.zoom ,
So, I can:
- remove the call to
customUIInit
from my onMeetingStatusChanged
implementation,
- remove the initialisation line
initParam.obConfigOpts.optionalFeatures = (1 << 5);
Then I can join the meeting successfullyPreformatted text
. Here’s sample code for reference. Note that I’m using mingw on windows 10.
Thanks,
Max
Output With Custom UI Handling
Starting app
Args 4
Meeting number #########
App key #########
App secret #########
Waiting for event
onAuthenticationReturn - 0
onAuthenticationReturn - AUTHRET_SUCCESS
Finished waiting for event
Creating Meeting Service
Joining the meeting
Joining meeting
Waiting for event
onLoginReturnWithReason - loginstatus 0, LoginFailReason 0
onMeetingStatusChanged - 7, result 0
MEETING_STATUS_ENDED
onMeetingStatusChanged - 1, result 0
MEETING_STATUS_CONNECTING
Setting up custom UI handling
Video container null on CreateVideoContainer: 7
Output Without Custom UI Handling
Starting app
Args 4
Meeting number #########
App key #########
App secret #########
Waiting for event
onAuthenticationReturn - 0
onAuthenticationReturn - AUTHRET_SUCCESS
Finished waiting for event
Creating Meeting Service
Joining the meeting
Joining meeting
Waiting for event
onMeetingStatusChanged - 1, result 0
MEETING_STATUS_CONNECTING
onMeetingStatusChanged - 2, result 0
MEETING_STATUS_WAITINGFORHOST
Reference Code
#include <windows.h>
#include <stdio.h>
#include <unistd.h>
#include <string>
#include "zoom_sdk.h"
#include "auth_service_interface.h"
#include "meeting_service_interface.h"
#include "setting_service_interface.h"
#include "meeting_service_components/meeting_configuration_interface.h"
#include "customized_ui/zoom_customized_ui.h"
#include "customized_ui/customized_ui_mgr.h"
#include "customized_ui/customized_video_container.h"
void customUIInit();
class CustomUIEventHandler : public ZOOM_SDK_NAMESPACE::ICustomizedUIMgrEvent, public ZOOM_SDK_NAMESPACE::ICustomizedVideoContainerEvent {
virtual void onVideoContainerDestroyed(ZOOM_SDK_NAMESPACE::ICustomizedVideoContainer* pContainer) {}
virtual void onShareRenderDestroyed(ZOOM_SDK_NAMESPACE::ICustomizedShareRender* pRender) {}
virtual void onRenderUserChanged(ZOOM_SDK_NAMESPACE::IVideoRenderElement *pElement, unsigned int userid) {}
virtual void onRenderDataTypeChanged(ZOOM_SDK_NAMESPACE::IVideoRenderElement *pElement, ZOOM_SDK_NAMESPACE::VideoRenderDataType dataType) { }
virtual void onLayoutNotification(RECT wnd_client_rect) { }
virtual void onVideoRenderElementDestroyed(ZOOM_SDK_NAMESPACE::IVideoRenderElement *pElement) { }
virtual void onWindowMsgNotification(UINT uMsg, WPARAM wParam, LPARAM lParam) { }
virtual void onSubscribeUserFail(ZOOM_SDK_NAMESPACE::ZoomSDKVideoSubscribeFailReason fail_reason, ZOOM_SDK_NAMESPACE::IVideoRenderElement* pElement) {}
};
class ZoomServiceEventHandler : public ZOOM_SDK_NAMESPACE::IAuthServiceEvent, public ZOOM_SDK_NAMESPACE::IMeetingServiceEvent {
public:
ZoomServiceEventHandler() {}
virtual ~ZoomServiceEventHandler() {}
virtual void onAuthenticationReturn(ZOOM_SDK_NAMESPACE::AuthResult ret) {
printf("onAuthenticationReturn - %d\n",ret);
waitForEventFlag = false;
errorFlag = true;
if (ret == ZOOM_SDK_NAMESPACE::AUTHRET_SUCCESS) {
printf("onAuthenticationReturn - AUTHRET_SUCCESS\n");
errorFlag = false;
} else if (ret == ZOOM_SDK_NAMESPACE::AUTHRET_JWTTOKENWRONG) {
printf("onAuthenticationReturn - AUTHRET_JWTTOKENWRONG\n");
} else if (ret == ZOOM_SDK_NAMESPACE::AUTHRET_KEYORSECRETWRONG) {
printf("onAuthenticationReturn - AUTHRET_KEYORSECRETWRONG\n");
} else {
printf("onAuthenticationReturn - OTHER ERROR\n");
}
}
virtual void onLoginRet(ZOOM_SDK_NAMESPACE::LOGINSTATUS ret, ZOOM_SDK_NAMESPACE::IAccountInfo* pAccountInfo) {
printf("onLoginRet\n");
}
virtual void onLoginReturnWithReason(ZOOM_SDK_NAMESPACE::LOGINSTATUS ret, ZOOM_SDK_NAMESPACE::IAccountInfo* pAccountInfo, ZOOM_SDK_NAMESPACE::LoginFailReason reason) {
printf("onLoginReturnWithReason - loginstatus %d, LoginFailReason %d\n",ret,reason);
}
virtual void onLogout() {
printf("onLogout\n");
}
virtual void onZoomIdentityExpired() {
printf("onZoomIdentityExpired\n");
}
virtual void onZoomAuthIdentityExpired() {
printf("onZoomAuthIdentityExpired\n");
}
// Meeting service
virtual void onMeetingStatusChanged(ZOOM_SDK_NAMESPACE::MeetingStatus status, int iResult=0) {
printf("onMeetingStatusChanged - %d, result %d\n",status,iResult);
if (status == ZOOM_SDK_NAMESPACE::MEETING_STATUS_IDLE) {
printf("MEETING_STATUS_IDLE\n");
} else if (status == ZOOM_SDK_NAMESPACE::MEETING_STATUS_CONNECTING) {
printf("MEETING_STATUS_CONNECTING\n");
// https://marketplace.zoom.us/docs/sdk/native-sdks/windows/mastering-sdk/custom-ui-feature/
// It is recommended to create the meeting service when you receive the onMeetingStatusChanged notification with the parameter MeetingStatus equalling ZOOM_SDK_NAMESPACE::MEETING_STATUS_CONNECTING. This allows you to work with the preview meeting function as well.
customUIInit();
} else if (status == ZOOM_SDK_NAMESPACE::MEETING_STATUS_WAITINGFORHOST) {
printf("MEETING_STATUS_WAITINGFORHOST\n");
} else if (status == ZOOM_SDK_NAMESPACE::MEETING_STATUS_INMEETING) {
printf("MEETING_STATUS_INMEETING\n");
} else if (status == ZOOM_SDK_NAMESPACE::MEETING_STATUS_DISCONNECTING) {
printf("MEETING_STATUS_DISCONNECTING\n");
} else if (status == ZOOM_SDK_NAMESPACE::MEETING_STATUS_RECONNECTING) {
printf("MEETING_STATUS_RECONNECTING\n");
} else if (status == ZOOM_SDK_NAMESPACE::MEETING_STATUS_FAILED) {
printf("MEETING_STATUS_FAILED\n");
} else if (status == ZOOM_SDK_NAMESPACE::MEETING_STATUS_ENDED) {
printf("MEETING_STATUS_ENDED\n");
} else if (status == ZOOM_SDK_NAMESPACE::MEETING_STATUS_UNKNOW) {
printf("MEETING_STATUS_UNKNOW\n");
} else if (status == ZOOM_SDK_NAMESPACE::MEETING_STATUS_LOCKED) {
printf("MEETING_STATUS_LOCKED\n");
} else if (status == ZOOM_SDK_NAMESPACE::MEETING_STATUS_UNLOCKED) {
printf("MEETING_STATUS_UNLOCKED\n");
} else if (status == ZOOM_SDK_NAMESPACE::MEETING_STATUS_IN_WAITING_ROOM) {
printf("MEETING_STATUS_IN_WAITING_ROOM\n");
} else {
printf("UNKNOWN\n");
}
}
virtual void onMeetingStatisticsWarningNotification (ZOOM_SDK_NAMESPACE::StatisticsWarningType type) {
printf("onMeetingStatusChanged\n");
}
virtual void onMeetingParameterNotification(const ZOOM_SDK_NAMESPACE::MeetingParameter* meeting_param) {
printf("onMeetingParameterNotification\n");
}
bool waitForEvent() {
printf("Waiting for event\n");
MSG msg;
int bRet;
waitForEventFlag = true;
while (((bRet = GetMessage(&msg, nullptr, 0, 0)) != 0)&&(waitForEventFlag)) {
//printf("Got message in windows event handler\n");
if (bRet == -1) {
//printf("Error event\n");
// handle the error and possibly exit
} else {
//printf("Not error event\n");
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
printf("Finished waiting for event\n");
return errorFlag;
}
private:
bool waitForEventFlag;
bool errorFlag;
};
ZoomServiceEventHandler zoomServiceEventHandler;
void customUIInit() {
// Custom UI stuff
ZOOM_SDK_NAMESPACE::SDKError err;
printf("Setting up custom UI handling\n");
CustomUIEventHandler customUIEventHandler;
ZOOM_SDK_NAMESPACE::ICustomizedUIMgr *uiManager;
err = ZOOM_SDK_NAMESPACE::CreateCustomizedUIMgr(&uiManager);
if (ZOOM_SDK_NAMESPACE::SDKERR_SUCCESS != err) {
printf("CreateCustomizedUIMgr failure - %d\n",err);
exit(-1);
}
uiManager->SetEvent(&customUIEventHandler);
HWND hParent = ::CreateWindowA("STATIC","dummy",WS_VISIBLE,0,0,200,200,NULL,NULL,NULL,NULL);
::SetWindowTextA(hParent,"Dummy Window!");
RECT rc;
GetWindowRect(hParent, &rc);
rc.bottom = rc.bottom - 10;
rc.top = rc.top + 10;
rc.right = rc.right - 10;
rc.left = rc.left + 10;
ZOOM_SDK_NAMESPACE::ICustomizedVideoContainer* videoContainer = NULL;
err = uiManager->CreateVideoContainer(&videoContainer, hParent, rc);
if (videoContainer == NULL) {
// We hit this condition, err is 7 = SDKERR_UNINITIALIZE
printf("Video container null on CreateVideoContainer: %d\n",err);
exit(0);
}
videoContainer->SetEvent(&customUIEventHandler);
videoContainer->Show();
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR , int nCmdShow) {
AllocConsole();
freopen("CONOUT$", "w", stdout);
printf("Starting app\n");
int argCount;
LPWSTR *szArgList = CommandLineToArgvW(GetCommandLineW(), &argCount);
printf("Args %d\n",argCount);
if (argCount != 4) {
printf("Usage: winpoc.exe <meeting id> <app key> <app secret>\n");
return 0;
}
std::wstring meetingNumber = szArgList[1];
std::wstring appKey = szArgList[2];
std::wstring appSecret = szArgList[3];
printf("Meeting number %ls\n",meetingNumber.c_str());
printf("App key %ls\n",appKey.c_str());
printf("App secret %ls\n",appSecret.c_str());
ZOOM_SDK_NAMESPACE::InitParam initParam;
initParam.strWebDomain = L"https://zoom.us";
initParam.strSupportUrl = L"https://zoom.us";
// Request Custom UI feature - see https://marketplace.zoom.us/docs/sdk/native-sdks/windows/mastering-sdk/custom-ui-feature/
initParam.obConfigOpts.optionalFeatures = (1 << 5);
initParam.enableLogByDefault = true;
//initParam.enableGenerateDump = true;
ZOOM_SDK_NAMESPACE::SDKError err = ZOOM_SDK_NAMESPACE::InitSDK(initParam);
if (ZOOM_SDK_NAMESPACE::SDKERR_SUCCESS != err) {
printf("failed InitSDK\n");
return -1;
}
ZOOM_SDK_NAMESPACE::IAuthService *authService;
err = ZOOM_SDK_NAMESPACE::CreateAuthService(&authService);
if (ZOOM_SDK_NAMESPACE::SDKERR_SUCCESS != err) {
printf("failed CreateAuthService\n");
return -1;
}
authService->SetEvent(&zoomServiceEventHandler);
// Auth using key and secret
ZOOM_SDK_NAMESPACE::AuthParam authParam;
authParam.appKey = appKey.c_str();
authParam.appSecret = appSecret.c_str();
err = authService->SDKAuth(authParam); // AUTHRET_KEYORSECRETWRONG
// Do the auth
if(ZOOM_SDK_NAMESPACE::SDKERR_SUCCESS != err) {
printf("Failed SDKAuth\n");
return -1;
}
// Creating auth thread
if (zoomServiceEventHandler.waitForEvent()) {
printf("Error!!\n");
return -1;
}
// Get meeting service - this is working
printf("Creating Meeting Service\n");
ZOOM_SDK_NAMESPACE::IMeetingService* meetingService;
err = ZOOM_SDK_NAMESPACE::CreateMeetingService(&meetingService);
if(ZOOM_SDK_NAMESPACE::SDKERR_SUCCESS != err) {
printf("failed GetMeetingService\n");
return -1;
}
meetingService->SetEvent(&zoomServiceEventHandler);
// Get setting service - this is working
if (meetingService->GetMeetingConfiguration())
meetingService->GetMeetingConfiguration()->SetSharingToolbarVisibility(false);
ZOOM_SDK_NAMESPACE::ISettingService* _setting_service;
ZOOM_SDK_NAMESPACE::CreateSettingService(&_setting_service);
if (!_setting_service) {
printf("failed CreateSettingService\n");
return -1;
}
printf("Joining the meeting\n");
ZOOM_SDK_NAMESPACE::tagJoinParam joinParam;
joinParam.userType = ZOOM_SDK_NAMESPACE::SDK_UT_WITHOUT_LOGIN;
ZOOM_SDK_NAMESPACE::JoinParam4WithoutLogin& withoutloginParam = joinParam.param.withoutloginuserJoin;
withoutloginParam.meetingNumber = _wtoi64(meetingNumber.c_str());
withoutloginParam.vanityID = NULL;
withoutloginParam.userName = L"My PoC";
withoutloginParam.psw = L"#######";
withoutloginParam.hDirectShareAppWnd = NULL;
withoutloginParam.customer_key = NULL;
withoutloginParam.webinarToken = NULL;
withoutloginParam.isDirectShareDesktop = false;
withoutloginParam.isVideoOff = false;
withoutloginParam.isAudioOff = false;
printf("Joining meeting\n");
err = meetingService->Join(joinParam);
if (err != ZOOM_SDK_NAMESPACE::SDKERR_SUCCESS) {
printf("Error on join meeting %d\n",err);
return -1;
}
if (zoomServiceEventHandler.waitForEvent()) {
printf("Error!!\n");
return -1;
}
printf("Waiting ...\n");
sleep(20);
printf("Finished app\n");
return 0;
}