Manage in-meeting annotation

The code on this page only works with the custom UI.

When users start sharing their screens, others can annotate on top of the shared video feed. Through the Meeting SDK, you can manage many settings related to the appearance and availability of annotation.

Annotation settings

Before starting to annotate, check the meeting settings in the web portal to confirm that it is currently enabled. Check synchronously through the annotation controller, or receive updates asynchronously through the IMeetingAnnotationSupportEvent.

If you are using custom UI, you will also need to conform to the ZoomSDKCustomizedAnnotationDelegate and ZoomSDKCustomizedAnnotationCtrlDelegate to receive callbacks of its annotation events.

class MyCustomizedAnnotationControllerEvent : public ZOOM_SDK_NAMESPACE::ICustomizedAnnotationControllerEvent {
public:
    void onCustomizedAnnotationObjDestroyed(ZOOM_SDK_NAMESPACE::ICustomizedAnnotationObj* obj_) override {
    }
    void onSharingShareAnnotationStatusChanged(
        ZOOM_SDK_NAMESPACE::ICustomizedShareRender* share_render_,
        ZOOM_SDK_NAMESPACE::CustomizedShareAnnotationStatus status_) override {
        if (status_ == ZOOM_SDK_NAMESPACE::CS_ANNO_READY_TO_USE) {
            // Annotation is ready to use
        }
    }
};
class MyCustomizedAnnotationObjEvent : public ZOOM_SDK_NAMESPACE::ICustomizedAnnotationObjEvent {
public:
    void onAnnotationObjToolChange(ZOOM_SDK_NAMESPACE::AnnotationToolType type_) override {
    }
};
void CreateCustomAnnotation(
    ZOOM_SDK_NAMESPACE::IMeetingService* meetingService,
    ZOOM_SDK_NAMESPACE::ICustomizedShareRender* shareRender,
    ZOOM_SDK_NAMESPACE::ICustomizedAnnotationController*& customAnnoController,
    ZOOM_SDK_NAMESPACE::ICustomizedAnnotationObj*& customAnnoObj) {
    ZOOM_SDK_NAMESPACE::IAnnotationController* annotationController =
        meetingService ? meetingService->GetAnnotationController() : nullptr;
    if (!annotationController) {
        return;
    }
    customAnnoController = annotationController->GetCustomizedAnnotationController(shareRender);
    if (!customAnnoController) {
        return;
    }
    static MyCustomizedAnnotationControllerEvent controllerEvent;
    static MyCustomizedAnnotationObjEvent objEvent;
    customAnnoController->SetEvent(&controllerEvent);
    // Local share: pass nullptr.
    // Remote share: pass the existing ICustomizedShareRender*.
    if (customAnnoController->CreateAnnoObj(shareRender, &customAnnoObj) == ZOOM_SDK_NAMESPACE::SDKERR_SUCCESS &&
        customAnnoObj) {
        customAnnoObj->SetEvent(&objEvent);
    }
}
void CheckCustomAnnotation(ZOOM_SDK_NAMESPACE::ICustomizedAnnotationObj* customAnnoObj) {
    bool canDoAnno = false;
    if (customAnnoObj &&
        customAnnoObj->CanDoAnnotation(canDoAnno) == ZOOM_SDK_NAMESPACE::SDKERR_SUCCESS &&
        canDoAnno) {
        // Annotations can be performed
    }
}

If the current user is sharing their screen, they can enable or disable viewers to annotate the shared screen.

if (customizedAnnotation) {
    bool canDisableAnnotation = false;
    if (customizedAnnotation->CanDisableViewerAnnotation(canDisableAnnotation) == ZOOM_SDK_NAMESPACE::SDKERR_SUCCESS &&
        canDisableAnnotation) {
        bool isAnnotationDisabled = customizedAnnotation->IsViewerAnnotationDisabled();
        // Depending on the isAnnotationDisabled value, then disable/enable viewer annotation
        customizedAnnotation->DisableViewerAnnotation(false); // Or true
    }
}

Control annotation properties

In some scenarios, the SDK by default shows an annotation toolbar overlay when it is possible for users to annotate. Replace this with your own UI using the concepts described here. Before doing so, you can optionally hide the default overlay.

In custom UI mode, you need to create your own annotation toolbar that best suits your use case.

To start annotating, call StartAnnotation. When annotation is finished, use StopAnnotation.

if (annotationController &&
    annotationController->StartAnnotation(ZOOM_SDK_NAMESPACE::SDK_FIRST_VIEW) == ZOOM_SDK_NAMESPACE::SDKERR_SUCCESS) {
    // You can begin using the annotation tool
}
if (annotationController) {
    annotationController->StopAnnotation(ZOOM_SDK_NAMESPACE::SDK_FIRST_VIEW);
}

Optionally, after verifying that annotation started based on the return value of StartAnnotation, modify the annotation appearance programmatically.

customizedAnnotation->SetColor(RGB(255, 255, 255)); // color: RGB
customizedAnnotation->SetTool(ZOOM_SDK_NAMESPACE::ANNOTOOL_PEN); // toolType: AnnotationToolType
customizedAnnotation->SetLineWidth(1); // lineWidth: long

Interact with annotations users create by undoing, redoing or clear annotations.

customizedAnnotation->Undo();
customizedAnnotation->Redo();
customizedAnnotation->Clear(ZOOM_SDK_NAMESPACE::ANNOCLEAR_ALL); // AnnotationClearType: all, self, others.

For the custom UI mode, when the meeting no longer needs annotation, remove the listener.

// Only for custom UI mode
if (customizedAnnotationController) {
    customizedAnnotationController->SetEvent(nullptr);
}
if (customizedAnnotation) {
    customizedAnnotation->SetEvent(nullptr);
    customizedAnnotationController->DestroyAnnoObj(customizedAnnotation);
    customizedAnnotation = nullptr;
}