[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-anthropic-video-sdkwindows":3,"mdc-mkrz4t-key":38,"related-org-anthropic-video-sdkwindows":7133,"related-repo-anthropic-video-sdkwindows":7321},{"slug":4,"name":5,"fn":6,"description":7,"org":8,"tags":13,"stars":27,"repoUrl":28,"updatedAt":29,"license":30,"forks":31,"topics":32,"repo":33,"sourceUrl":36,"mdContent":37},"video-sdkwindows","video-sdk\u002Fwindows","build Zoom Video SDK apps for Windows","Zoom Video SDK for Windows - C++ integration for video sessions, raw audio\u002Fvideo capture, screen sharing, recording, and real-time communication",{"slug":9,"name":10,"logoUrl":11,"githubOrg":12},"anthropic","Anthropic","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fanthropic.png","anthropics",[14,18,21,24],{"name":15,"slug":16,"type":17},"Windows","windows","tag",{"name":19,"slug":20,"type":17},"C#","c",{"name":22,"slug":23,"type":17},"SDK","sdk",{"name":25,"slug":26,"type":17},"Zoom","zoom",22885,"https:\u002F\u002Fgithub.com\u002Fanthropics\u002Fknowledge-work-plugins","2026-04-10T04:57:10.831332",null,2736,[],{"repoUrl":28,"stars":27,"forks":31,"topics":34,"description":35},[],"Open source repository of plugins primarily intended for knowledge workers to use in Claude Cowork","https:\u002F\u002Fgithub.com\u002Fanthropics\u002Fknowledge-work-plugins\u002Ftree\u002FHEAD\u002Fpartner-built\u002Fzoom-plugin\u002Fskills\u002Fvideo-sdk\u002Fwindows","---\nname: video-sdk\u002Fwindows\ndescription: \"Zoom Video SDK for Windows - C++ integration for video sessions, raw audio\u002Fvideo capture, screen sharing, recording, and real-time communication\"\nuser-invocable: false\ntriggers:\n  - \"video sdk windows\"\n  - \"windows video sdk\"\n  - \"video sdk raw data windows\"\n  - \"windows custom video\"\n  - \"c++ video sdk\"\n---\n\n# Zoom Video SDK - Windows Development\n\nExpert guidance for developing with the Zoom Video SDK on Windows. This SDK enables custom video applications, raw media capture\u002Finjection, cloud recording, live streaming, and real-time transcription on Windows platforms.\n\n**Official Documentation**: https:\u002F\u002Fdevelopers.zoom.us\u002Fdocs\u002Fvideo-sdk\u002Fwindows\u002F\n**API Reference**: https:\u002F\u002Fmarketplacefront.zoom.us\u002Fsdk\u002Fcustom\u002Fwindows\u002F\n**Sample Repository**: https:\u002F\u002Fgithub.com\u002Fzoom\u002Fvideosdk-windows-rawdata-sample\n\n## Quick Links\n\n**New to Video SDK? Follow this path:**\n\n1. **[SDK Architecture Pattern](concepts\u002Fsdk-architecture-pattern.md)** - Universal 3-step pattern for ANY feature\n2. **[Session Join Pattern](examples\u002Fsession-join-pattern.md)** - Complete working code to join a session\n3. **[Windows Message Loop](troubleshooting\u002Fwindows-message-loop.md)** - **CRITICAL**: Fix callbacks not firing\n4. **[Video Rendering](examples\u002Fvideo-rendering.md)** - Display video with Canvas API\n\n**Reference:**\n- **[Singleton Hierarchy](concepts\u002Fsingleton-hierarchy.md)** - 5-level SDK navigation map\n- **[API Reference](references\u002Fwindows-reference.md)** - Methods, error codes, timing rules\n- **[Delegate Methods](references\u002Fdelegate-methods.md)** - All 80+ callback methods\n- **[Sample Applications](references\u002Fsamples.md)** - Official samples guide\n- **[windows.md](windows.md)** - Secondary overview doc (pointer-style)\n- **[SKILL.md](SKILL.md)** - Complete documentation navigation\n\n**Having issues?**\n- Callbacks not firing → [Windows Message Loop](troubleshooting\u002Fwindows-message-loop.md)\n- Build errors → [Build Errors Guide](troubleshooting\u002Fbuild-errors.md)\n- Video subscribe fails → [Video Rendering](examples\u002Fvideo-rendering.md) (subscribe in `onUserVideoStatusChanged`)\n- Quick diagnostics → [Common Issues](troubleshooting\u002Fcommon-issues.md)\n\n**Building a Custom UI?**\n- [Canvas vs Raw Data](concepts\u002Fcanvas-vs-raw-data.md) - Choose your rendering approach\n- [Raw Video Capture](examples\u002Fraw-video-capture.md) - YUV420 frame processing\n\n## SDK Overview\n\nThe Zoom Video SDK for Windows is a C++ library that provides:\n- **Session Management**: Join\u002Fleave video SDK sessions\n- **Raw Data Access**: Capture raw audio\u002Fvideo frames (YUV420, PCM)\n- **Raw Data Injection**: Send custom audio\u002Fvideo into sessions\n- **Screen Sharing**: Share screens or inject custom share sources\n- **Cloud Recording**: Record sessions to Zoom cloud\n- **Live Streaming**: Stream to RTMP endpoints (YouTube, etc.)\n- **Chat & Commands**: In-session messaging and command channels\n- **Live Transcription**: Real-time speech-to-text\n- **Subsessions**: Breakout room support\n- **Whiteboard**: Collaborative whiteboard features\n- **Annotations**: Screen share annotations\n- **C# Integration**: C++\u002FCLI wrapper for .NET applications\n\n## Prerequisites\n\n### System Requirements\n\n- **OS**: Windows 10 (1903 or later) or Windows 11\n- **Architecture**: x64 (recommended), x86, or ARM64\n- **Visual Studio**: 2019 or 2022 (Community, Professional, or Enterprise)\n- **Windows SDK**: 10.0.19041.0 or later\n- **.NET Framework**: 4.8 or later (for C# applications)\n\n### Visual Studio Workloads\n\nInstall these workloads via Visual Studio Installer:\n\n1. **Desktop development with C++**\n   - MSVC v142 or v143 compiler\n   - Windows 10\u002F11 SDK\n   - C++ CMake tools (optional)\n\n2. **.NET desktop development** (for C# applications)\n   - .NET Framework 4.8 targeting pack\n   - C++\u002FCLI support\n\n## Quick Start\n\n### C++ Application\n\n```cpp\n#include \u003Cwindows.h>\n#include \"zoom_video_sdk_api.h\"\n#include \"zoom_video_sdk_interface.h\"\n#include \"zoom_video_sdk_delegate_interface.h\"\n\nUSING_ZOOM_VIDEO_SDK_NAMESPACE\n\n\u002F\u002F 1. Create SDK object\nIZoomVideoSDK* video_sdk_obj = CreateZoomVideoSDKObj();\n\n\u002F\u002F 2. Initialize\nZoomVideoSDKInitParams init_params;\ninit_params.domain = L\"https:\u002F\u002Fzoom.us\";\ninit_params.enableLog = true;\ninit_params.logFilePrefix = L\"zoom_win_video\";\ninit_params.videoRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap;\ninit_params.shareRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap;\ninit_params.audioRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap;\n\nZoomVideoSDKErrors err = video_sdk_obj->initialize(init_params);\n\n\u002F\u002F 3. Add event listener\nvideo_sdk_obj->addListener(myDelegate);\n\n\u002F\u002F 4. Join session (IMPORTANT: set audioOption.connect = false)\nZoomVideoSDKSessionContext session_context;\nsession_context.sessionName = L\"my-session\";\nsession_context.userName = L\"Windows User\";\nsession_context.token = L\"your-jwt-token\";\nsession_context.videoOption.localVideoOn = false;\nsession_context.audioOption.connect = false;  \u002F\u002F Connect audio after join\nsession_context.audioOption.mute = true;\n\nIZoomVideoSDKSession* session = video_sdk_obj->joinSession(session_context);\n\n\u002F\u002F 5. CRITICAL: Add Windows message pump for callbacks to work\nbool running = true;\nwhile (running) {\n    \u002F\u002F Process Windows messages (required for SDK callbacks)\n    MSG msg;\n    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {\n        TranslateMessage(&msg);\n        DispatchMessage(&msg);\n    }\n    \n    \u002F\u002F Your application logic here\n    Sleep(10);\n}\n```\n\n### C# Application\n\n```csharp\nusing ZoomVideoSDK;\n\nvar sdkManager = new ZoomSDKManager();\nsdkManager.Initialize();\nsdkManager.JoinSession(\"my-session\", \"jwt-token\", \"User Name\", \"\");\n```\n\n## Key Features\n\n| Feature | Description |\n|---------|-------------|\n| **Session Management** | Join, leave, and manage video sessions |\n| **Raw Video (YUV I420)** | Capture and inject raw video frames |\n| **Raw Audio (PCM)** | Capture and inject raw audio data |\n| **Screen Sharing** | Share screens or custom content |\n| **Cloud Recording** | Record sessions to Zoom cloud |\n| **Live Streaming** | Stream to RTMP endpoints |\n| **Chat** | Send\u002Freceive chat messages |\n| **Command Channel** | Custom command messaging |\n| **Live Transcription** | Real-time speech-to-text |\n| **C# Support** | Full .NET Framework integration |\n\n## Sample Applications\n\n**Official Repository**: https:\u002F\u002Fgithub.com\u002Fzoom\u002Fvideosdk-windows-rawdata-sample\n\n| Sample | Description |\n|--------|-------------|\n| VSDK_SkeletonDemo | Minimal session join - **start here** |\n| VSDK_getRawVideo | Capture YUV420 video frames |\n| VSDK_getRawAudio | Capture PCM audio |\n| VSDK_sendRawVideo | Inject custom video (virtual camera) |\n| VSDK_sendRawAudio | Inject custom audio (virtual mic) |\n| VSDK_CloudRecording | Cloud recording control |\n| VSDK_CommandChannel | Custom command messaging |\n| VSDK_TranscriptionAndTranslation | Live captions |\n\n**See complete guide**: [Sample Applications Reference](references\u002Fsamples.md)\n\n## Critical Gotchas and Best Practices\n\n### ⚠️ CRITICAL: Windows Message Pump Required\n\n**The #1 issue that causes session joins to hang with no callbacks:**\n\nAll Windows applications using the Zoom SDK **MUST** process Windows messages. The SDK uses Windows messages to deliver callbacks like `onSessionJoin()`, `onError()`, etc.\n\n**Problem**: Without a message pump, `joinSession()` appears to succeed but callbacks never fire.\n\n**Solution**: Add this to your main loop:\n\n```cpp\nwhile (running) {\n    \u002F\u002F REQUIRED: Process Windows messages\n    MSG msg;\n    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {\n        TranslateMessage(&msg);\n        DispatchMessage(&msg);\n    }\n    \n    \u002F\u002F Your application logic\n    Sleep(10);\n}\n```\n\n**Applies to**:\n- Console applications (no automatic message pump)\n- Custom main loops\n- Applications that don't use standard WinMain\u002FWndProc\n\n**GUI applications** using WinMain with standard message loop already have this.\n\n### Audio Connection Strategy\n\n**Best Practice**: Set `audioOption.connect = false` when joining, then connect audio in the `onSessionJoin()` callback.\n\n```cpp\n\u002F\u002F During join\nsession_context.audioOption.connect = false;  \u002F\u002F Don't connect yet\nsession_context.audioOption.mute = true;\n\n\u002F\u002F In onSessionJoin() callback\nvoid onSessionJoin() override {\n    IZoomVideoSDKAudioHelper* audioHelper = video_sdk_obj->getAudioHelper();\n    if (audioHelper) {\n        audioHelper->startAudio();  \u002F\u002F Connect now\n    }\n}\n```\n\n**Why**: This pattern is used in all official Zoom samples. It separates session join from audio initialization for better reliability and error handling.\n\n### All Delegate Callbacks Must Be Implemented\n\nThe `IZoomVideoSDKDelegate` interface has 70+ pure virtual methods. **ALL must be implemented**, even if empty:\n\n```cpp\n\u002F\u002F Required even if you don't use them\nvoid onProxyDetectComplete() override {}\nvoid onUserWhiteboardShareStatusChanged(IZoomVideoSDKUser*, IZoomVideoSDKWhiteboardHelper*) override {}\n\u002F\u002F ... etc\n```\n\n**Tip**: Check the SDK version's `zoom_video_sdk_delegate_interface.h` for the complete list. The interface changes between SDK versions.\n\n### Memory Mode for Raw Data\n\nAlways use heap mode for raw data memory:\n\n```cpp\ninit_params.videoRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap;\ninit_params.shareRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap;\ninit_params.audioRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap;\n```\n\nStack mode can cause issues with large video frames.\n\n### Thread Safety\n\nSDK callbacks execute on SDK threads, not your main thread:\n- Don't perform heavy operations in callbacks\n- Don't call `cleanup()` from within callbacks\n- Use thread-safe queues for passing data to UI thread\n- Use mutexes when accessing shared state\n\n### Consult Official Samples First\n\nWhen SDK behavior is unexpected, **always check the official samples** before troubleshooting:\n\n**Local samples**:\n- `C:\\tempsdk\\Zoom_VideoSDK_Windows_RawDataDemos\\VSDK_SkeletonDemo\\` (simplest)\n- `C:\\tempsdk\\sdksamples\\zoom-video-sdk-windows-2.4.12\\Sample-Libs\\x64\\demo\\`\n\nOfficial samples show correct patterns for:\n- Message pump implementation ✓\n- Audio connection strategy ✓\n- Error handling ✓\n- Memory management ✓\n\n## Video Rendering - Two Approaches\n\nThe Zoom SDK provides **two different ways** to render video. Choose based on your needs.\n\n### 🎯 Canvas API (Recommended for Most Use Cases)\n\n**Best for**: Standard applications, clean video quality, ease of implementation\n\nThe SDK renders video directly to your HWND. **No YUV conversion needed**.\n\n```cpp\n\u002F\u002F Subscribe to a user's video with Canvas API\nIZoomVideoSDKCanvas* canvas = user->GetVideoCanvas();\nif (canvas) {\n    ZoomVideoSDKErrors ret = canvas->subscribeWithView(\n        hwnd,                                    \u002F\u002F Your window handle\n        ZoomVideoSDKVideoAspect_PanAndScan,     \u002F\u002F Fit to window, may crop\n        ZoomVideoSDKResolution_Auto              \u002F\u002F Let SDK choose best resolution\n    );\n    \n    if (ret == ZoomVideoSDKErrors_Success) {\n        \u002F\u002F SDK is now rendering directly to your window!\n    }\n}\n\n\u002F\u002F Unsubscribe when done\ncanvas->unSubscribeWithView(hwnd);\n```\n\n**Advantages**:\n- ✅ **Best quality** - SDK uses optimized, hardware-accelerated rendering\n- ✅ **No artifacts** - Professional video quality\n- ✅ **Simple code** - 3 lines to subscribe\n- ✅ **Better performance** - No CPU-intensive YUV conversion\n- ✅ **Automatic scaling** - SDK handles window resizing\n- ✅ **Aspect ratio** - Built-in aspect ratio handling\n\n**Example from official .NET sample**:\n```cpp\n\u002F\u002F Self video preview\nIZoomVideoSDKCanvas* canvas = myself->GetVideoCanvas();\ncanvas->subscribeWithView(selfVideoHwnd, aspect, resolution);\n\n\u002F\u002F Remote user video\nIZoomVideoSDKCanvas* remoteCanvas = remoteUser->GetVideoCanvas();\nremoteCanvas->subscribeWithView(remoteVideoHwnd, aspect, resolution);\n```\n\n**Video Aspect Options**:\n- `ZoomVideoSDKVideoAspect_Original` - Letterbox\u002Fpillarbox, no cropping\n- `ZoomVideoSDKVideoAspect_FullFilled` - Fill window, may crop edges\n- `ZoomVideoSDKVideoAspect_PanAndScan` - Smart crop to fill window\n- `ZoomVideoSDKVideoAspect_LetterBox` - Show full video with black bars\n\n**Resolution Options**:\n- `ZoomVideoSDKResolution_90P`\n- `ZoomVideoSDKResolution_180P`\n- `ZoomVideoSDKResolution_360P` - Good balance\n- `ZoomVideoSDKResolution_720P` - HD quality\n- `ZoomVideoSDKResolution_1080P`\n- `ZoomVideoSDKResolution_Auto` - Let SDK decide (recommended)\n\n### 🔧 Raw Data Pipe (Advanced Use Cases)\n\n**Best for**: Custom video processing, effects, recording, computer vision\n\nYou receive raw YUV420 frames and handle rendering yourself.\n\n```cpp\n\u002F\u002F 1. Create a delegate to receive frames\nclass VideoRenderer : public IZoomVideoSDKRawDataPipeDelegate {\npublic:\n    void onRawDataFrameReceived(YUVRawDataI420* data) override {\n        int width = data->GetStreamWidth();\n        int height = data->GetStreamHeight();\n        \n        char* yBuffer = data->GetYBuffer();\n        char* uBuffer = data->GetUBuffer();\n        char* vBuffer = data->GetVBuffer();\n        \n        \u002F\u002F Convert YUV420 to RGB and render\n        ConvertYUVToRGB(yBuffer, uBuffer, vBuffer, width, height);\n        RenderToWindow(rgbBuffer, width, height);\n    }\n    \n    void onRawDataStatusChanged(RawDataStatus status) override {\n        \u002F\u002F Handle video on\u002Foff\n    }\n};\n\n\u002F\u002F 2. Subscribe to raw data\nIZoomVideoSDKRawDataPipe* pipe = user->GetVideoPipe();\nVideoRenderer* renderer = new VideoRenderer();\npipe->subscribe(ZoomVideoSDKResolution_720P, renderer);\n```\n\n**YUV420 to RGB Conversion** (ITU-R BT.601):\n```cpp\nvoid ConvertYUV420ToRGB(char* yBuffer, char* uBuffer, char* vBuffer, \n                        int width, int height) {\n    for (int y = 0; y \u003C height; y++) {\n        for (int x = 0; x \u003C width; x++) {\n            int yIndex = y * width + x;\n            int uvIndex = (y \u002F 2) * (width \u002F 2) + (x \u002F 2);\n            \n            int Y = (unsigned char)yBuffer[yIndex];\n            int U = (unsigned char)uBuffer[uvIndex];\n            int V = (unsigned char)vBuffer[uvIndex];\n            \n            \u002F\u002F YUV to RGB conversion\n            int C = Y - 16;\n            int D = U - 128;\n            int E = V - 128;\n            \n            int R = (298 * C + 409 * E + 128) >> 8;\n            int G = (298 * C - 100 * D - 208 * E + 128) >> 8;\n            int B = (298 * C + 516 * D + 128) >> 8;\n            \n            \u002F\u002F Clamp to [0, 255]\n            R = (R \u003C 0) ? 0 : (R > 255) ? 255 : R;\n            G = (G \u003C 0) ? 0 : (G > 255) ? 255 : G;\n            B = (B \u003C 0) ? 0 : (B > 255) ? 255 : B;\n            \n            \u002F\u002F Store RGB (BGR format for Windows)\n            rgbBuffer[yIndex * 3 + 0] = (unsigned char)B;\n            rgbBuffer[yIndex * 3 + 1] = (unsigned char)G;\n            rgbBuffer[yIndex * 3 + 2] = (unsigned char)R;\n        }\n    }\n}\n```\n\n**Render with GDI**:\n```cpp\nvoid RenderToWindow(unsigned char* rgbBuffer, int width, int height) {\n    HDC hdc = GetDC(hwnd);\n    \n    BITMAPINFO bmi = {};\n    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);\n    bmi.bmiHeader.biWidth = width;\n    bmi.bmiHeader.biHeight = -height;  \u002F\u002F Negative for top-down\n    bmi.bmiHeader.biPlanes = 1;\n    bmi.bmiHeader.biBitCount = 24;     \u002F\u002F 24-bit RGB\n    bmi.bmiHeader.biCompression = BI_RGB;\n    \n    RECT rect;\n    GetClientRect(hwnd, &rect);\n    \n    StretchDIBits(hdc,\n        0, 0, rect.right, rect.bottom,  \u002F\u002F Destination\n        0, 0, width, height,              \u002F\u002F Source\n        rgbBuffer, &bmi,\n        DIB_RGB_COLORS, SRCCOPY);\n    \n    ReleaseDC(hwnd, hdc);\n}\n```\n\n**Disadvantages**:\n- ⚠️ **CPU intensive** - YUV conversion can cause frame drops\n- ⚠️ **Artifacts** - Manual rendering may show tearing\u002Fartifacts\n- ⚠️ **Complex** - More code to maintain\n- ⚠️ **Performance** - Slower than Canvas API\n\n**Use Raw Data When**:\n- Adding video filters\u002Feffects\n- Recording to custom formats\n- Computer vision processing\n- Custom compositing\n- Streaming to non-standard outputs\n\n### Self Video vs Remote Users\n\n**Self Video** (your own camera):\n\n**Option A: Canvas API**\n```cpp\nIZoomVideoSDKSession* session = sdk->getSessionInfo();\nIZoomVideoSDKUser* myself = session->getMyself();\nIZoomVideoSDKCanvas* canvas = myself->GetVideoCanvas();\ncanvas->subscribeWithView(selfVideoHwnd, aspect, resolution);\n```\n\n**Option B: Video Preview** (for self only)\n```cpp\nIZoomVideoSDKVideoHelper* videoHelper = sdk->getVideoHelper();\nvideoHelper->startVideo();  \u002F\u002F Start transmission\n\n\u002F\u002F For preview rendering\nvideoHelper->startVideoCanvasPreview(selfVideoHwnd, aspect, resolution);\n```\n\n**Remote Users** (other participants):\n\n**Canvas API** (recommended):\n```cpp\n\u002F\u002F In onUserJoin callback\nvoid onUserJoin(IZoomVideoSDKUserHelper*, IVideoSDKVector\u003CIZoomVideoSDKUser*>* userList) {\n    for (int i = 0; i \u003C userList->GetCount(); i++) {\n        IZoomVideoSDKUser* user = userList->GetItem(i);\n        IZoomVideoSDKCanvas* canvas = user->GetVideoCanvas();\n        canvas->subscribeWithView(userVideoHwnd, aspect, resolution);\n    }\n}\n```\n\n### Event-Driven Subscription Pattern\n\n⚠️ **CRITICAL**: Video subscription must be **event-driven** and **manual**.\n\n**Key Events**:\n\n1. **`onSessionJoin`** - Subscribe to self video\n2. **`onUserJoin`** - Subscribe to new remote users\n3. **`onUserVideoStatusChanged`** - Re-subscribe when video turns on\u002Foff\n4. **`onUserLeave`** - Unsubscribe and cleanup\n\n**Complete Pattern**:\n\n```cpp\nclass MainFrame : public IZoomVideoSDKDelegate {\nprivate:\n    std::map\u003CIZoomVideoSDKUser*, IZoomVideoSDKCanvas*> subscribedUsers_;\n    HWND videoWindow_;\n    \npublic:\n    void onSessionJoin() override {\n        \u002F\u002F Start your own video\n        IZoomVideoSDKVideoHelper* videoHelper = sdk->getVideoHelper();\n        videoHelper->startVideo();\n        \n        \u002F\u002F Subscribe to self video\n        IZoomVideoSDKUser* myself = sdk->getSessionInfo()->getMyself();\n        SubscribeToUser(myself);\n    }\n    \n    void onUserJoin(IZoomVideoSDKUserHelper*, \n                    IVideoSDKVector\u003CIZoomVideoSDKUser*>* userList) override {\n        \u002F\u002F Get current user to exclude self\n        IZoomVideoSDKUser* myself = sdk->getSessionInfo()->getMyself();\n        \n        for (int i = 0; i \u003C userList->GetCount(); i++) {\n            IZoomVideoSDKUser* user = userList->GetItem(i);\n            \n            \u002F\u002F IMPORTANT: Only subscribe to REMOTE users!\n            if (user != myself) {\n                SubscribeToUser(user);\n            }\n        }\n    }\n    \n    void onUserVideoStatusChanged(IZoomVideoSDKVideoHelper*, \n                                  IVideoSDKVector\u003CIZoomVideoSDKUser*>* userList) override {\n        IZoomVideoSDKUser* myself = sdk->getSessionInfo()->getMyself();\n        \n        for (int i = 0; i \u003C userList->GetCount(); i++) {\n            IZoomVideoSDKUser* user = userList->GetItem(i);\n            if (user != myself) {\n                \u002F\u002F Re-subscribe when video status changes\n                SubscribeToUser(user);\n            }\n        }\n    }\n    \n    void onUserLeave(IZoomVideoSDKUserHelper*, \n                    IVideoSDKVector\u003CIZoomVideoSDKUser*>* userList) override {\n        for (int i = 0; i \u003C userList->GetCount(); i++) {\n            IZoomVideoSDKUser* user = userList->GetItem(i);\n            UnsubscribeFromUser(user);\n        }\n    }\n    \n    void onSessionLeave() override {\n        \u002F\u002F Cleanup all subscriptions\n        for (auto& pair : subscribedUsers_) {\n            IZoomVideoSDKCanvas* canvas = pair.second;\n            if (canvas) {\n                canvas->unSubscribeWithView(videoWindow_);\n            }\n        }\n        subscribedUsers_.clear();\n    }\n    \nprivate:\n    void SubscribeToUser(IZoomVideoSDKUser* user) {\n        if (!user || subscribedUsers_.find(user) != subscribedUsers_.end())\n            return;\n            \n        IZoomVideoSDKCanvas* canvas = user->GetVideoCanvas();\n        if (canvas) {\n            ZoomVideoSDKErrors ret = canvas->subscribeWithView(\n                videoWindow_,\n                ZoomVideoSDKVideoAspect_PanAndScan,\n                ZoomVideoSDKResolution_Auto\n            );\n            \n            if (ret == ZoomVideoSDKErrors_Success) {\n                subscribedUsers_[user] = canvas;\n            }\n        }\n    }\n    \n    void UnsubscribeFromUser(IZoomVideoSDKUser* user) {\n        auto it = subscribedUsers_.find(user);\n        if (it != subscribedUsers_.end()) {\n            IZoomVideoSDKCanvas* canvas = it->second;\n            if (canvas) {\n                canvas->unSubscribeWithView(videoWindow_);\n            }\n            subscribedUsers_.erase(it);\n        }\n    }\n};\n```\n\n**Key Points**:\n- ✅ Subscribe in response to events (onUserJoin, onUserVideoStatusChanged)\n- ✅ Always exclude current user from remote subscriptions\n- ✅ Unsubscribe on onUserLeave\n- ✅ Clean up all subscriptions on onSessionLeave\n- ✅ Track subscriptions in a map for lifecycle management\n\n### ⚠️ Screen Share Subscription (DIFFERENT from Video!)\n\n**CRITICAL**: Screen share subscription uses `IZoomVideoSDKShareAction` from the callback, NOT `user->GetShareCanvas()`!\n\n```cpp\n\u002F\u002F WRONG - This won't work for remote screen shares!\nuser->GetShareCanvas()->subscribeWithView(hwnd, ...);\n\n\u002F\u002F CORRECT - Use IZoomVideoSDKShareAction from onUserShareStatusChanged callback\nvoid onUserShareStatusChanged(IZoomVideoSDKShareHelper* pShareHelper,\n                               IZoomVideoSDKUser* pUser,\n                               IZoomVideoSDKShareAction* pShareAction) {\n    if (!pShareAction) return;\n    \n    ZoomVideoSDKShareStatus status = pShareAction->getShareStatus();\n    \n    if (status == ZoomVideoSDKShareStatus_Start || \n        status == ZoomVideoSDKShareStatus_Resume) {\n        \u002F\u002F Subscribe to the share using Canvas API\n        IZoomVideoSDKCanvas* shareCanvas = pShareAction->getShareCanvas();\n        if (shareCanvas) {\n            shareCanvas->subscribeWithView(shareWindow_, \n                ZoomVideoSDKVideoAspect_Original);\n        }\n    }\n    else if (status == ZoomVideoSDKShareStatus_Stop) {\n        \u002F\u002F Unsubscribe when share stops\n        IZoomVideoSDKCanvas* shareCanvas = pShareAction->getShareCanvas();\n        if (shareCanvas) {\n            shareCanvas->unSubscribeWithView(shareWindow_);\n        }\n    }\n}\n```\n\n**Why is share different from video?**\n- **Video**: Each user has one video stream → use `user->GetVideoCanvas()`\n- **Share**: A user can have multiple share actions (multi-share) → use `IZoomVideoSDKShareAction*` from callback\n- The `IZoomVideoSDKShareAction` object represents a specific share stream and contains the share status, type, and rendering interfaces\n\n**See also**: [Screen Share Subscription Example](examples\u002Fscreen-share-subscription.md)\n\n### Multi-User Video Layout\n\nFor multiple participants, you need **one HWND per user**:\n\n```cpp\n\u002F\u002F Create separate windows\u002Fpanels for each user\nHWND selfVideoWindow = CreateWindow(...);   \u002F\u002F Your video\nHWND user1Window = CreateWindow(...);       \u002F\u002F User 1's video\nHWND user2Window = CreateWindow(...);       \u002F\u002F User 2's video\n\n\u002F\u002F Subscribe each user to their own window\nmyself->GetVideoCanvas()->subscribeWithView(selfVideoWindow, ...);\nuser1->GetVideoCanvas()->subscribeWithView(user1Window, ...);\nuser2->GetVideoCanvas()->subscribeWithView(user2Window, ...);\n```\n\n**Layout Strategies**:\n- Grid layout (2x2, 3x3)\n- Gallery view (scrollable)\n- Active speaker (large) + thumbnails\n- Picture-in-picture\n\n### Common Video Issues\n\n| Issue | Cause | Solution |\n|-------|-------|----------|\n| Video not showing | Not calling `startVideo()` | Call `videoHelper->startVideo()` in `onSessionJoin` |\n| Artifacts\u002Ftearing | Using Raw Data Pipe | Switch to Canvas API |\n| Poor performance | YUV conversion on UI thread | Use Canvas API or move conversion to worker thread |\n| Video freezes | Not processing Windows messages | Add message pump to main loop |\n| Can't see self | Subscribing to wrong user | Use `session->getMyself()` for self video |\n| Seeing self in remote list | Not excluding self | Check `if (user != myself)` before subscribing |\n\n## Complete Documentation Library\n\nThis skill includes comprehensive guides organized by category:\n\n### Core Concepts (Start Here!)\n- **[SDK Architecture Pattern](concepts\u002Fsdk-architecture-pattern.md)** - Universal 3-step pattern for ANY feature\n- **[Singleton Hierarchy](concepts\u002Fsingleton-hierarchy.md)** - 5-level navigation guide\n- **[Canvas vs Raw Data](concepts\u002Fcanvas-vs-raw-data.md)** - Choose your rendering approach\n\n### Complete Examples\n- **[Session Join Pattern](examples\u002Fsession-join-pattern.md)** - JWT auth + session join with full code\n- **[Video Rendering](examples\u002Fvideo-rendering.md)** - Canvas API video display\n- **[Screen Share Subscription](examples\u002Fscreen-share-subscription.md)** - View remote screen shares (DIFFERENT from video!)\n- **[Raw Video Capture](examples\u002Fraw-video-capture.md)** - YUV420 frame capture\n- **[Raw Audio Capture](examples\u002Fraw-audio-capture.md)** - PCM audio capture\n- **[Send Raw Video](examples\u002Fsend-raw-video.md)** - Virtual camera (inject custom video)\n- **[Send Raw Audio](examples\u002Fsend-raw-audio.md)** - Virtual mic (inject custom audio)\n- **[Cloud Recording](examples\u002Fcloud-recording.md)** - Cloud recording control\n- **[Command Channel](examples\u002Fcommand-channel.md)** - Custom command messaging\n- **[Transcription](examples\u002Ftranscription.md)** - Live transcription\u002Fcaptions\n\n### UI Framework Integration\n- **[Win32 Native](examples\u002Fdotnet-winforms\u002FREADME.md#option-1-win32-native-c---direct-sdk)** - Direct SDK usage with Canvas API (best performance)\n- **[WinForms (.NET)](examples\u002Fdotnet-winforms\u002FREADME.md#option-2-winforms-c--ccli-wrapper)** - C++\u002FCLI wrapper + Raw Data Pipe\n- **[WPF (.NET)](examples\u002Fdotnet-winforms\u002FREADME.md#option-3-wpf-c--ccli-wrapper)** - C++\u002FCLI wrapper + BitmapSource conversion\n- **[Production Quality Guidelines](examples\u002Fdotnet-winforms\u002FREADME.md#production-quality-review)** - Checklist and common issues\n\n### C++\u002FCLI Wrapper Patterns (Wrapping ANY Native Library)\n- **[Complete Guide](examples\u002Fdotnet-winforms\u002FREADME.md#ccli-wrapper-patterns-for-net-integration)** - 8 patterns for native→.NET interop\n- **[Pattern 1: Basic Structure](examples\u002Fdotnet-winforms\u002FREADME.md#pattern-1-basic-wrapper-structure)** - Project setup, class layout\n- **[Pattern 2: void* Pointers](examples\u002Fdotnet-winforms\u002FREADME.md#pattern-2-opaque-void-pointers)** - Hide native types\n- **[Pattern 3: gcroot Callbacks](examples\u002Fdotnet-winforms\u002FREADME.md#pattern-3-gcrootT-for-nativemanaged-callbacks)** - Native→Managed events\n- **[Pattern 4: IDisposable](examples\u002Fdotnet-winforms\u002FREADME.md#pattern-4-destructor--finalizer-idisposable)** - Cleanup pattern\n- **[Pattern 5: Strings](examples\u002Fdotnet-winforms\u002FREADME.md#pattern-5-string-conversion)** - String^ ↔ wstring\u002Fstring\n- **[Pattern 6: Arrays](examples\u002Fdotnet-winforms\u002FREADME.md#pattern-6-arraybuffer-conversion)** - pin_ptr, Marshal::Copy\n- **[Pattern 7: Threading](examples\u002Fdotnet-winforms\u002FREADME.md#pattern-7-thread-marshaling-native-thread--ui-thread)** - UI thread dispatch\n- **[Pattern 8: LockBits](examples\u002Fdotnet-winforms\u002FREADME.md#pattern-8-lockbits-for-fast-image-manipulation)** - Fast image conversion\n- **[Common Errors](examples\u002Fdotnet-winforms\u002FREADME.md#common-wrapper-errors)** - Troubleshooting\n\n### Troubleshooting\n- **[Windows Message Loop](troubleshooting\u002Fwindows-message-loop.md)** - **CRITICAL**: Why callbacks don't fire\n- **[Build Errors](troubleshooting\u002Fbuild-errors.md)** - SDK header dependency fixes\n- **[Common Issues](troubleshooting\u002Fcommon-issues.md)** - Quick diagnostics & error codes\n\n### References\n- **[API Reference](references\u002Fwindows-reference.md)** - 5-level API hierarchy, methods, error codes\n- **[Delegate Methods](references\u002Fdelegate-methods.md)** - All 80+ callback methods\n- **[SKILL.md](SKILL.md)** - Complete navigation guide\n\n### Most Critical Issues (From Real Debugging)\n\n1. **Callbacks not firing** → Missing Windows message loop (99% of issues)\n   - See: [Windows Message Loop Guide](troubleshooting\u002Fwindows-message-loop.md)\n\n2. **Video subscribe returns error 2** → Subscribing too early\n   - See: [Video Rendering](examples\u002Fvideo-rendering.md) - Subscribe in `onUserVideoStatusChanged`\n\n3. **Abstract class errors** → Missing virtual method implementations\n   - See: [Delegate Methods](references\u002Fdelegate-methods.md)\n\n### Key Insight\n\n**Once you learn the 3-step pattern, you can implement ANY feature:**\n1. Get singleton → 2. Implement delegate → 3. Subscribe & use\n\nSee: [SDK Architecture Pattern](concepts\u002Fsdk-architecture-pattern.md)\n\n## Resources\n\n- **Official Docs**: https:\u002F\u002Fdevelopers.zoom.us\u002Fdocs\u002Fvideo-sdk\u002Fwindows\u002F\n- **API Reference**: https:\u002F\u002Fmarketplacefront.zoom.us\u002Fsdk\u002Fcustom\u002Fwindows\u002F\n- **Dev Forum**: https:\u002F\u002Fdevforum.zoom.us\u002F\n- **GitHub Samples**: https:\u002F\u002Fgithub.com\u002Fzoom\u002Fvideosdk-windows-rawdata-sample\n- **Working Sample**: `C:\\tempsdk\\zoom-video-sdk-windows-sample\\` (complete implementation)\n\n---\n\n**Need help?** Start with [SKILL.md](SKILL.md) for complete navigation.\n\n\n## Merged from video-sdk\u002Fwindows\u002FSKILL.md\n\n# Zoom Video SDK Windows - Complete Documentation Index\n\n## Quick Start Path\n\n**If you're new to the SDK, follow this order:**\n\n0. **Overview** → [windows.md](windows.md)\n1. **Read the architecture pattern** → [concepts\u002Fsdk-architecture-pattern.md](concepts\u002Fsdk-architecture-pattern.md)\n   - Universal formula: Singleton → Delegate → Subscribe\n   - Once you understand this, you can implement any feature\n\n2. **Fix build errors** → [troubleshooting\u002Fbuild-errors.md](troubleshooting\u002Fbuild-errors.md)\n   - SDK header dependencies\n   - Required include order\n\n3. **Implement session join** → [examples\u002Fsession-join-pattern.md](examples\u002Fsession-join-pattern.md)\n   - Complete working JWT + session join code\n\n4. **Fix callback issues** → [troubleshooting\u002Fwindows-message-loop.md](troubleshooting\u002Fwindows-message-loop.md)\n   - **CRITICAL**: Why callbacks don't fire without Windows message loop\n\n5. **Implement video** → [examples\u002Fvideo-rendering.md](examples\u002Fvideo-rendering.md)\n   - Canvas API (SDK-rendered) vs Raw Data Pipe\n\n6. **Troubleshoot any issues** → [troubleshooting\u002Fcommon-issues.md](troubleshooting\u002Fcommon-issues.md)\n   - Quick diagnostic checklist\n   - Error code tables\n\n---\n\n## Documentation Structure\n\n```\nvideo-sdk\u002Fwindows\u002F\n├── SKILL.md                           # Main skill overview\n├── SKILL.md                           # This file - navigation guide\n├── windows.md                          # Secondary overview doc (pointer-style)\n│\n├── concepts\u002F                          # Core architectural patterns\n│   ├── sdk-architecture-pattern.md   # Universal formula for ANY feature\n│   ├── singleton-hierarchy.md        # 5-level navigation guide\n│   └── canvas-vs-raw-data.md         # SDK-rendered vs self-rendered choice\n│\n├── examples\u002F                          # Complete working code\n│   ├── session-join-pattern.md       # JWT auth + session join\n│   ├── video-rendering.md            # Canvas API video display\n│   ├── screen-share-subscription.md  # View remote screen shares\n│   ├── raw-video-capture.md          # YUV420 raw frame capture\n│   ├── raw-audio-capture.md          # PCM audio capture\n│   ├── send-raw-video.md             # Virtual camera (inject video)\n│   ├── send-raw-audio.md             # Virtual mic (inject audio)\n│   ├── cloud-recording.md            # Cloud recording control\n│   ├── command-channel.md            # Custom command messaging\n│   ├── transcription.md              # Live transcription\u002Fcaptions\n│   └── dotnet-winforms\u002F              # UI Framework integration\n│       └── README.md                 # Win32, WinForms, WPF patterns\n│                                     # C++\u002FCLI wrapper patterns\n│                                     # Production quality guidelines\n│\n├── troubleshooting\u002F                   # Problem solving guides\n│   ├── windows-message-loop.md       # CRITICAL - Why callbacks fail\n│   ├── build-errors.md               # Header dependency fixes\n│   └── common-issues.md              # Quick diagnostic workflow\n│\n└── references\u002F                        # Reference documentation\n    ├── windows-reference.md           # API hierarchy, methods, error codes\n    ├── delegate-methods.md            # All 80+ callback methods\n    └── samples.md                     # Official samples guide\n```\n\n---\n\n## By Use Case\n\n### I want to build a video app\n1. [SDK Architecture Pattern](concepts\u002Fsdk-architecture-pattern.md) - Understand the pattern\n2. [Session Join Pattern](examples\u002Fsession-join-pattern.md) - Join sessions\n3. [Video Rendering](examples\u002Fvideo-rendering.md) - Display video\n4. [Windows Message Loop](troubleshooting\u002Fwindows-message-loop.md) - Fix callback issues\n\n### I'm getting build errors\n1. [Build Errors Guide](troubleshooting\u002Fbuild-errors.md) - SDK header dependencies\n2. [Delegate Methods](references\u002Fdelegate-methods.md) - Abstract class errors\n3. [Common Issues](troubleshooting\u002Fcommon-issues.md) - Linker errors\n\n### I'm getting runtime errors\n1. [Windows Message Loop](troubleshooting\u002Fwindows-message-loop.md) - Callbacks not firing\n2. [Common Issues](troubleshooting\u002Fcommon-issues.md) - Error code tables\n\n### I want to view screen shares\n1. [Screen Share Subscription](examples\u002Fscreen-share-subscription.md) - **DIFFERENT from video!**\n2. [SDK Architecture Pattern](concepts\u002Fsdk-architecture-pattern.md) - Event-driven pattern\n3. [Video Rendering](examples\u002Fvideo-rendering.md) - Compare with video subscription\n\n### I want to capture raw video\u002Faudio\n1. [Canvas vs Raw Data](concepts\u002Fcanvas-vs-raw-data.md) - Choose your approach\n2. [Raw Video Capture](examples\u002Fraw-video-capture.md) - YUV420 frame capture\n3. [Raw Audio Capture](examples\u002Fraw-audio-capture.md) - PCM audio capture\n4. [SDK Architecture Pattern](concepts\u002Fsdk-architecture-pattern.md) - Subscription pattern\n\n### I want to send custom video\u002Faudio (virtual camera\u002Fmic)\n1. [Send Raw Video](examples\u002Fsend-raw-video.md) - Inject custom video frames\n2. [Send Raw Audio](examples\u002Fsend-raw-audio.md) - Inject custom audio\n3. [SDK Architecture Pattern](concepts\u002Fsdk-architecture-pattern.md) - External source pattern\n\n### I want to record sessions\n1. [Cloud Recording](examples\u002Fcloud-recording.md) - Start\u002Fstop cloud recording\n2. [API Reference](references\u002Fwindows-reference.md) - Recording helper methods\n\n### I want to use live transcription\n1. [Transcription](examples\u002Ftranscription.md) - Enable live captions\n2. [Delegate Methods](references\u002Fdelegate-methods.md) - Transcription callbacks\n\n### I want custom messaging between participants\n1. [Command Channel](examples\u002Fcommand-channel.md) - Send custom commands\n2. [API Reference](references\u002Fwindows-reference.md) - Command channel methods\n\n### I want to build a Win32 native app\n1. [Win32 Integration](examples\u002Fdotnet-winforms\u002FREADME.md#option-1-win32-native-c---direct-sdk) - Direct SDK + Canvas API\n2. [Video Rendering](examples\u002Fvideo-rendering.md) - Canvas API patterns\n3. [Production Guidelines](examples\u002Fdotnet-winforms\u002FREADME.md#production-quality-review) - Best practices\n\n### I want to build a WinForms (.NET) app\n1. [WinForms Integration](examples\u002Fdotnet-winforms\u002FREADME.md#option-2-winforms-c--ccli-wrapper) - C++\u002FCLI wrapper + Raw Data\n2. [C++\u002FCLI Patterns](examples\u002Fdotnet-winforms\u002FREADME.md#ccli-wrapper-patterns-for-net-integration) - gcroot, Finalizer, LockBits\n3. [Production Guidelines](examples\u002Fdotnet-winforms\u002FREADME.md#production-quality-review) - IDisposable, thread safety\n\n### I want to build a WPF (.NET) app\n1. [WPF Integration](examples\u002Fdotnet-winforms\u002FREADME.md#option-3-wpf-c--ccli-wrapper) - C++\u002FCLI + BitmapSource\n2. [Bitmap Conversion](examples\u002Fdotnet-winforms\u002FREADME.md#2-bitmap--bitmapsource-conversion) - Freeze(), Dispatcher\n3. [Production Guidelines](examples\u002Fdotnet-winforms\u002FREADME.md#production-quality-review) - Performance optimization\n\n### I want to use C# \u002F .NET Framework (general)\n1. [.NET Integration Overview](examples\u002Fdotnet-winforms\u002FREADME.md) - **Complete C++\u002FCLI wrapper guide**\n2. [Raw Video Capture](examples\u002Fraw-video-capture.md) - YUV→RGB conversion patterns\n3. [Session Join Pattern](examples\u002Fsession-join-pattern.md) - SDK initialization flow\n\n### I want to wrap ANY native C++ library for .NET\n1. [C++\u002FCLI Wrapper Patterns](examples\u002Fdotnet-winforms\u002FREADME.md#ccli-wrapper-patterns-for-net-integration) - **Complete 8-pattern guide**\n2. [Pattern 1: Basic Structure](examples\u002Fdotnet-winforms\u002FREADME.md#pattern-1-basic-wrapper-structure) - Project setup + class layout\n3. [Pattern 3: gcroot Callbacks](examples\u002Fdotnet-winforms\u002FREADME.md#pattern-3-gcrootT-for-nativemanaged-callbacks) - Native→Managed events\n4. [Pattern 4: IDisposable](examples\u002Fdotnet-winforms\u002FREADME.md#pattern-4-destructor--finalizer-idisposable) - Cleanup pattern\n5. [Common Errors](examples\u002Fdotnet-winforms\u002FREADME.md#common-wrapper-errors) - Troubleshooting\n\n### I want to implement a specific feature\n1. [SDK Architecture Pattern](concepts\u002Fsdk-architecture-pattern.md) - **START HERE!**\n2. [Singleton Hierarchy](concepts\u002Fsingleton-hierarchy.md) - Navigate to the feature\n3. [API Reference](references\u002Fwindows-reference.md) - Method signatures\n\n---\n\n## Most Critical Documents\n\n### 1. SDK Architecture Pattern (MASTER DOCUMENT)\n**[concepts\u002Fsdk-architecture-pattern.md](concepts\u002Fsdk-architecture-pattern.md)**\n\nThe universal 3-step pattern:\n1. Get singleton (SDK, helpers, session, users)\n2. Implement delegate (event callbacks)\n3. Subscribe and use\n\n### 2. Windows Message Loop (MOST COMMON ISSUE)\n**[troubleshooting\u002Fwindows-message-loop.md](troubleshooting\u002Fwindows-message-loop.md)**\n\n99% of \"callbacks not firing\" issues are caused by missing Windows message loop.\n\n### 3. Singleton Hierarchy (NAVIGATION MAP)\n**[concepts\u002Fsingleton-hierarchy.md](concepts\u002Fsingleton-hierarchy.md)**\n\n5-level deep navigation showing how to reach every feature.\n\n---\n\n## Key Learnings\n\n### Critical Discoveries:\n\n1. **Windows Message Loop is MANDATORY**\n   - SDK uses Windows message pump for callbacks\n   - Without it, callbacks are queued but never fire\n   - See: [Windows Message Loop Guide](troubleshooting\u002Fwindows-message-loop.md)\n\n2. **Subscribe in onUserVideoStatusChanged, NOT onUserJoin**\n   - Video may not be ready when user joins\n   - Wait for video status change callback\n   - See: [Video Rendering](examples\u002Fvideo-rendering.md)\n\n3. **Two Rendering Paths**\n   - Canvas API: SDK renders to your HWND (recommended)\n   - Raw Data Pipe: You receive YUV frames (advanced)\n   - See: [Canvas vs Raw Data](concepts\u002Fcanvas-vs-raw-data.md)\n\n4. **Helpers Control YOUR Streams Only**\n   - `videoHelper->startVideo()` starts YOUR camera\n   - To see others, subscribe to their Canvas\u002FPipe\n   - See: [Singleton Hierarchy](concepts\u002Fsingleton-hierarchy.md)\n\n5. **UI Framework Integration Differs by Platform**\n   - **Win32**: Direct SDK, Canvas API (SDK renders to HWND) - best performance\n   - **WinForms**: C++\u002FCLI wrapper, Raw Data Pipe, YUV→Bitmap, InvokeRequired\n   - **WPF**: Same wrapper + Bitmap→BitmapSource, Dispatcher, Freeze()\n   - See: [UI Framework Integration](examples\u002Fdotnet-winforms\u002FREADME.md)\n\n6. **C++\u002FCLI Wrapper Patterns (for ANY native library → .NET)**\n   - `void*` pointers - hide native types from managed headers\n   - `gcroot\u003CT^>` - prevent GC from collecting managed references in native code\n   - Finalizer + Destructor - `~Class()` and `!Class()` for IDisposable cleanup\n   - `pin_ptr` + `Marshal::Copy` - array\u002Fbuffer conversion\n   - `LockBits` - 100x faster than SetPixel for image manipulation\n   - Thread marshaling - InvokeRequired (WinForms) \u002F Dispatcher (WPF)\n   - See: [C++\u002FCLI Wrapper Guide](examples\u002Fdotnet-winforms\u002FREADME.md#ccli-wrapper-patterns-for-net-integration)\n\n7. **Audio Connection Timing**\n   - Set `audioOption.connect = false` during join\n   - Call `startAudio()` in `onSessionJoin` callback\n   - See: [Production Guidelines](examples\u002Fdotnet-winforms\u002FREADME.md#production-quality-review)\n\n---\n\n## Quick Reference\n\n### \"My code won't compile\"\n→ [Build Errors Guide](troubleshooting\u002Fbuild-errors.md)\n\n### \"Callbacks never fire\"\n→ [Windows Message Loop](troubleshooting\u002Fwindows-message-loop.md)\n\n### \"Video subscription returns error 2\"\n→ [Video Rendering](examples\u002Fvideo-rendering.md) - Subscribe in onUserVideoStatusChanged\n\n### \"Abstract class error\"\n→ [Delegate Methods](references\u002Fdelegate-methods.md)\n\n### \"How do I implement [feature]?\"\n→ [SDK Architecture Pattern](concepts\u002Fsdk-architecture-pattern.md)\n\n### \"How do I navigate to [controller]?\"\n→ [Singleton Hierarchy](concepts\u002Fsingleton-hierarchy.md)\n\n### \"What error code means what?\"\n→ [Common Issues](troubleshooting\u002Fcommon-issues.md)\n\n---\n\n## Document Version\n\nBased on **Zoom Video SDK for Windows v2.x**\n\n---\n\n**Happy coding!**\n\nRemember: The [SDK Architecture Pattern](concepts\u002Fsdk-architecture-pattern.md) is your key to unlocking the entire SDK. Read it first!\n\n## Operations\n\n- [RUNBOOK.md](RUNBOOK.md) - 5-minute preflight and debugging checklist.\n",{"data":39,"body":47},{"name":5,"description":7,"user-invocable":40,"triggers":41},false,[42,43,44,45,46],"video sdk windows","windows video sdk","video sdk raw data windows","windows custom video","c++ video sdk",{"type":48,"children":49},"root",[50,59,65,108,115,123,191,199,284,292,346,354,379,385,390,513,519,526,579,585,590,642,648,654,1093,1099,1147,1153,1336,1341,1355,1484,1498,1504,1510,1518,1546,1564,1574,1660,1670,1688,1698,1704,1729,1820,1830,1836,1856,1895,1913,1919,1924,1952,1957,1963,1968,1999,2005,2017,2026,2049,2054,2077,2083,2095,2101,2111,2123,2254,2263,2333,2342,2404,2413,2460,2469,2532,2538,2547,2552,2754,2764,3021,3030,3208,3217,3265,3274,3302,3308,3318,3326,3363,3373,3419,3429,3439,3508,3514,3537,3546,3604,3613,4364,4373,4401,4407,4432,4653,4661,4709,4724,4730,4741,4819,4828,4851,4857,5026,5032,5037,5043,5080,5086,5220,5226,5285,5291,5434,5440,5485,5491,5529,5535,5610,5616,5624,5632,5640,5646,5722,5726,5742,5748,5754,5760,5768,5931,5934,5940,5950,5953,5959,5965,6004,6010,6040,6046,6067,6073,6107,6113,6150,6156,6186,6192,6213,6219,6240,6246,6267,6273,6305,6311,6343,6349,6382,6388,6424,6430,6480,6486,6520,6523,6529,6535,6545,6550,6568,6574,6584,6589,6595,6605,6610,6613,6619,6625,6944,6947,6953,6959,6968,6974,6982,6988,6998,7004,7012,7025,7033,7045,7053,7059,7067,7070,7076,7086,7089,7097,7108,7114,7127],{"type":51,"tag":52,"props":53,"children":55},"element","h1",{"id":54},"zoom-video-sdk-windows-development",[56],{"type":57,"value":58},"text","Zoom Video SDK - Windows Development",{"type":51,"tag":60,"props":61,"children":62},"p",{},[63],{"type":57,"value":64},"Expert guidance for developing with the Zoom Video SDK on Windows. This SDK enables custom video applications, raw media capture\u002Finjection, cloud recording, live streaming, and real-time transcription on Windows platforms.",{"type":51,"tag":60,"props":66,"children":67},{},[68,74,76,84,89,90,96,101,102],{"type":51,"tag":69,"props":70,"children":71},"strong",{},[72],{"type":57,"value":73},"Official Documentation",{"type":57,"value":75},": ",{"type":51,"tag":77,"props":78,"children":82},"a",{"href":79,"rel":80},"https:\u002F\u002Fdevelopers.zoom.us\u002Fdocs\u002Fvideo-sdk\u002Fwindows\u002F",[81],"nofollow",[83],{"type":57,"value":79},{"type":51,"tag":69,"props":85,"children":86},{},[87],{"type":57,"value":88},"API Reference",{"type":57,"value":75},{"type":51,"tag":77,"props":91,"children":94},{"href":92,"rel":93},"https:\u002F\u002Fmarketplacefront.zoom.us\u002Fsdk\u002Fcustom\u002Fwindows\u002F",[81],[95],{"type":57,"value":92},{"type":51,"tag":69,"props":97,"children":98},{},[99],{"type":57,"value":100},"Sample Repository",{"type":57,"value":75},{"type":51,"tag":77,"props":103,"children":106},{"href":104,"rel":105},"https:\u002F\u002Fgithub.com\u002Fzoom\u002Fvideosdk-windows-rawdata-sample",[81],[107],{"type":57,"value":104},{"type":51,"tag":109,"props":110,"children":112},"h2",{"id":111},"quick-links",[113],{"type":57,"value":114},"Quick Links",{"type":51,"tag":60,"props":116,"children":117},{},[118],{"type":51,"tag":69,"props":119,"children":120},{},[121],{"type":57,"value":122},"New to Video SDK? Follow this path:",{"type":51,"tag":124,"props":125,"children":126},"ol",{},[127,142,156,177],{"type":51,"tag":128,"props":129,"children":130},"li",{},[131,140],{"type":51,"tag":69,"props":132,"children":133},{},[134],{"type":51,"tag":77,"props":135,"children":137},{"href":136},"concepts\u002Fsdk-architecture-pattern.md",[138],{"type":57,"value":139},"SDK Architecture Pattern",{"type":57,"value":141}," - Universal 3-step pattern for ANY feature",{"type":51,"tag":128,"props":143,"children":144},{},[145,154],{"type":51,"tag":69,"props":146,"children":147},{},[148],{"type":51,"tag":77,"props":149,"children":151},{"href":150},"examples\u002Fsession-join-pattern.md",[152],{"type":57,"value":153},"Session Join Pattern",{"type":57,"value":155}," - Complete working code to join a session",{"type":51,"tag":128,"props":157,"children":158},{},[159,168,170,175],{"type":51,"tag":69,"props":160,"children":161},{},[162],{"type":51,"tag":77,"props":163,"children":165},{"href":164},"troubleshooting\u002Fwindows-message-loop.md",[166],{"type":57,"value":167},"Windows Message Loop",{"type":57,"value":169}," - ",{"type":51,"tag":69,"props":171,"children":172},{},[173],{"type":57,"value":174},"CRITICAL",{"type":57,"value":176},": Fix callbacks not firing",{"type":51,"tag":128,"props":178,"children":179},{},[180,189],{"type":51,"tag":69,"props":181,"children":182},{},[183],{"type":51,"tag":77,"props":184,"children":186},{"href":185},"examples\u002Fvideo-rendering.md",[187],{"type":57,"value":188},"Video Rendering",{"type":57,"value":190}," - Display video with Canvas API",{"type":51,"tag":60,"props":192,"children":193},{},[194],{"type":51,"tag":69,"props":195,"children":196},{},[197],{"type":57,"value":198},"Reference:",{"type":51,"tag":200,"props":201,"children":202},"ul",{},[203,217,230,244,258,271],{"type":51,"tag":128,"props":204,"children":205},{},[206,215],{"type":51,"tag":69,"props":207,"children":208},{},[209],{"type":51,"tag":77,"props":210,"children":212},{"href":211},"concepts\u002Fsingleton-hierarchy.md",[213],{"type":57,"value":214},"Singleton Hierarchy",{"type":57,"value":216}," - 5-level SDK navigation map",{"type":51,"tag":128,"props":218,"children":219},{},[220,228],{"type":51,"tag":69,"props":221,"children":222},{},[223],{"type":51,"tag":77,"props":224,"children":226},{"href":225},"references\u002Fwindows-reference.md",[227],{"type":57,"value":88},{"type":57,"value":229}," - Methods, error codes, timing rules",{"type":51,"tag":128,"props":231,"children":232},{},[233,242],{"type":51,"tag":69,"props":234,"children":235},{},[236],{"type":51,"tag":77,"props":237,"children":239},{"href":238},"references\u002Fdelegate-methods.md",[240],{"type":57,"value":241},"Delegate Methods",{"type":57,"value":243}," - All 80+ callback methods",{"type":51,"tag":128,"props":245,"children":246},{},[247,256],{"type":51,"tag":69,"props":248,"children":249},{},[250],{"type":51,"tag":77,"props":251,"children":253},{"href":252},"references\u002Fsamples.md",[254],{"type":57,"value":255},"Sample Applications",{"type":57,"value":257}," - Official samples guide",{"type":51,"tag":128,"props":259,"children":260},{},[261,269],{"type":51,"tag":69,"props":262,"children":263},{},[264],{"type":51,"tag":77,"props":265,"children":267},{"href":266},"windows.md",[268],{"type":57,"value":266},{"type":57,"value":270}," - Secondary overview doc (pointer-style)",{"type":51,"tag":128,"props":272,"children":273},{},[274,282],{"type":51,"tag":69,"props":275,"children":276},{},[277],{"type":51,"tag":77,"props":278,"children":280},{"href":279},"SKILL.md",[281],{"type":57,"value":279},{"type":57,"value":283}," - Complete documentation navigation",{"type":51,"tag":60,"props":285,"children":286},{},[287],{"type":51,"tag":69,"props":288,"children":289},{},[290],{"type":57,"value":291},"Having issues?",{"type":51,"tag":200,"props":293,"children":294},{},[295,304,315,335],{"type":51,"tag":128,"props":296,"children":297},{},[298,300],{"type":57,"value":299},"Callbacks not firing → ",{"type":51,"tag":77,"props":301,"children":302},{"href":164},[303],{"type":57,"value":167},{"type":51,"tag":128,"props":305,"children":306},{},[307,309],{"type":57,"value":308},"Build errors → ",{"type":51,"tag":77,"props":310,"children":312},{"href":311},"troubleshooting\u002Fbuild-errors.md",[313],{"type":57,"value":314},"Build Errors Guide",{"type":51,"tag":128,"props":316,"children":317},{},[318,320,324,326,333],{"type":57,"value":319},"Video subscribe fails → ",{"type":51,"tag":77,"props":321,"children":322},{"href":185},[323],{"type":57,"value":188},{"type":57,"value":325}," (subscribe in ",{"type":51,"tag":327,"props":328,"children":330},"code",{"className":329},[],[331],{"type":57,"value":332},"onUserVideoStatusChanged",{"type":57,"value":334},")",{"type":51,"tag":128,"props":336,"children":337},{},[338,340],{"type":57,"value":339},"Quick diagnostics → ",{"type":51,"tag":77,"props":341,"children":343},{"href":342},"troubleshooting\u002Fcommon-issues.md",[344],{"type":57,"value":345},"Common Issues",{"type":51,"tag":60,"props":347,"children":348},{},[349],{"type":51,"tag":69,"props":350,"children":351},{},[352],{"type":57,"value":353},"Building a Custom UI?",{"type":51,"tag":200,"props":355,"children":356},{},[357,368],{"type":51,"tag":128,"props":358,"children":359},{},[360,366],{"type":51,"tag":77,"props":361,"children":363},{"href":362},"concepts\u002Fcanvas-vs-raw-data.md",[364],{"type":57,"value":365},"Canvas vs Raw Data",{"type":57,"value":367}," - Choose your rendering approach",{"type":51,"tag":128,"props":369,"children":370},{},[371,377],{"type":51,"tag":77,"props":372,"children":374},{"href":373},"examples\u002Fraw-video-capture.md",[375],{"type":57,"value":376},"Raw Video Capture",{"type":57,"value":378}," - YUV420 frame processing",{"type":51,"tag":109,"props":380,"children":382},{"id":381},"sdk-overview",[383],{"type":57,"value":384},"SDK Overview",{"type":51,"tag":60,"props":386,"children":387},{},[388],{"type":57,"value":389},"The Zoom Video SDK for Windows is a C++ library that provides:",{"type":51,"tag":200,"props":391,"children":392},{},[393,403,413,423,433,443,453,463,473,483,493,503],{"type":51,"tag":128,"props":394,"children":395},{},[396,401],{"type":51,"tag":69,"props":397,"children":398},{},[399],{"type":57,"value":400},"Session Management",{"type":57,"value":402},": Join\u002Fleave video SDK sessions",{"type":51,"tag":128,"props":404,"children":405},{},[406,411],{"type":51,"tag":69,"props":407,"children":408},{},[409],{"type":57,"value":410},"Raw Data Access",{"type":57,"value":412},": Capture raw audio\u002Fvideo frames (YUV420, PCM)",{"type":51,"tag":128,"props":414,"children":415},{},[416,421],{"type":51,"tag":69,"props":417,"children":418},{},[419],{"type":57,"value":420},"Raw Data Injection",{"type":57,"value":422},": Send custom audio\u002Fvideo into sessions",{"type":51,"tag":128,"props":424,"children":425},{},[426,431],{"type":51,"tag":69,"props":427,"children":428},{},[429],{"type":57,"value":430},"Screen Sharing",{"type":57,"value":432},": Share screens or inject custom share sources",{"type":51,"tag":128,"props":434,"children":435},{},[436,441],{"type":51,"tag":69,"props":437,"children":438},{},[439],{"type":57,"value":440},"Cloud Recording",{"type":57,"value":442},": Record sessions to Zoom cloud",{"type":51,"tag":128,"props":444,"children":445},{},[446,451],{"type":51,"tag":69,"props":447,"children":448},{},[449],{"type":57,"value":450},"Live Streaming",{"type":57,"value":452},": Stream to RTMP endpoints (YouTube, etc.)",{"type":51,"tag":128,"props":454,"children":455},{},[456,461],{"type":51,"tag":69,"props":457,"children":458},{},[459],{"type":57,"value":460},"Chat & Commands",{"type":57,"value":462},": In-session messaging and command channels",{"type":51,"tag":128,"props":464,"children":465},{},[466,471],{"type":51,"tag":69,"props":467,"children":468},{},[469],{"type":57,"value":470},"Live Transcription",{"type":57,"value":472},": Real-time speech-to-text",{"type":51,"tag":128,"props":474,"children":475},{},[476,481],{"type":51,"tag":69,"props":477,"children":478},{},[479],{"type":57,"value":480},"Subsessions",{"type":57,"value":482},": Breakout room support",{"type":51,"tag":128,"props":484,"children":485},{},[486,491],{"type":51,"tag":69,"props":487,"children":488},{},[489],{"type":57,"value":490},"Whiteboard",{"type":57,"value":492},": Collaborative whiteboard features",{"type":51,"tag":128,"props":494,"children":495},{},[496,501],{"type":51,"tag":69,"props":497,"children":498},{},[499],{"type":57,"value":500},"Annotations",{"type":57,"value":502},": Screen share annotations",{"type":51,"tag":128,"props":504,"children":505},{},[506,511],{"type":51,"tag":69,"props":507,"children":508},{},[509],{"type":57,"value":510},"C# Integration",{"type":57,"value":512},": C++\u002FCLI wrapper for .NET applications",{"type":51,"tag":109,"props":514,"children":516},{"id":515},"prerequisites",[517],{"type":57,"value":518},"Prerequisites",{"type":51,"tag":520,"props":521,"children":523},"h3",{"id":522},"system-requirements",[524],{"type":57,"value":525},"System Requirements",{"type":51,"tag":200,"props":527,"children":528},{},[529,539,549,559,569],{"type":51,"tag":128,"props":530,"children":531},{},[532,537],{"type":51,"tag":69,"props":533,"children":534},{},[535],{"type":57,"value":536},"OS",{"type":57,"value":538},": Windows 10 (1903 or later) or Windows 11",{"type":51,"tag":128,"props":540,"children":541},{},[542,547],{"type":51,"tag":69,"props":543,"children":544},{},[545],{"type":57,"value":546},"Architecture",{"type":57,"value":548},": x64 (recommended), x86, or ARM64",{"type":51,"tag":128,"props":550,"children":551},{},[552,557],{"type":51,"tag":69,"props":553,"children":554},{},[555],{"type":57,"value":556},"Visual Studio",{"type":57,"value":558},": 2019 or 2022 (Community, Professional, or Enterprise)",{"type":51,"tag":128,"props":560,"children":561},{},[562,567],{"type":51,"tag":69,"props":563,"children":564},{},[565],{"type":57,"value":566},"Windows SDK",{"type":57,"value":568},": 10.0.19041.0 or later",{"type":51,"tag":128,"props":570,"children":571},{},[572,577],{"type":51,"tag":69,"props":573,"children":574},{},[575],{"type":57,"value":576},".NET Framework",{"type":57,"value":578},": 4.8 or later (for C# applications)",{"type":51,"tag":520,"props":580,"children":582},{"id":581},"visual-studio-workloads",[583],{"type":57,"value":584},"Visual Studio Workloads",{"type":51,"tag":60,"props":586,"children":587},{},[588],{"type":57,"value":589},"Install these workloads via Visual Studio Installer:",{"type":51,"tag":124,"props":591,"children":592},{},[593,619],{"type":51,"tag":128,"props":594,"children":595},{},[596,601],{"type":51,"tag":69,"props":597,"children":598},{},[599],{"type":57,"value":600},"Desktop development with C++",{"type":51,"tag":200,"props":602,"children":603},{},[604,609,614],{"type":51,"tag":128,"props":605,"children":606},{},[607],{"type":57,"value":608},"MSVC v142 or v143 compiler",{"type":51,"tag":128,"props":610,"children":611},{},[612],{"type":57,"value":613},"Windows 10\u002F11 SDK",{"type":51,"tag":128,"props":615,"children":616},{},[617],{"type":57,"value":618},"C++ CMake tools (optional)",{"type":51,"tag":128,"props":620,"children":621},{},[622,627,629],{"type":51,"tag":69,"props":623,"children":624},{},[625],{"type":57,"value":626},".NET desktop development",{"type":57,"value":628}," (for C# applications)",{"type":51,"tag":200,"props":630,"children":631},{},[632,637],{"type":51,"tag":128,"props":633,"children":634},{},[635],{"type":57,"value":636},".NET Framework 4.8 targeting pack",{"type":51,"tag":128,"props":638,"children":639},{},[640],{"type":57,"value":641},"C++\u002FCLI support",{"type":51,"tag":109,"props":643,"children":645},{"id":644},"quick-start",[646],{"type":57,"value":647},"Quick Start",{"type":51,"tag":520,"props":649,"children":651},{"id":650},"c-application",[652],{"type":57,"value":653},"C++ Application",{"type":51,"tag":655,"props":656,"children":661},"pre",{"className":657,"code":658,"language":659,"meta":660,"style":660},"language-cpp shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","#include \u003Cwindows.h>\n#include \"zoom_video_sdk_api.h\"\n#include \"zoom_video_sdk_interface.h\"\n#include \"zoom_video_sdk_delegate_interface.h\"\n\nUSING_ZOOM_VIDEO_SDK_NAMESPACE\n\n\u002F\u002F 1. Create SDK object\nIZoomVideoSDK* video_sdk_obj = CreateZoomVideoSDKObj();\n\n\u002F\u002F 2. Initialize\nZoomVideoSDKInitParams init_params;\ninit_params.domain = L\"https:\u002F\u002Fzoom.us\";\ninit_params.enableLog = true;\ninit_params.logFilePrefix = L\"zoom_win_video\";\ninit_params.videoRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap;\ninit_params.shareRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap;\ninit_params.audioRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap;\n\nZoomVideoSDKErrors err = video_sdk_obj->initialize(init_params);\n\n\u002F\u002F 3. Add event listener\nvideo_sdk_obj->addListener(myDelegate);\n\n\u002F\u002F 4. Join session (IMPORTANT: set audioOption.connect = false)\nZoomVideoSDKSessionContext session_context;\nsession_context.sessionName = L\"my-session\";\nsession_context.userName = L\"Windows User\";\nsession_context.token = L\"your-jwt-token\";\nsession_context.videoOption.localVideoOn = false;\nsession_context.audioOption.connect = false;  \u002F\u002F Connect audio after join\nsession_context.audioOption.mute = true;\n\nIZoomVideoSDKSession* session = video_sdk_obj->joinSession(session_context);\n\n\u002F\u002F 5. CRITICAL: Add Windows message pump for callbacks to work\nbool running = true;\nwhile (running) {\n    \u002F\u002F Process Windows messages (required for SDK callbacks)\n    MSG msg;\n    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {\n        TranslateMessage(&msg);\n        DispatchMessage(&msg);\n    }\n    \n    \u002F\u002F Your application logic here\n    Sleep(10);\n}\n","cpp","",[662],{"type":51,"tag":327,"props":663,"children":664},{"__ignoreMap":660},[665,676,685,694,703,713,722,730,739,748,756,765,774,783,792,801,810,819,828,836,845,853,862,871,879,888,897,906,915,924,933,942,951,959,968,976,985,994,1003,1012,1021,1030,1039,1048,1057,1066,1075,1084],{"type":51,"tag":666,"props":667,"children":670},"span",{"class":668,"line":669},"line",1,[671],{"type":51,"tag":666,"props":672,"children":673},{},[674],{"type":57,"value":675},"#include \u003Cwindows.h>\n",{"type":51,"tag":666,"props":677,"children":679},{"class":668,"line":678},2,[680],{"type":51,"tag":666,"props":681,"children":682},{},[683],{"type":57,"value":684},"#include \"zoom_video_sdk_api.h\"\n",{"type":51,"tag":666,"props":686,"children":688},{"class":668,"line":687},3,[689],{"type":51,"tag":666,"props":690,"children":691},{},[692],{"type":57,"value":693},"#include \"zoom_video_sdk_interface.h\"\n",{"type":51,"tag":666,"props":695,"children":697},{"class":668,"line":696},4,[698],{"type":51,"tag":666,"props":699,"children":700},{},[701],{"type":57,"value":702},"#include \"zoom_video_sdk_delegate_interface.h\"\n",{"type":51,"tag":666,"props":704,"children":706},{"class":668,"line":705},5,[707],{"type":51,"tag":666,"props":708,"children":710},{"emptyLinePlaceholder":709},true,[711],{"type":57,"value":712},"\n",{"type":51,"tag":666,"props":714,"children":716},{"class":668,"line":715},6,[717],{"type":51,"tag":666,"props":718,"children":719},{},[720],{"type":57,"value":721},"USING_ZOOM_VIDEO_SDK_NAMESPACE\n",{"type":51,"tag":666,"props":723,"children":725},{"class":668,"line":724},7,[726],{"type":51,"tag":666,"props":727,"children":728},{"emptyLinePlaceholder":709},[729],{"type":57,"value":712},{"type":51,"tag":666,"props":731,"children":733},{"class":668,"line":732},8,[734],{"type":51,"tag":666,"props":735,"children":736},{},[737],{"type":57,"value":738},"\u002F\u002F 1. Create SDK object\n",{"type":51,"tag":666,"props":740,"children":742},{"class":668,"line":741},9,[743],{"type":51,"tag":666,"props":744,"children":745},{},[746],{"type":57,"value":747},"IZoomVideoSDK* video_sdk_obj = CreateZoomVideoSDKObj();\n",{"type":51,"tag":666,"props":749,"children":751},{"class":668,"line":750},10,[752],{"type":51,"tag":666,"props":753,"children":754},{"emptyLinePlaceholder":709},[755],{"type":57,"value":712},{"type":51,"tag":666,"props":757,"children":759},{"class":668,"line":758},11,[760],{"type":51,"tag":666,"props":761,"children":762},{},[763],{"type":57,"value":764},"\u002F\u002F 2. Initialize\n",{"type":51,"tag":666,"props":766,"children":768},{"class":668,"line":767},12,[769],{"type":51,"tag":666,"props":770,"children":771},{},[772],{"type":57,"value":773},"ZoomVideoSDKInitParams init_params;\n",{"type":51,"tag":666,"props":775,"children":777},{"class":668,"line":776},13,[778],{"type":51,"tag":666,"props":779,"children":780},{},[781],{"type":57,"value":782},"init_params.domain = L\"https:\u002F\u002Fzoom.us\";\n",{"type":51,"tag":666,"props":784,"children":786},{"class":668,"line":785},14,[787],{"type":51,"tag":666,"props":788,"children":789},{},[790],{"type":57,"value":791},"init_params.enableLog = true;\n",{"type":51,"tag":666,"props":793,"children":795},{"class":668,"line":794},15,[796],{"type":51,"tag":666,"props":797,"children":798},{},[799],{"type":57,"value":800},"init_params.logFilePrefix = L\"zoom_win_video\";\n",{"type":51,"tag":666,"props":802,"children":804},{"class":668,"line":803},16,[805],{"type":51,"tag":666,"props":806,"children":807},{},[808],{"type":57,"value":809},"init_params.videoRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap;\n",{"type":51,"tag":666,"props":811,"children":813},{"class":668,"line":812},17,[814],{"type":51,"tag":666,"props":815,"children":816},{},[817],{"type":57,"value":818},"init_params.shareRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap;\n",{"type":51,"tag":666,"props":820,"children":822},{"class":668,"line":821},18,[823],{"type":51,"tag":666,"props":824,"children":825},{},[826],{"type":57,"value":827},"init_params.audioRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap;\n",{"type":51,"tag":666,"props":829,"children":831},{"class":668,"line":830},19,[832],{"type":51,"tag":666,"props":833,"children":834},{"emptyLinePlaceholder":709},[835],{"type":57,"value":712},{"type":51,"tag":666,"props":837,"children":839},{"class":668,"line":838},20,[840],{"type":51,"tag":666,"props":841,"children":842},{},[843],{"type":57,"value":844},"ZoomVideoSDKErrors err = video_sdk_obj->initialize(init_params);\n",{"type":51,"tag":666,"props":846,"children":848},{"class":668,"line":847},21,[849],{"type":51,"tag":666,"props":850,"children":851},{"emptyLinePlaceholder":709},[852],{"type":57,"value":712},{"type":51,"tag":666,"props":854,"children":856},{"class":668,"line":855},22,[857],{"type":51,"tag":666,"props":858,"children":859},{},[860],{"type":57,"value":861},"\u002F\u002F 3. Add event listener\n",{"type":51,"tag":666,"props":863,"children":865},{"class":668,"line":864},23,[866],{"type":51,"tag":666,"props":867,"children":868},{},[869],{"type":57,"value":870},"video_sdk_obj->addListener(myDelegate);\n",{"type":51,"tag":666,"props":872,"children":874},{"class":668,"line":873},24,[875],{"type":51,"tag":666,"props":876,"children":877},{"emptyLinePlaceholder":709},[878],{"type":57,"value":712},{"type":51,"tag":666,"props":880,"children":882},{"class":668,"line":881},25,[883],{"type":51,"tag":666,"props":884,"children":885},{},[886],{"type":57,"value":887},"\u002F\u002F 4. Join session (IMPORTANT: set audioOption.connect = false)\n",{"type":51,"tag":666,"props":889,"children":891},{"class":668,"line":890},26,[892],{"type":51,"tag":666,"props":893,"children":894},{},[895],{"type":57,"value":896},"ZoomVideoSDKSessionContext session_context;\n",{"type":51,"tag":666,"props":898,"children":900},{"class":668,"line":899},27,[901],{"type":51,"tag":666,"props":902,"children":903},{},[904],{"type":57,"value":905},"session_context.sessionName = L\"my-session\";\n",{"type":51,"tag":666,"props":907,"children":909},{"class":668,"line":908},28,[910],{"type":51,"tag":666,"props":911,"children":912},{},[913],{"type":57,"value":914},"session_context.userName = L\"Windows User\";\n",{"type":51,"tag":666,"props":916,"children":918},{"class":668,"line":917},29,[919],{"type":51,"tag":666,"props":920,"children":921},{},[922],{"type":57,"value":923},"session_context.token = L\"your-jwt-token\";\n",{"type":51,"tag":666,"props":925,"children":927},{"class":668,"line":926},30,[928],{"type":51,"tag":666,"props":929,"children":930},{},[931],{"type":57,"value":932},"session_context.videoOption.localVideoOn = false;\n",{"type":51,"tag":666,"props":934,"children":936},{"class":668,"line":935},31,[937],{"type":51,"tag":666,"props":938,"children":939},{},[940],{"type":57,"value":941},"session_context.audioOption.connect = false;  \u002F\u002F Connect audio after join\n",{"type":51,"tag":666,"props":943,"children":945},{"class":668,"line":944},32,[946],{"type":51,"tag":666,"props":947,"children":948},{},[949],{"type":57,"value":950},"session_context.audioOption.mute = true;\n",{"type":51,"tag":666,"props":952,"children":954},{"class":668,"line":953},33,[955],{"type":51,"tag":666,"props":956,"children":957},{"emptyLinePlaceholder":709},[958],{"type":57,"value":712},{"type":51,"tag":666,"props":960,"children":962},{"class":668,"line":961},34,[963],{"type":51,"tag":666,"props":964,"children":965},{},[966],{"type":57,"value":967},"IZoomVideoSDKSession* session = video_sdk_obj->joinSession(session_context);\n",{"type":51,"tag":666,"props":969,"children":971},{"class":668,"line":970},35,[972],{"type":51,"tag":666,"props":973,"children":974},{"emptyLinePlaceholder":709},[975],{"type":57,"value":712},{"type":51,"tag":666,"props":977,"children":979},{"class":668,"line":978},36,[980],{"type":51,"tag":666,"props":981,"children":982},{},[983],{"type":57,"value":984},"\u002F\u002F 5. CRITICAL: Add Windows message pump for callbacks to work\n",{"type":51,"tag":666,"props":986,"children":988},{"class":668,"line":987},37,[989],{"type":51,"tag":666,"props":990,"children":991},{},[992],{"type":57,"value":993},"bool running = true;\n",{"type":51,"tag":666,"props":995,"children":997},{"class":668,"line":996},38,[998],{"type":51,"tag":666,"props":999,"children":1000},{},[1001],{"type":57,"value":1002},"while (running) {\n",{"type":51,"tag":666,"props":1004,"children":1006},{"class":668,"line":1005},39,[1007],{"type":51,"tag":666,"props":1008,"children":1009},{},[1010],{"type":57,"value":1011},"    \u002F\u002F Process Windows messages (required for SDK callbacks)\n",{"type":51,"tag":666,"props":1013,"children":1015},{"class":668,"line":1014},40,[1016],{"type":51,"tag":666,"props":1017,"children":1018},{},[1019],{"type":57,"value":1020},"    MSG msg;\n",{"type":51,"tag":666,"props":1022,"children":1024},{"class":668,"line":1023},41,[1025],{"type":51,"tag":666,"props":1026,"children":1027},{},[1028],{"type":57,"value":1029},"    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {\n",{"type":51,"tag":666,"props":1031,"children":1033},{"class":668,"line":1032},42,[1034],{"type":51,"tag":666,"props":1035,"children":1036},{},[1037],{"type":57,"value":1038},"        TranslateMessage(&msg);\n",{"type":51,"tag":666,"props":1040,"children":1042},{"class":668,"line":1041},43,[1043],{"type":51,"tag":666,"props":1044,"children":1045},{},[1046],{"type":57,"value":1047},"        DispatchMessage(&msg);\n",{"type":51,"tag":666,"props":1049,"children":1051},{"class":668,"line":1050},44,[1052],{"type":51,"tag":666,"props":1053,"children":1054},{},[1055],{"type":57,"value":1056},"    }\n",{"type":51,"tag":666,"props":1058,"children":1060},{"class":668,"line":1059},45,[1061],{"type":51,"tag":666,"props":1062,"children":1063},{},[1064],{"type":57,"value":1065},"    \n",{"type":51,"tag":666,"props":1067,"children":1069},{"class":668,"line":1068},46,[1070],{"type":51,"tag":666,"props":1071,"children":1072},{},[1073],{"type":57,"value":1074},"    \u002F\u002F Your application logic here\n",{"type":51,"tag":666,"props":1076,"children":1078},{"class":668,"line":1077},47,[1079],{"type":51,"tag":666,"props":1080,"children":1081},{},[1082],{"type":57,"value":1083},"    Sleep(10);\n",{"type":51,"tag":666,"props":1085,"children":1087},{"class":668,"line":1086},48,[1088],{"type":51,"tag":666,"props":1089,"children":1090},{},[1091],{"type":57,"value":1092},"}\n",{"type":51,"tag":520,"props":1094,"children":1096},{"id":1095},"c-application-1",[1097],{"type":57,"value":1098},"C# Application",{"type":51,"tag":655,"props":1100,"children":1104},{"className":1101,"code":1102,"language":1103,"meta":660,"style":660},"language-csharp shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","using ZoomVideoSDK;\n\nvar sdkManager = new ZoomSDKManager();\nsdkManager.Initialize();\nsdkManager.JoinSession(\"my-session\", \"jwt-token\", \"User Name\", \"\");\n","csharp",[1105],{"type":51,"tag":327,"props":1106,"children":1107},{"__ignoreMap":660},[1108,1116,1123,1131,1139],{"type":51,"tag":666,"props":1109,"children":1110},{"class":668,"line":669},[1111],{"type":51,"tag":666,"props":1112,"children":1113},{},[1114],{"type":57,"value":1115},"using ZoomVideoSDK;\n",{"type":51,"tag":666,"props":1117,"children":1118},{"class":668,"line":678},[1119],{"type":51,"tag":666,"props":1120,"children":1121},{"emptyLinePlaceholder":709},[1122],{"type":57,"value":712},{"type":51,"tag":666,"props":1124,"children":1125},{"class":668,"line":687},[1126],{"type":51,"tag":666,"props":1127,"children":1128},{},[1129],{"type":57,"value":1130},"var sdkManager = new ZoomSDKManager();\n",{"type":51,"tag":666,"props":1132,"children":1133},{"class":668,"line":696},[1134],{"type":51,"tag":666,"props":1135,"children":1136},{},[1137],{"type":57,"value":1138},"sdkManager.Initialize();\n",{"type":51,"tag":666,"props":1140,"children":1141},{"class":668,"line":705},[1142],{"type":51,"tag":666,"props":1143,"children":1144},{},[1145],{"type":57,"value":1146},"sdkManager.JoinSession(\"my-session\", \"jwt-token\", \"User Name\", \"\");\n",{"type":51,"tag":109,"props":1148,"children":1150},{"id":1149},"key-features",[1151],{"type":57,"value":1152},"Key Features",{"type":51,"tag":1154,"props":1155,"children":1156},"table",{},[1157,1176],{"type":51,"tag":1158,"props":1159,"children":1160},"thead",{},[1161],{"type":51,"tag":1162,"props":1163,"children":1164},"tr",{},[1165,1171],{"type":51,"tag":1166,"props":1167,"children":1168},"th",{},[1169],{"type":57,"value":1170},"Feature",{"type":51,"tag":1166,"props":1172,"children":1173},{},[1174],{"type":57,"value":1175},"Description",{"type":51,"tag":1177,"props":1178,"children":1179},"tbody",{},[1180,1196,1212,1228,1243,1258,1273,1289,1305,1320],{"type":51,"tag":1162,"props":1181,"children":1182},{},[1183,1191],{"type":51,"tag":1184,"props":1185,"children":1186},"td",{},[1187],{"type":51,"tag":69,"props":1188,"children":1189},{},[1190],{"type":57,"value":400},{"type":51,"tag":1184,"props":1192,"children":1193},{},[1194],{"type":57,"value":1195},"Join, leave, and manage video sessions",{"type":51,"tag":1162,"props":1197,"children":1198},{},[1199,1207],{"type":51,"tag":1184,"props":1200,"children":1201},{},[1202],{"type":51,"tag":69,"props":1203,"children":1204},{},[1205],{"type":57,"value":1206},"Raw Video (YUV I420)",{"type":51,"tag":1184,"props":1208,"children":1209},{},[1210],{"type":57,"value":1211},"Capture and inject raw video frames",{"type":51,"tag":1162,"props":1213,"children":1214},{},[1215,1223],{"type":51,"tag":1184,"props":1216,"children":1217},{},[1218],{"type":51,"tag":69,"props":1219,"children":1220},{},[1221],{"type":57,"value":1222},"Raw Audio (PCM)",{"type":51,"tag":1184,"props":1224,"children":1225},{},[1226],{"type":57,"value":1227},"Capture and inject raw audio data",{"type":51,"tag":1162,"props":1229,"children":1230},{},[1231,1238],{"type":51,"tag":1184,"props":1232,"children":1233},{},[1234],{"type":51,"tag":69,"props":1235,"children":1236},{},[1237],{"type":57,"value":430},{"type":51,"tag":1184,"props":1239,"children":1240},{},[1241],{"type":57,"value":1242},"Share screens or custom content",{"type":51,"tag":1162,"props":1244,"children":1245},{},[1246,1253],{"type":51,"tag":1184,"props":1247,"children":1248},{},[1249],{"type":51,"tag":69,"props":1250,"children":1251},{},[1252],{"type":57,"value":440},{"type":51,"tag":1184,"props":1254,"children":1255},{},[1256],{"type":57,"value":1257},"Record sessions to Zoom cloud",{"type":51,"tag":1162,"props":1259,"children":1260},{},[1261,1268],{"type":51,"tag":1184,"props":1262,"children":1263},{},[1264],{"type":51,"tag":69,"props":1265,"children":1266},{},[1267],{"type":57,"value":450},{"type":51,"tag":1184,"props":1269,"children":1270},{},[1271],{"type":57,"value":1272},"Stream to RTMP endpoints",{"type":51,"tag":1162,"props":1274,"children":1275},{},[1276,1284],{"type":51,"tag":1184,"props":1277,"children":1278},{},[1279],{"type":51,"tag":69,"props":1280,"children":1281},{},[1282],{"type":57,"value":1283},"Chat",{"type":51,"tag":1184,"props":1285,"children":1286},{},[1287],{"type":57,"value":1288},"Send\u002Freceive chat messages",{"type":51,"tag":1162,"props":1290,"children":1291},{},[1292,1300],{"type":51,"tag":1184,"props":1293,"children":1294},{},[1295],{"type":51,"tag":69,"props":1296,"children":1297},{},[1298],{"type":57,"value":1299},"Command Channel",{"type":51,"tag":1184,"props":1301,"children":1302},{},[1303],{"type":57,"value":1304},"Custom command messaging",{"type":51,"tag":1162,"props":1306,"children":1307},{},[1308,1315],{"type":51,"tag":1184,"props":1309,"children":1310},{},[1311],{"type":51,"tag":69,"props":1312,"children":1313},{},[1314],{"type":57,"value":470},{"type":51,"tag":1184,"props":1316,"children":1317},{},[1318],{"type":57,"value":1319},"Real-time speech-to-text",{"type":51,"tag":1162,"props":1321,"children":1322},{},[1323,1331],{"type":51,"tag":1184,"props":1324,"children":1325},{},[1326],{"type":51,"tag":69,"props":1327,"children":1328},{},[1329],{"type":57,"value":1330},"C# Support",{"type":51,"tag":1184,"props":1332,"children":1333},{},[1334],{"type":57,"value":1335},"Full .NET Framework integration",{"type":51,"tag":109,"props":1337,"children":1339},{"id":1338},"sample-applications",[1340],{"type":57,"value":255},{"type":51,"tag":60,"props":1342,"children":1343},{},[1344,1349,1350],{"type":51,"tag":69,"props":1345,"children":1346},{},[1347],{"type":57,"value":1348},"Official Repository",{"type":57,"value":75},{"type":51,"tag":77,"props":1351,"children":1353},{"href":104,"rel":1352},[81],[1354],{"type":57,"value":104},{"type":51,"tag":1154,"props":1356,"children":1357},{},[1358,1373],{"type":51,"tag":1158,"props":1359,"children":1360},{},[1361],{"type":51,"tag":1162,"props":1362,"children":1363},{},[1364,1369],{"type":51,"tag":1166,"props":1365,"children":1366},{},[1367],{"type":57,"value":1368},"Sample",{"type":51,"tag":1166,"props":1370,"children":1371},{},[1372],{"type":57,"value":1175},{"type":51,"tag":1177,"props":1374,"children":1375},{},[1376,1394,1407,1420,1433,1446,1459,1471],{"type":51,"tag":1162,"props":1377,"children":1378},{},[1379,1384],{"type":51,"tag":1184,"props":1380,"children":1381},{},[1382],{"type":57,"value":1383},"VSDK_SkeletonDemo",{"type":51,"tag":1184,"props":1385,"children":1386},{},[1387,1389],{"type":57,"value":1388},"Minimal session join - ",{"type":51,"tag":69,"props":1390,"children":1391},{},[1392],{"type":57,"value":1393},"start here",{"type":51,"tag":1162,"props":1395,"children":1396},{},[1397,1402],{"type":51,"tag":1184,"props":1398,"children":1399},{},[1400],{"type":57,"value":1401},"VSDK_getRawVideo",{"type":51,"tag":1184,"props":1403,"children":1404},{},[1405],{"type":57,"value":1406},"Capture YUV420 video frames",{"type":51,"tag":1162,"props":1408,"children":1409},{},[1410,1415],{"type":51,"tag":1184,"props":1411,"children":1412},{},[1413],{"type":57,"value":1414},"VSDK_getRawAudio",{"type":51,"tag":1184,"props":1416,"children":1417},{},[1418],{"type":57,"value":1419},"Capture PCM audio",{"type":51,"tag":1162,"props":1421,"children":1422},{},[1423,1428],{"type":51,"tag":1184,"props":1424,"children":1425},{},[1426],{"type":57,"value":1427},"VSDK_sendRawVideo",{"type":51,"tag":1184,"props":1429,"children":1430},{},[1431],{"type":57,"value":1432},"Inject custom video (virtual camera)",{"type":51,"tag":1162,"props":1434,"children":1435},{},[1436,1441],{"type":51,"tag":1184,"props":1437,"children":1438},{},[1439],{"type":57,"value":1440},"VSDK_sendRawAudio",{"type":51,"tag":1184,"props":1442,"children":1443},{},[1444],{"type":57,"value":1445},"Inject custom audio (virtual mic)",{"type":51,"tag":1162,"props":1447,"children":1448},{},[1449,1454],{"type":51,"tag":1184,"props":1450,"children":1451},{},[1452],{"type":57,"value":1453},"VSDK_CloudRecording",{"type":51,"tag":1184,"props":1455,"children":1456},{},[1457],{"type":57,"value":1458},"Cloud recording control",{"type":51,"tag":1162,"props":1460,"children":1461},{},[1462,1467],{"type":51,"tag":1184,"props":1463,"children":1464},{},[1465],{"type":57,"value":1466},"VSDK_CommandChannel",{"type":51,"tag":1184,"props":1468,"children":1469},{},[1470],{"type":57,"value":1304},{"type":51,"tag":1162,"props":1472,"children":1473},{},[1474,1479],{"type":51,"tag":1184,"props":1475,"children":1476},{},[1477],{"type":57,"value":1478},"VSDK_TranscriptionAndTranslation",{"type":51,"tag":1184,"props":1480,"children":1481},{},[1482],{"type":57,"value":1483},"Live captions",{"type":51,"tag":60,"props":1485,"children":1486},{},[1487,1492,1493],{"type":51,"tag":69,"props":1488,"children":1489},{},[1490],{"type":57,"value":1491},"See complete guide",{"type":57,"value":75},{"type":51,"tag":77,"props":1494,"children":1495},{"href":252},[1496],{"type":57,"value":1497},"Sample Applications Reference",{"type":51,"tag":109,"props":1499,"children":1501},{"id":1500},"critical-gotchas-and-best-practices",[1502],{"type":57,"value":1503},"Critical Gotchas and Best Practices",{"type":51,"tag":520,"props":1505,"children":1507},{"id":1506},"️-critical-windows-message-pump-required",[1508],{"type":57,"value":1509},"⚠️ CRITICAL: Windows Message Pump Required",{"type":51,"tag":60,"props":1511,"children":1512},{},[1513],{"type":51,"tag":69,"props":1514,"children":1515},{},[1516],{"type":57,"value":1517},"The #1 issue that causes session joins to hang with no callbacks:",{"type":51,"tag":60,"props":1519,"children":1520},{},[1521,1523,1528,1530,1536,1538,1544],{"type":57,"value":1522},"All Windows applications using the Zoom SDK ",{"type":51,"tag":69,"props":1524,"children":1525},{},[1526],{"type":57,"value":1527},"MUST",{"type":57,"value":1529}," process Windows messages. The SDK uses Windows messages to deliver callbacks like ",{"type":51,"tag":327,"props":1531,"children":1533},{"className":1532},[],[1534],{"type":57,"value":1535},"onSessionJoin()",{"type":57,"value":1537},", ",{"type":51,"tag":327,"props":1539,"children":1541},{"className":1540},[],[1542],{"type":57,"value":1543},"onError()",{"type":57,"value":1545},", etc.",{"type":51,"tag":60,"props":1547,"children":1548},{},[1549,1554,1556,1562],{"type":51,"tag":69,"props":1550,"children":1551},{},[1552],{"type":57,"value":1553},"Problem",{"type":57,"value":1555},": Without a message pump, ",{"type":51,"tag":327,"props":1557,"children":1559},{"className":1558},[],[1560],{"type":57,"value":1561},"joinSession()",{"type":57,"value":1563}," appears to succeed but callbacks never fire.",{"type":51,"tag":60,"props":1565,"children":1566},{},[1567,1572],{"type":51,"tag":69,"props":1568,"children":1569},{},[1570],{"type":57,"value":1571},"Solution",{"type":57,"value":1573},": Add this to your main loop:",{"type":51,"tag":655,"props":1575,"children":1577},{"className":657,"code":1576,"language":659,"meta":660,"style":660},"while (running) {\n    \u002F\u002F REQUIRED: Process Windows messages\n    MSG msg;\n    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {\n        TranslateMessage(&msg);\n        DispatchMessage(&msg);\n    }\n    \n    \u002F\u002F Your application logic\n    Sleep(10);\n}\n",[1578],{"type":51,"tag":327,"props":1579,"children":1580},{"__ignoreMap":660},[1581,1588,1596,1603,1610,1617,1624,1631,1638,1646,1653],{"type":51,"tag":666,"props":1582,"children":1583},{"class":668,"line":669},[1584],{"type":51,"tag":666,"props":1585,"children":1586},{},[1587],{"type":57,"value":1002},{"type":51,"tag":666,"props":1589,"children":1590},{"class":668,"line":678},[1591],{"type":51,"tag":666,"props":1592,"children":1593},{},[1594],{"type":57,"value":1595},"    \u002F\u002F REQUIRED: Process Windows messages\n",{"type":51,"tag":666,"props":1597,"children":1598},{"class":668,"line":687},[1599],{"type":51,"tag":666,"props":1600,"children":1601},{},[1602],{"type":57,"value":1020},{"type":51,"tag":666,"props":1604,"children":1605},{"class":668,"line":696},[1606],{"type":51,"tag":666,"props":1607,"children":1608},{},[1609],{"type":57,"value":1029},{"type":51,"tag":666,"props":1611,"children":1612},{"class":668,"line":705},[1613],{"type":51,"tag":666,"props":1614,"children":1615},{},[1616],{"type":57,"value":1038},{"type":51,"tag":666,"props":1618,"children":1619},{"class":668,"line":715},[1620],{"type":51,"tag":666,"props":1621,"children":1622},{},[1623],{"type":57,"value":1047},{"type":51,"tag":666,"props":1625,"children":1626},{"class":668,"line":724},[1627],{"type":51,"tag":666,"props":1628,"children":1629},{},[1630],{"type":57,"value":1056},{"type":51,"tag":666,"props":1632,"children":1633},{"class":668,"line":732},[1634],{"type":51,"tag":666,"props":1635,"children":1636},{},[1637],{"type":57,"value":1065},{"type":51,"tag":666,"props":1639,"children":1640},{"class":668,"line":741},[1641],{"type":51,"tag":666,"props":1642,"children":1643},{},[1644],{"type":57,"value":1645},"    \u002F\u002F Your application logic\n",{"type":51,"tag":666,"props":1647,"children":1648},{"class":668,"line":750},[1649],{"type":51,"tag":666,"props":1650,"children":1651},{},[1652],{"type":57,"value":1083},{"type":51,"tag":666,"props":1654,"children":1655},{"class":668,"line":758},[1656],{"type":51,"tag":666,"props":1657,"children":1658},{},[1659],{"type":57,"value":1092},{"type":51,"tag":60,"props":1661,"children":1662},{},[1663,1668],{"type":51,"tag":69,"props":1664,"children":1665},{},[1666],{"type":57,"value":1667},"Applies to",{"type":57,"value":1669},":",{"type":51,"tag":200,"props":1671,"children":1672},{},[1673,1678,1683],{"type":51,"tag":128,"props":1674,"children":1675},{},[1676],{"type":57,"value":1677},"Console applications (no automatic message pump)",{"type":51,"tag":128,"props":1679,"children":1680},{},[1681],{"type":57,"value":1682},"Custom main loops",{"type":51,"tag":128,"props":1684,"children":1685},{},[1686],{"type":57,"value":1687},"Applications that don't use standard WinMain\u002FWndProc",{"type":51,"tag":60,"props":1689,"children":1690},{},[1691,1696],{"type":51,"tag":69,"props":1692,"children":1693},{},[1694],{"type":57,"value":1695},"GUI applications",{"type":57,"value":1697}," using WinMain with standard message loop already have this.",{"type":51,"tag":520,"props":1699,"children":1701},{"id":1700},"audio-connection-strategy",[1702],{"type":57,"value":1703},"Audio Connection Strategy",{"type":51,"tag":60,"props":1705,"children":1706},{},[1707,1712,1714,1720,1722,1727],{"type":51,"tag":69,"props":1708,"children":1709},{},[1710],{"type":57,"value":1711},"Best Practice",{"type":57,"value":1713},": Set ",{"type":51,"tag":327,"props":1715,"children":1717},{"className":1716},[],[1718],{"type":57,"value":1719},"audioOption.connect = false",{"type":57,"value":1721}," when joining, then connect audio in the ",{"type":51,"tag":327,"props":1723,"children":1725},{"className":1724},[],[1726],{"type":57,"value":1535},{"type":57,"value":1728}," callback.",{"type":51,"tag":655,"props":1730,"children":1732},{"className":657,"code":1731,"language":659,"meta":660,"style":660},"\u002F\u002F During join\nsession_context.audioOption.connect = false;  \u002F\u002F Don't connect yet\nsession_context.audioOption.mute = true;\n\n\u002F\u002F In onSessionJoin() callback\nvoid onSessionJoin() override {\n    IZoomVideoSDKAudioHelper* audioHelper = video_sdk_obj->getAudioHelper();\n    if (audioHelper) {\n        audioHelper->startAudio();  \u002F\u002F Connect now\n    }\n}\n",[1733],{"type":51,"tag":327,"props":1734,"children":1735},{"__ignoreMap":660},[1736,1744,1752,1759,1766,1774,1782,1790,1798,1806,1813],{"type":51,"tag":666,"props":1737,"children":1738},{"class":668,"line":669},[1739],{"type":51,"tag":666,"props":1740,"children":1741},{},[1742],{"type":57,"value":1743},"\u002F\u002F During join\n",{"type":51,"tag":666,"props":1745,"children":1746},{"class":668,"line":678},[1747],{"type":51,"tag":666,"props":1748,"children":1749},{},[1750],{"type":57,"value":1751},"session_context.audioOption.connect = false;  \u002F\u002F Don't connect yet\n",{"type":51,"tag":666,"props":1753,"children":1754},{"class":668,"line":687},[1755],{"type":51,"tag":666,"props":1756,"children":1757},{},[1758],{"type":57,"value":950},{"type":51,"tag":666,"props":1760,"children":1761},{"class":668,"line":696},[1762],{"type":51,"tag":666,"props":1763,"children":1764},{"emptyLinePlaceholder":709},[1765],{"type":57,"value":712},{"type":51,"tag":666,"props":1767,"children":1768},{"class":668,"line":705},[1769],{"type":51,"tag":666,"props":1770,"children":1771},{},[1772],{"type":57,"value":1773},"\u002F\u002F In onSessionJoin() callback\n",{"type":51,"tag":666,"props":1775,"children":1776},{"class":668,"line":715},[1777],{"type":51,"tag":666,"props":1778,"children":1779},{},[1780],{"type":57,"value":1781},"void onSessionJoin() override {\n",{"type":51,"tag":666,"props":1783,"children":1784},{"class":668,"line":724},[1785],{"type":51,"tag":666,"props":1786,"children":1787},{},[1788],{"type":57,"value":1789},"    IZoomVideoSDKAudioHelper* audioHelper = video_sdk_obj->getAudioHelper();\n",{"type":51,"tag":666,"props":1791,"children":1792},{"class":668,"line":732},[1793],{"type":51,"tag":666,"props":1794,"children":1795},{},[1796],{"type":57,"value":1797},"    if (audioHelper) {\n",{"type":51,"tag":666,"props":1799,"children":1800},{"class":668,"line":741},[1801],{"type":51,"tag":666,"props":1802,"children":1803},{},[1804],{"type":57,"value":1805},"        audioHelper->startAudio();  \u002F\u002F Connect now\n",{"type":51,"tag":666,"props":1807,"children":1808},{"class":668,"line":750},[1809],{"type":51,"tag":666,"props":1810,"children":1811},{},[1812],{"type":57,"value":1056},{"type":51,"tag":666,"props":1814,"children":1815},{"class":668,"line":758},[1816],{"type":51,"tag":666,"props":1817,"children":1818},{},[1819],{"type":57,"value":1092},{"type":51,"tag":60,"props":1821,"children":1822},{},[1823,1828],{"type":51,"tag":69,"props":1824,"children":1825},{},[1826],{"type":57,"value":1827},"Why",{"type":57,"value":1829},": This pattern is used in all official Zoom samples. It separates session join from audio initialization for better reliability and error handling.",{"type":51,"tag":520,"props":1831,"children":1833},{"id":1832},"all-delegate-callbacks-must-be-implemented",[1834],{"type":57,"value":1835},"All Delegate Callbacks Must Be Implemented",{"type":51,"tag":60,"props":1837,"children":1838},{},[1839,1841,1847,1849,1854],{"type":57,"value":1840},"The ",{"type":51,"tag":327,"props":1842,"children":1844},{"className":1843},[],[1845],{"type":57,"value":1846},"IZoomVideoSDKDelegate",{"type":57,"value":1848}," interface has 70+ pure virtual methods. ",{"type":51,"tag":69,"props":1850,"children":1851},{},[1852],{"type":57,"value":1853},"ALL must be implemented",{"type":57,"value":1855},", even if empty:",{"type":51,"tag":655,"props":1857,"children":1859},{"className":657,"code":1858,"language":659,"meta":660,"style":660},"\u002F\u002F Required even if you don't use them\nvoid onProxyDetectComplete() override {}\nvoid onUserWhiteboardShareStatusChanged(IZoomVideoSDKUser*, IZoomVideoSDKWhiteboardHelper*) override {}\n\u002F\u002F ... etc\n",[1860],{"type":51,"tag":327,"props":1861,"children":1862},{"__ignoreMap":660},[1863,1871,1879,1887],{"type":51,"tag":666,"props":1864,"children":1865},{"class":668,"line":669},[1866],{"type":51,"tag":666,"props":1867,"children":1868},{},[1869],{"type":57,"value":1870},"\u002F\u002F Required even if you don't use them\n",{"type":51,"tag":666,"props":1872,"children":1873},{"class":668,"line":678},[1874],{"type":51,"tag":666,"props":1875,"children":1876},{},[1877],{"type":57,"value":1878},"void onProxyDetectComplete() override {}\n",{"type":51,"tag":666,"props":1880,"children":1881},{"class":668,"line":687},[1882],{"type":51,"tag":666,"props":1883,"children":1884},{},[1885],{"type":57,"value":1886},"void onUserWhiteboardShareStatusChanged(IZoomVideoSDKUser*, IZoomVideoSDKWhiteboardHelper*) override {}\n",{"type":51,"tag":666,"props":1888,"children":1889},{"class":668,"line":696},[1890],{"type":51,"tag":666,"props":1891,"children":1892},{},[1893],{"type":57,"value":1894},"\u002F\u002F ... etc\n",{"type":51,"tag":60,"props":1896,"children":1897},{},[1898,1903,1905,1911],{"type":51,"tag":69,"props":1899,"children":1900},{},[1901],{"type":57,"value":1902},"Tip",{"type":57,"value":1904},": Check the SDK version's ",{"type":51,"tag":327,"props":1906,"children":1908},{"className":1907},[],[1909],{"type":57,"value":1910},"zoom_video_sdk_delegate_interface.h",{"type":57,"value":1912}," for the complete list. The interface changes between SDK versions.",{"type":51,"tag":520,"props":1914,"children":1916},{"id":1915},"memory-mode-for-raw-data",[1917],{"type":57,"value":1918},"Memory Mode for Raw Data",{"type":51,"tag":60,"props":1920,"children":1921},{},[1922],{"type":57,"value":1923},"Always use heap mode for raw data memory:",{"type":51,"tag":655,"props":1925,"children":1927},{"className":657,"code":1926,"language":659,"meta":660,"style":660},"init_params.videoRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap;\ninit_params.shareRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap;\ninit_params.audioRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap;\n",[1928],{"type":51,"tag":327,"props":1929,"children":1930},{"__ignoreMap":660},[1931,1938,1945],{"type":51,"tag":666,"props":1932,"children":1933},{"class":668,"line":669},[1934],{"type":51,"tag":666,"props":1935,"children":1936},{},[1937],{"type":57,"value":809},{"type":51,"tag":666,"props":1939,"children":1940},{"class":668,"line":678},[1941],{"type":51,"tag":666,"props":1942,"children":1943},{},[1944],{"type":57,"value":818},{"type":51,"tag":666,"props":1946,"children":1947},{"class":668,"line":687},[1948],{"type":51,"tag":666,"props":1949,"children":1950},{},[1951],{"type":57,"value":827},{"type":51,"tag":60,"props":1953,"children":1954},{},[1955],{"type":57,"value":1956},"Stack mode can cause issues with large video frames.",{"type":51,"tag":520,"props":1958,"children":1960},{"id":1959},"thread-safety",[1961],{"type":57,"value":1962},"Thread Safety",{"type":51,"tag":60,"props":1964,"children":1965},{},[1966],{"type":57,"value":1967},"SDK callbacks execute on SDK threads, not your main thread:",{"type":51,"tag":200,"props":1969,"children":1970},{},[1971,1976,1989,1994],{"type":51,"tag":128,"props":1972,"children":1973},{},[1974],{"type":57,"value":1975},"Don't perform heavy operations in callbacks",{"type":51,"tag":128,"props":1977,"children":1978},{},[1979,1981,1987],{"type":57,"value":1980},"Don't call ",{"type":51,"tag":327,"props":1982,"children":1984},{"className":1983},[],[1985],{"type":57,"value":1986},"cleanup()",{"type":57,"value":1988}," from within callbacks",{"type":51,"tag":128,"props":1990,"children":1991},{},[1992],{"type":57,"value":1993},"Use thread-safe queues for passing data to UI thread",{"type":51,"tag":128,"props":1995,"children":1996},{},[1997],{"type":57,"value":1998},"Use mutexes when accessing shared state",{"type":51,"tag":520,"props":2000,"children":2002},{"id":2001},"consult-official-samples-first",[2003],{"type":57,"value":2004},"Consult Official Samples First",{"type":51,"tag":60,"props":2006,"children":2007},{},[2008,2010,2015],{"type":57,"value":2009},"When SDK behavior is unexpected, ",{"type":51,"tag":69,"props":2011,"children":2012},{},[2013],{"type":57,"value":2014},"always check the official samples",{"type":57,"value":2016}," before troubleshooting:",{"type":51,"tag":60,"props":2018,"children":2019},{},[2020,2025],{"type":51,"tag":69,"props":2021,"children":2022},{},[2023],{"type":57,"value":2024},"Local samples",{"type":57,"value":1669},{"type":51,"tag":200,"props":2027,"children":2028},{},[2029,2040],{"type":51,"tag":128,"props":2030,"children":2031},{},[2032,2038],{"type":51,"tag":327,"props":2033,"children":2035},{"className":2034},[],[2036],{"type":57,"value":2037},"C:\\tempsdk\\Zoom_VideoSDK_Windows_RawDataDemos\\VSDK_SkeletonDemo\\",{"type":57,"value":2039}," (simplest)",{"type":51,"tag":128,"props":2041,"children":2042},{},[2043],{"type":51,"tag":327,"props":2044,"children":2046},{"className":2045},[],[2047],{"type":57,"value":2048},"C:\\tempsdk\\sdksamples\\zoom-video-sdk-windows-2.4.12\\Sample-Libs\\x64\\demo\\",{"type":51,"tag":60,"props":2050,"children":2051},{},[2052],{"type":57,"value":2053},"Official samples show correct patterns for:",{"type":51,"tag":200,"props":2055,"children":2056},{},[2057,2062,2067,2072],{"type":51,"tag":128,"props":2058,"children":2059},{},[2060],{"type":57,"value":2061},"Message pump implementation ✓",{"type":51,"tag":128,"props":2063,"children":2064},{},[2065],{"type":57,"value":2066},"Audio connection strategy ✓",{"type":51,"tag":128,"props":2068,"children":2069},{},[2070],{"type":57,"value":2071},"Error handling ✓",{"type":51,"tag":128,"props":2073,"children":2074},{},[2075],{"type":57,"value":2076},"Memory management ✓",{"type":51,"tag":109,"props":2078,"children":2080},{"id":2079},"video-rendering-two-approaches",[2081],{"type":57,"value":2082},"Video Rendering - Two Approaches",{"type":51,"tag":60,"props":2084,"children":2085},{},[2086,2088,2093],{"type":57,"value":2087},"The Zoom SDK provides ",{"type":51,"tag":69,"props":2089,"children":2090},{},[2091],{"type":57,"value":2092},"two different ways",{"type":57,"value":2094}," to render video. Choose based on your needs.",{"type":51,"tag":520,"props":2096,"children":2098},{"id":2097},"canvas-api-recommended-for-most-use-cases",[2099],{"type":57,"value":2100},"🎯 Canvas API (Recommended for Most Use Cases)",{"type":51,"tag":60,"props":2102,"children":2103},{},[2104,2109],{"type":51,"tag":69,"props":2105,"children":2106},{},[2107],{"type":57,"value":2108},"Best for",{"type":57,"value":2110},": Standard applications, clean video quality, ease of implementation",{"type":51,"tag":60,"props":2112,"children":2113},{},[2114,2116,2121],{"type":57,"value":2115},"The SDK renders video directly to your HWND. ",{"type":51,"tag":69,"props":2117,"children":2118},{},[2119],{"type":57,"value":2120},"No YUV conversion needed",{"type":57,"value":2122},".",{"type":51,"tag":655,"props":2124,"children":2126},{"className":657,"code":2125,"language":659,"meta":660,"style":660},"\u002F\u002F Subscribe to a user's video with Canvas API\nIZoomVideoSDKCanvas* canvas = user->GetVideoCanvas();\nif (canvas) {\n    ZoomVideoSDKErrors ret = canvas->subscribeWithView(\n        hwnd,                                    \u002F\u002F Your window handle\n        ZoomVideoSDKVideoAspect_PanAndScan,     \u002F\u002F Fit to window, may crop\n        ZoomVideoSDKResolution_Auto              \u002F\u002F Let SDK choose best resolution\n    );\n    \n    if (ret == ZoomVideoSDKErrors_Success) {\n        \u002F\u002F SDK is now rendering directly to your window!\n    }\n}\n\n\u002F\u002F Unsubscribe when done\ncanvas->unSubscribeWithView(hwnd);\n",[2127],{"type":51,"tag":327,"props":2128,"children":2129},{"__ignoreMap":660},[2130,2138,2146,2154,2162,2170,2178,2186,2194,2201,2209,2217,2224,2231,2238,2246],{"type":51,"tag":666,"props":2131,"children":2132},{"class":668,"line":669},[2133],{"type":51,"tag":666,"props":2134,"children":2135},{},[2136],{"type":57,"value":2137},"\u002F\u002F Subscribe to a user's video with Canvas API\n",{"type":51,"tag":666,"props":2139,"children":2140},{"class":668,"line":678},[2141],{"type":51,"tag":666,"props":2142,"children":2143},{},[2144],{"type":57,"value":2145},"IZoomVideoSDKCanvas* canvas = user->GetVideoCanvas();\n",{"type":51,"tag":666,"props":2147,"children":2148},{"class":668,"line":687},[2149],{"type":51,"tag":666,"props":2150,"children":2151},{},[2152],{"type":57,"value":2153},"if (canvas) {\n",{"type":51,"tag":666,"props":2155,"children":2156},{"class":668,"line":696},[2157],{"type":51,"tag":666,"props":2158,"children":2159},{},[2160],{"type":57,"value":2161},"    ZoomVideoSDKErrors ret = canvas->subscribeWithView(\n",{"type":51,"tag":666,"props":2163,"children":2164},{"class":668,"line":705},[2165],{"type":51,"tag":666,"props":2166,"children":2167},{},[2168],{"type":57,"value":2169},"        hwnd,                                    \u002F\u002F Your window handle\n",{"type":51,"tag":666,"props":2171,"children":2172},{"class":668,"line":715},[2173],{"type":51,"tag":666,"props":2174,"children":2175},{},[2176],{"type":57,"value":2177},"        ZoomVideoSDKVideoAspect_PanAndScan,     \u002F\u002F Fit to window, may crop\n",{"type":51,"tag":666,"props":2179,"children":2180},{"class":668,"line":724},[2181],{"type":51,"tag":666,"props":2182,"children":2183},{},[2184],{"type":57,"value":2185},"        ZoomVideoSDKResolution_Auto              \u002F\u002F Let SDK choose best resolution\n",{"type":51,"tag":666,"props":2187,"children":2188},{"class":668,"line":732},[2189],{"type":51,"tag":666,"props":2190,"children":2191},{},[2192],{"type":57,"value":2193},"    );\n",{"type":51,"tag":666,"props":2195,"children":2196},{"class":668,"line":741},[2197],{"type":51,"tag":666,"props":2198,"children":2199},{},[2200],{"type":57,"value":1065},{"type":51,"tag":666,"props":2202,"children":2203},{"class":668,"line":750},[2204],{"type":51,"tag":666,"props":2205,"children":2206},{},[2207],{"type":57,"value":2208},"    if (ret == ZoomVideoSDKErrors_Success) {\n",{"type":51,"tag":666,"props":2210,"children":2211},{"class":668,"line":758},[2212],{"type":51,"tag":666,"props":2213,"children":2214},{},[2215],{"type":57,"value":2216},"        \u002F\u002F SDK is now rendering directly to your window!\n",{"type":51,"tag":666,"props":2218,"children":2219},{"class":668,"line":767},[2220],{"type":51,"tag":666,"props":2221,"children":2222},{},[2223],{"type":57,"value":1056},{"type":51,"tag":666,"props":2225,"children":2226},{"class":668,"line":776},[2227],{"type":51,"tag":666,"props":2228,"children":2229},{},[2230],{"type":57,"value":1092},{"type":51,"tag":666,"props":2232,"children":2233},{"class":668,"line":785},[2234],{"type":51,"tag":666,"props":2235,"children":2236},{"emptyLinePlaceholder":709},[2237],{"type":57,"value":712},{"type":51,"tag":666,"props":2239,"children":2240},{"class":668,"line":794},[2241],{"type":51,"tag":666,"props":2242,"children":2243},{},[2244],{"type":57,"value":2245},"\u002F\u002F Unsubscribe when done\n",{"type":51,"tag":666,"props":2247,"children":2248},{"class":668,"line":803},[2249],{"type":51,"tag":666,"props":2250,"children":2251},{},[2252],{"type":57,"value":2253},"canvas->unSubscribeWithView(hwnd);\n",{"type":51,"tag":60,"props":2255,"children":2256},{},[2257,2262],{"type":51,"tag":69,"props":2258,"children":2259},{},[2260],{"type":57,"value":2261},"Advantages",{"type":57,"value":1669},{"type":51,"tag":200,"props":2264,"children":2265},{},[2266,2278,2289,2300,2311,2322],{"type":51,"tag":128,"props":2267,"children":2268},{},[2269,2271,2276],{"type":57,"value":2270},"✅ ",{"type":51,"tag":69,"props":2272,"children":2273},{},[2274],{"type":57,"value":2275},"Best quality",{"type":57,"value":2277}," - SDK uses optimized, hardware-accelerated rendering",{"type":51,"tag":128,"props":2279,"children":2280},{},[2281,2282,2287],{"type":57,"value":2270},{"type":51,"tag":69,"props":2283,"children":2284},{},[2285],{"type":57,"value":2286},"No artifacts",{"type":57,"value":2288}," - Professional video quality",{"type":51,"tag":128,"props":2290,"children":2291},{},[2292,2293,2298],{"type":57,"value":2270},{"type":51,"tag":69,"props":2294,"children":2295},{},[2296],{"type":57,"value":2297},"Simple code",{"type":57,"value":2299}," - 3 lines to subscribe",{"type":51,"tag":128,"props":2301,"children":2302},{},[2303,2304,2309],{"type":57,"value":2270},{"type":51,"tag":69,"props":2305,"children":2306},{},[2307],{"type":57,"value":2308},"Better performance",{"type":57,"value":2310}," - No CPU-intensive YUV conversion",{"type":51,"tag":128,"props":2312,"children":2313},{},[2314,2315,2320],{"type":57,"value":2270},{"type":51,"tag":69,"props":2316,"children":2317},{},[2318],{"type":57,"value":2319},"Automatic scaling",{"type":57,"value":2321}," - SDK handles window resizing",{"type":51,"tag":128,"props":2323,"children":2324},{},[2325,2326,2331],{"type":57,"value":2270},{"type":51,"tag":69,"props":2327,"children":2328},{},[2329],{"type":57,"value":2330},"Aspect ratio",{"type":57,"value":2332}," - Built-in aspect ratio handling",{"type":51,"tag":60,"props":2334,"children":2335},{},[2336,2341],{"type":51,"tag":69,"props":2337,"children":2338},{},[2339],{"type":57,"value":2340},"Example from official .NET sample",{"type":57,"value":1669},{"type":51,"tag":655,"props":2343,"children":2345},{"className":657,"code":2344,"language":659,"meta":660,"style":660},"\u002F\u002F Self video preview\nIZoomVideoSDKCanvas* canvas = myself->GetVideoCanvas();\ncanvas->subscribeWithView(selfVideoHwnd, aspect, resolution);\n\n\u002F\u002F Remote user video\nIZoomVideoSDKCanvas* remoteCanvas = remoteUser->GetVideoCanvas();\nremoteCanvas->subscribeWithView(remoteVideoHwnd, aspect, resolution);\n",[2346],{"type":51,"tag":327,"props":2347,"children":2348},{"__ignoreMap":660},[2349,2357,2365,2373,2380,2388,2396],{"type":51,"tag":666,"props":2350,"children":2351},{"class":668,"line":669},[2352],{"type":51,"tag":666,"props":2353,"children":2354},{},[2355],{"type":57,"value":2356},"\u002F\u002F Self video preview\n",{"type":51,"tag":666,"props":2358,"children":2359},{"class":668,"line":678},[2360],{"type":51,"tag":666,"props":2361,"children":2362},{},[2363],{"type":57,"value":2364},"IZoomVideoSDKCanvas* canvas = myself->GetVideoCanvas();\n",{"type":51,"tag":666,"props":2366,"children":2367},{"class":668,"line":687},[2368],{"type":51,"tag":666,"props":2369,"children":2370},{},[2371],{"type":57,"value":2372},"canvas->subscribeWithView(selfVideoHwnd, aspect, resolution);\n",{"type":51,"tag":666,"props":2374,"children":2375},{"class":668,"line":696},[2376],{"type":51,"tag":666,"props":2377,"children":2378},{"emptyLinePlaceholder":709},[2379],{"type":57,"value":712},{"type":51,"tag":666,"props":2381,"children":2382},{"class":668,"line":705},[2383],{"type":51,"tag":666,"props":2384,"children":2385},{},[2386],{"type":57,"value":2387},"\u002F\u002F Remote user video\n",{"type":51,"tag":666,"props":2389,"children":2390},{"class":668,"line":715},[2391],{"type":51,"tag":666,"props":2392,"children":2393},{},[2394],{"type":57,"value":2395},"IZoomVideoSDKCanvas* remoteCanvas = remoteUser->GetVideoCanvas();\n",{"type":51,"tag":666,"props":2397,"children":2398},{"class":668,"line":724},[2399],{"type":51,"tag":666,"props":2400,"children":2401},{},[2402],{"type":57,"value":2403},"remoteCanvas->subscribeWithView(remoteVideoHwnd, aspect, resolution);\n",{"type":51,"tag":60,"props":2405,"children":2406},{},[2407,2412],{"type":51,"tag":69,"props":2408,"children":2409},{},[2410],{"type":57,"value":2411},"Video Aspect Options",{"type":57,"value":1669},{"type":51,"tag":200,"props":2414,"children":2415},{},[2416,2427,2438,2449],{"type":51,"tag":128,"props":2417,"children":2418},{},[2419,2425],{"type":51,"tag":327,"props":2420,"children":2422},{"className":2421},[],[2423],{"type":57,"value":2424},"ZoomVideoSDKVideoAspect_Original",{"type":57,"value":2426}," - Letterbox\u002Fpillarbox, no cropping",{"type":51,"tag":128,"props":2428,"children":2429},{},[2430,2436],{"type":51,"tag":327,"props":2431,"children":2433},{"className":2432},[],[2434],{"type":57,"value":2435},"ZoomVideoSDKVideoAspect_FullFilled",{"type":57,"value":2437}," - Fill window, may crop edges",{"type":51,"tag":128,"props":2439,"children":2440},{},[2441,2447],{"type":51,"tag":327,"props":2442,"children":2444},{"className":2443},[],[2445],{"type":57,"value":2446},"ZoomVideoSDKVideoAspect_PanAndScan",{"type":57,"value":2448}," - Smart crop to fill window",{"type":51,"tag":128,"props":2450,"children":2451},{},[2452,2458],{"type":51,"tag":327,"props":2453,"children":2455},{"className":2454},[],[2456],{"type":57,"value":2457},"ZoomVideoSDKVideoAspect_LetterBox",{"type":57,"value":2459}," - Show full video with black bars",{"type":51,"tag":60,"props":2461,"children":2462},{},[2463,2468],{"type":51,"tag":69,"props":2464,"children":2465},{},[2466],{"type":57,"value":2467},"Resolution Options",{"type":57,"value":1669},{"type":51,"tag":200,"props":2470,"children":2471},{},[2472,2481,2490,2501,2512,2521],{"type":51,"tag":128,"props":2473,"children":2474},{},[2475],{"type":51,"tag":327,"props":2476,"children":2478},{"className":2477},[],[2479],{"type":57,"value":2480},"ZoomVideoSDKResolution_90P",{"type":51,"tag":128,"props":2482,"children":2483},{},[2484],{"type":51,"tag":327,"props":2485,"children":2487},{"className":2486},[],[2488],{"type":57,"value":2489},"ZoomVideoSDKResolution_180P",{"type":51,"tag":128,"props":2491,"children":2492},{},[2493,2499],{"type":51,"tag":327,"props":2494,"children":2496},{"className":2495},[],[2497],{"type":57,"value":2498},"ZoomVideoSDKResolution_360P",{"type":57,"value":2500}," - Good balance",{"type":51,"tag":128,"props":2502,"children":2503},{},[2504,2510],{"type":51,"tag":327,"props":2505,"children":2507},{"className":2506},[],[2508],{"type":57,"value":2509},"ZoomVideoSDKResolution_720P",{"type":57,"value":2511}," - HD quality",{"type":51,"tag":128,"props":2513,"children":2514},{},[2515],{"type":51,"tag":327,"props":2516,"children":2518},{"className":2517},[],[2519],{"type":57,"value":2520},"ZoomVideoSDKResolution_1080P",{"type":51,"tag":128,"props":2522,"children":2523},{},[2524,2530],{"type":51,"tag":327,"props":2525,"children":2527},{"className":2526},[],[2528],{"type":57,"value":2529},"ZoomVideoSDKResolution_Auto",{"type":57,"value":2531}," - Let SDK decide (recommended)",{"type":51,"tag":520,"props":2533,"children":2535},{"id":2534},"raw-data-pipe-advanced-use-cases",[2536],{"type":57,"value":2537},"🔧 Raw Data Pipe (Advanced Use Cases)",{"type":51,"tag":60,"props":2539,"children":2540},{},[2541,2545],{"type":51,"tag":69,"props":2542,"children":2543},{},[2544],{"type":57,"value":2108},{"type":57,"value":2546},": Custom video processing, effects, recording, computer vision",{"type":51,"tag":60,"props":2548,"children":2549},{},[2550],{"type":57,"value":2551},"You receive raw YUV420 frames and handle rendering yourself.",{"type":51,"tag":655,"props":2553,"children":2555},{"className":657,"code":2554,"language":659,"meta":660,"style":660},"\u002F\u002F 1. Create a delegate to receive frames\nclass VideoRenderer : public IZoomVideoSDKRawDataPipeDelegate {\npublic:\n    void onRawDataFrameReceived(YUVRawDataI420* data) override {\n        int width = data->GetStreamWidth();\n        int height = data->GetStreamHeight();\n        \n        char* yBuffer = data->GetYBuffer();\n        char* uBuffer = data->GetUBuffer();\n        char* vBuffer = data->GetVBuffer();\n        \n        \u002F\u002F Convert YUV420 to RGB and render\n        ConvertYUVToRGB(yBuffer, uBuffer, vBuffer, width, height);\n        RenderToWindow(rgbBuffer, width, height);\n    }\n    \n    void onRawDataStatusChanged(RawDataStatus status) override {\n        \u002F\u002F Handle video on\u002Foff\n    }\n};\n\n\u002F\u002F 2. Subscribe to raw data\nIZoomVideoSDKRawDataPipe* pipe = user->GetVideoPipe();\nVideoRenderer* renderer = new VideoRenderer();\npipe->subscribe(ZoomVideoSDKResolution_720P, renderer);\n",[2556],{"type":51,"tag":327,"props":2557,"children":2558},{"__ignoreMap":660},[2559,2567,2575,2583,2591,2599,2607,2615,2623,2631,2639,2646,2654,2662,2670,2677,2684,2692,2700,2707,2715,2722,2730,2738,2746],{"type":51,"tag":666,"props":2560,"children":2561},{"class":668,"line":669},[2562],{"type":51,"tag":666,"props":2563,"children":2564},{},[2565],{"type":57,"value":2566},"\u002F\u002F 1. Create a delegate to receive frames\n",{"type":51,"tag":666,"props":2568,"children":2569},{"class":668,"line":678},[2570],{"type":51,"tag":666,"props":2571,"children":2572},{},[2573],{"type":57,"value":2574},"class VideoRenderer : public IZoomVideoSDKRawDataPipeDelegate {\n",{"type":51,"tag":666,"props":2576,"children":2577},{"class":668,"line":687},[2578],{"type":51,"tag":666,"props":2579,"children":2580},{},[2581],{"type":57,"value":2582},"public:\n",{"type":51,"tag":666,"props":2584,"children":2585},{"class":668,"line":696},[2586],{"type":51,"tag":666,"props":2587,"children":2588},{},[2589],{"type":57,"value":2590},"    void onRawDataFrameReceived(YUVRawDataI420* data) override {\n",{"type":51,"tag":666,"props":2592,"children":2593},{"class":668,"line":705},[2594],{"type":51,"tag":666,"props":2595,"children":2596},{},[2597],{"type":57,"value":2598},"        int width = data->GetStreamWidth();\n",{"type":51,"tag":666,"props":2600,"children":2601},{"class":668,"line":715},[2602],{"type":51,"tag":666,"props":2603,"children":2604},{},[2605],{"type":57,"value":2606},"        int height = data->GetStreamHeight();\n",{"type":51,"tag":666,"props":2608,"children":2609},{"class":668,"line":724},[2610],{"type":51,"tag":666,"props":2611,"children":2612},{},[2613],{"type":57,"value":2614},"        \n",{"type":51,"tag":666,"props":2616,"children":2617},{"class":668,"line":732},[2618],{"type":51,"tag":666,"props":2619,"children":2620},{},[2621],{"type":57,"value":2622},"        char* yBuffer = data->GetYBuffer();\n",{"type":51,"tag":666,"props":2624,"children":2625},{"class":668,"line":741},[2626],{"type":51,"tag":666,"props":2627,"children":2628},{},[2629],{"type":57,"value":2630},"        char* uBuffer = data->GetUBuffer();\n",{"type":51,"tag":666,"props":2632,"children":2633},{"class":668,"line":750},[2634],{"type":51,"tag":666,"props":2635,"children":2636},{},[2637],{"type":57,"value":2638},"        char* vBuffer = data->GetVBuffer();\n",{"type":51,"tag":666,"props":2640,"children":2641},{"class":668,"line":758},[2642],{"type":51,"tag":666,"props":2643,"children":2644},{},[2645],{"type":57,"value":2614},{"type":51,"tag":666,"props":2647,"children":2648},{"class":668,"line":767},[2649],{"type":51,"tag":666,"props":2650,"children":2651},{},[2652],{"type":57,"value":2653},"        \u002F\u002F Convert YUV420 to RGB and render\n",{"type":51,"tag":666,"props":2655,"children":2656},{"class":668,"line":776},[2657],{"type":51,"tag":666,"props":2658,"children":2659},{},[2660],{"type":57,"value":2661},"        ConvertYUVToRGB(yBuffer, uBuffer, vBuffer, width, height);\n",{"type":51,"tag":666,"props":2663,"children":2664},{"class":668,"line":785},[2665],{"type":51,"tag":666,"props":2666,"children":2667},{},[2668],{"type":57,"value":2669},"        RenderToWindow(rgbBuffer, width, height);\n",{"type":51,"tag":666,"props":2671,"children":2672},{"class":668,"line":794},[2673],{"type":51,"tag":666,"props":2674,"children":2675},{},[2676],{"type":57,"value":1056},{"type":51,"tag":666,"props":2678,"children":2679},{"class":668,"line":803},[2680],{"type":51,"tag":666,"props":2681,"children":2682},{},[2683],{"type":57,"value":1065},{"type":51,"tag":666,"props":2685,"children":2686},{"class":668,"line":812},[2687],{"type":51,"tag":666,"props":2688,"children":2689},{},[2690],{"type":57,"value":2691},"    void onRawDataStatusChanged(RawDataStatus status) override {\n",{"type":51,"tag":666,"props":2693,"children":2694},{"class":668,"line":821},[2695],{"type":51,"tag":666,"props":2696,"children":2697},{},[2698],{"type":57,"value":2699},"        \u002F\u002F Handle video on\u002Foff\n",{"type":51,"tag":666,"props":2701,"children":2702},{"class":668,"line":830},[2703],{"type":51,"tag":666,"props":2704,"children":2705},{},[2706],{"type":57,"value":1056},{"type":51,"tag":666,"props":2708,"children":2709},{"class":668,"line":838},[2710],{"type":51,"tag":666,"props":2711,"children":2712},{},[2713],{"type":57,"value":2714},"};\n",{"type":51,"tag":666,"props":2716,"children":2717},{"class":668,"line":847},[2718],{"type":51,"tag":666,"props":2719,"children":2720},{"emptyLinePlaceholder":709},[2721],{"type":57,"value":712},{"type":51,"tag":666,"props":2723,"children":2724},{"class":668,"line":855},[2725],{"type":51,"tag":666,"props":2726,"children":2727},{},[2728],{"type":57,"value":2729},"\u002F\u002F 2. Subscribe to raw data\n",{"type":51,"tag":666,"props":2731,"children":2732},{"class":668,"line":864},[2733],{"type":51,"tag":666,"props":2734,"children":2735},{},[2736],{"type":57,"value":2737},"IZoomVideoSDKRawDataPipe* pipe = user->GetVideoPipe();\n",{"type":51,"tag":666,"props":2739,"children":2740},{"class":668,"line":873},[2741],{"type":51,"tag":666,"props":2742,"children":2743},{},[2744],{"type":57,"value":2745},"VideoRenderer* renderer = new VideoRenderer();\n",{"type":51,"tag":666,"props":2747,"children":2748},{"class":668,"line":881},[2749],{"type":51,"tag":666,"props":2750,"children":2751},{},[2752],{"type":57,"value":2753},"pipe->subscribe(ZoomVideoSDKResolution_720P, renderer);\n",{"type":51,"tag":60,"props":2755,"children":2756},{},[2757,2762],{"type":51,"tag":69,"props":2758,"children":2759},{},[2760],{"type":57,"value":2761},"YUV420 to RGB Conversion",{"type":57,"value":2763}," (ITU-R BT.601):",{"type":51,"tag":655,"props":2765,"children":2767},{"className":657,"code":2766,"language":659,"meta":660,"style":660},"void ConvertYUV420ToRGB(char* yBuffer, char* uBuffer, char* vBuffer, \n                        int width, int height) {\n    for (int y = 0; y \u003C height; y++) {\n        for (int x = 0; x \u003C width; x++) {\n            int yIndex = y * width + x;\n            int uvIndex = (y \u002F 2) * (width \u002F 2) + (x \u002F 2);\n            \n            int Y = (unsigned char)yBuffer[yIndex];\n            int U = (unsigned char)uBuffer[uvIndex];\n            int V = (unsigned char)vBuffer[uvIndex];\n            \n            \u002F\u002F YUV to RGB conversion\n            int C = Y - 16;\n            int D = U - 128;\n            int E = V - 128;\n            \n            int R = (298 * C + 409 * E + 128) >> 8;\n            int G = (298 * C - 100 * D - 208 * E + 128) >> 8;\n            int B = (298 * C + 516 * D + 128) >> 8;\n            \n            \u002F\u002F Clamp to [0, 255]\n            R = (R \u003C 0) ? 0 : (R > 255) ? 255 : R;\n            G = (G \u003C 0) ? 0 : (G > 255) ? 255 : G;\n            B = (B \u003C 0) ? 0 : (B > 255) ? 255 : B;\n            \n            \u002F\u002F Store RGB (BGR format for Windows)\n            rgbBuffer[yIndex * 3 + 0] = (unsigned char)B;\n            rgbBuffer[yIndex * 3 + 1] = (unsigned char)G;\n            rgbBuffer[yIndex * 3 + 2] = (unsigned char)R;\n        }\n    }\n}\n",[2768],{"type":51,"tag":327,"props":2769,"children":2770},{"__ignoreMap":660},[2771,2779,2787,2795,2803,2811,2819,2827,2835,2843,2851,2858,2866,2874,2882,2890,2897,2905,2913,2921,2928,2936,2944,2952,2960,2967,2975,2983,2991,2999,3007,3014],{"type":51,"tag":666,"props":2772,"children":2773},{"class":668,"line":669},[2774],{"type":51,"tag":666,"props":2775,"children":2776},{},[2777],{"type":57,"value":2778},"void ConvertYUV420ToRGB(char* yBuffer, char* uBuffer, char* vBuffer, \n",{"type":51,"tag":666,"props":2780,"children":2781},{"class":668,"line":678},[2782],{"type":51,"tag":666,"props":2783,"children":2784},{},[2785],{"type":57,"value":2786},"                        int width, int height) {\n",{"type":51,"tag":666,"props":2788,"children":2789},{"class":668,"line":687},[2790],{"type":51,"tag":666,"props":2791,"children":2792},{},[2793],{"type":57,"value":2794},"    for (int y = 0; y \u003C height; y++) {\n",{"type":51,"tag":666,"props":2796,"children":2797},{"class":668,"line":696},[2798],{"type":51,"tag":666,"props":2799,"children":2800},{},[2801],{"type":57,"value":2802},"        for (int x = 0; x \u003C width; x++) {\n",{"type":51,"tag":666,"props":2804,"children":2805},{"class":668,"line":705},[2806],{"type":51,"tag":666,"props":2807,"children":2808},{},[2809],{"type":57,"value":2810},"            int yIndex = y * width + x;\n",{"type":51,"tag":666,"props":2812,"children":2813},{"class":668,"line":715},[2814],{"type":51,"tag":666,"props":2815,"children":2816},{},[2817],{"type":57,"value":2818},"            int uvIndex = (y \u002F 2) * (width \u002F 2) + (x \u002F 2);\n",{"type":51,"tag":666,"props":2820,"children":2821},{"class":668,"line":724},[2822],{"type":51,"tag":666,"props":2823,"children":2824},{},[2825],{"type":57,"value":2826},"            \n",{"type":51,"tag":666,"props":2828,"children":2829},{"class":668,"line":732},[2830],{"type":51,"tag":666,"props":2831,"children":2832},{},[2833],{"type":57,"value":2834},"            int Y = (unsigned char)yBuffer[yIndex];\n",{"type":51,"tag":666,"props":2836,"children":2837},{"class":668,"line":741},[2838],{"type":51,"tag":666,"props":2839,"children":2840},{},[2841],{"type":57,"value":2842},"            int U = (unsigned char)uBuffer[uvIndex];\n",{"type":51,"tag":666,"props":2844,"children":2845},{"class":668,"line":750},[2846],{"type":51,"tag":666,"props":2847,"children":2848},{},[2849],{"type":57,"value":2850},"            int V = (unsigned char)vBuffer[uvIndex];\n",{"type":51,"tag":666,"props":2852,"children":2853},{"class":668,"line":758},[2854],{"type":51,"tag":666,"props":2855,"children":2856},{},[2857],{"type":57,"value":2826},{"type":51,"tag":666,"props":2859,"children":2860},{"class":668,"line":767},[2861],{"type":51,"tag":666,"props":2862,"children":2863},{},[2864],{"type":57,"value":2865},"            \u002F\u002F YUV to RGB conversion\n",{"type":51,"tag":666,"props":2867,"children":2868},{"class":668,"line":776},[2869],{"type":51,"tag":666,"props":2870,"children":2871},{},[2872],{"type":57,"value":2873},"            int C = Y - 16;\n",{"type":51,"tag":666,"props":2875,"children":2876},{"class":668,"line":785},[2877],{"type":51,"tag":666,"props":2878,"children":2879},{},[2880],{"type":57,"value":2881},"            int D = U - 128;\n",{"type":51,"tag":666,"props":2883,"children":2884},{"class":668,"line":794},[2885],{"type":51,"tag":666,"props":2886,"children":2887},{},[2888],{"type":57,"value":2889},"            int E = V - 128;\n",{"type":51,"tag":666,"props":2891,"children":2892},{"class":668,"line":803},[2893],{"type":51,"tag":666,"props":2894,"children":2895},{},[2896],{"type":57,"value":2826},{"type":51,"tag":666,"props":2898,"children":2899},{"class":668,"line":812},[2900],{"type":51,"tag":666,"props":2901,"children":2902},{},[2903],{"type":57,"value":2904},"            int R = (298 * C + 409 * E + 128) >> 8;\n",{"type":51,"tag":666,"props":2906,"children":2907},{"class":668,"line":821},[2908],{"type":51,"tag":666,"props":2909,"children":2910},{},[2911],{"type":57,"value":2912},"            int G = (298 * C - 100 * D - 208 * E + 128) >> 8;\n",{"type":51,"tag":666,"props":2914,"children":2915},{"class":668,"line":830},[2916],{"type":51,"tag":666,"props":2917,"children":2918},{},[2919],{"type":57,"value":2920},"            int B = (298 * C + 516 * D + 128) >> 8;\n",{"type":51,"tag":666,"props":2922,"children":2923},{"class":668,"line":838},[2924],{"type":51,"tag":666,"props":2925,"children":2926},{},[2927],{"type":57,"value":2826},{"type":51,"tag":666,"props":2929,"children":2930},{"class":668,"line":847},[2931],{"type":51,"tag":666,"props":2932,"children":2933},{},[2934],{"type":57,"value":2935},"            \u002F\u002F Clamp to [0, 255]\n",{"type":51,"tag":666,"props":2937,"children":2938},{"class":668,"line":855},[2939],{"type":51,"tag":666,"props":2940,"children":2941},{},[2942],{"type":57,"value":2943},"            R = (R \u003C 0) ? 0 : (R > 255) ? 255 : R;\n",{"type":51,"tag":666,"props":2945,"children":2946},{"class":668,"line":864},[2947],{"type":51,"tag":666,"props":2948,"children":2949},{},[2950],{"type":57,"value":2951},"            G = (G \u003C 0) ? 0 : (G > 255) ? 255 : G;\n",{"type":51,"tag":666,"props":2953,"children":2954},{"class":668,"line":873},[2955],{"type":51,"tag":666,"props":2956,"children":2957},{},[2958],{"type":57,"value":2959},"            B = (B \u003C 0) ? 0 : (B > 255) ? 255 : B;\n",{"type":51,"tag":666,"props":2961,"children":2962},{"class":668,"line":881},[2963],{"type":51,"tag":666,"props":2964,"children":2965},{},[2966],{"type":57,"value":2826},{"type":51,"tag":666,"props":2968,"children":2969},{"class":668,"line":890},[2970],{"type":51,"tag":666,"props":2971,"children":2972},{},[2973],{"type":57,"value":2974},"            \u002F\u002F Store RGB (BGR format for Windows)\n",{"type":51,"tag":666,"props":2976,"children":2977},{"class":668,"line":899},[2978],{"type":51,"tag":666,"props":2979,"children":2980},{},[2981],{"type":57,"value":2982},"            rgbBuffer[yIndex * 3 + 0] = (unsigned char)B;\n",{"type":51,"tag":666,"props":2984,"children":2985},{"class":668,"line":908},[2986],{"type":51,"tag":666,"props":2987,"children":2988},{},[2989],{"type":57,"value":2990},"            rgbBuffer[yIndex * 3 + 1] = (unsigned char)G;\n",{"type":51,"tag":666,"props":2992,"children":2993},{"class":668,"line":917},[2994],{"type":51,"tag":666,"props":2995,"children":2996},{},[2997],{"type":57,"value":2998},"            rgbBuffer[yIndex * 3 + 2] = (unsigned char)R;\n",{"type":51,"tag":666,"props":3000,"children":3001},{"class":668,"line":926},[3002],{"type":51,"tag":666,"props":3003,"children":3004},{},[3005],{"type":57,"value":3006},"        }\n",{"type":51,"tag":666,"props":3008,"children":3009},{"class":668,"line":935},[3010],{"type":51,"tag":666,"props":3011,"children":3012},{},[3013],{"type":57,"value":1056},{"type":51,"tag":666,"props":3015,"children":3016},{"class":668,"line":944},[3017],{"type":51,"tag":666,"props":3018,"children":3019},{},[3020],{"type":57,"value":1092},{"type":51,"tag":60,"props":3022,"children":3023},{},[3024,3029],{"type":51,"tag":69,"props":3025,"children":3026},{},[3027],{"type":57,"value":3028},"Render with GDI",{"type":57,"value":1669},{"type":51,"tag":655,"props":3031,"children":3033},{"className":657,"code":3032,"language":659,"meta":660,"style":660},"void RenderToWindow(unsigned char* rgbBuffer, int width, int height) {\n    HDC hdc = GetDC(hwnd);\n    \n    BITMAPINFO bmi = {};\n    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);\n    bmi.bmiHeader.biWidth = width;\n    bmi.bmiHeader.biHeight = -height;  \u002F\u002F Negative for top-down\n    bmi.bmiHeader.biPlanes = 1;\n    bmi.bmiHeader.biBitCount = 24;     \u002F\u002F 24-bit RGB\n    bmi.bmiHeader.biCompression = BI_RGB;\n    \n    RECT rect;\n    GetClientRect(hwnd, &rect);\n    \n    StretchDIBits(hdc,\n        0, 0, rect.right, rect.bottom,  \u002F\u002F Destination\n        0, 0, width, height,              \u002F\u002F Source\n        rgbBuffer, &bmi,\n        DIB_RGB_COLORS, SRCCOPY);\n    \n    ReleaseDC(hwnd, hdc);\n}\n",[3034],{"type":51,"tag":327,"props":3035,"children":3036},{"__ignoreMap":660},[3037,3045,3053,3060,3068,3076,3084,3092,3100,3108,3116,3123,3131,3139,3146,3154,3162,3170,3178,3186,3193,3201],{"type":51,"tag":666,"props":3038,"children":3039},{"class":668,"line":669},[3040],{"type":51,"tag":666,"props":3041,"children":3042},{},[3043],{"type":57,"value":3044},"void RenderToWindow(unsigned char* rgbBuffer, int width, int height) {\n",{"type":51,"tag":666,"props":3046,"children":3047},{"class":668,"line":678},[3048],{"type":51,"tag":666,"props":3049,"children":3050},{},[3051],{"type":57,"value":3052},"    HDC hdc = GetDC(hwnd);\n",{"type":51,"tag":666,"props":3054,"children":3055},{"class":668,"line":687},[3056],{"type":51,"tag":666,"props":3057,"children":3058},{},[3059],{"type":57,"value":1065},{"type":51,"tag":666,"props":3061,"children":3062},{"class":668,"line":696},[3063],{"type":51,"tag":666,"props":3064,"children":3065},{},[3066],{"type":57,"value":3067},"    BITMAPINFO bmi = {};\n",{"type":51,"tag":666,"props":3069,"children":3070},{"class":668,"line":705},[3071],{"type":51,"tag":666,"props":3072,"children":3073},{},[3074],{"type":57,"value":3075},"    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);\n",{"type":51,"tag":666,"props":3077,"children":3078},{"class":668,"line":715},[3079],{"type":51,"tag":666,"props":3080,"children":3081},{},[3082],{"type":57,"value":3083},"    bmi.bmiHeader.biWidth = width;\n",{"type":51,"tag":666,"props":3085,"children":3086},{"class":668,"line":724},[3087],{"type":51,"tag":666,"props":3088,"children":3089},{},[3090],{"type":57,"value":3091},"    bmi.bmiHeader.biHeight = -height;  \u002F\u002F Negative for top-down\n",{"type":51,"tag":666,"props":3093,"children":3094},{"class":668,"line":732},[3095],{"type":51,"tag":666,"props":3096,"children":3097},{},[3098],{"type":57,"value":3099},"    bmi.bmiHeader.biPlanes = 1;\n",{"type":51,"tag":666,"props":3101,"children":3102},{"class":668,"line":741},[3103],{"type":51,"tag":666,"props":3104,"children":3105},{},[3106],{"type":57,"value":3107},"    bmi.bmiHeader.biBitCount = 24;     \u002F\u002F 24-bit RGB\n",{"type":51,"tag":666,"props":3109,"children":3110},{"class":668,"line":750},[3111],{"type":51,"tag":666,"props":3112,"children":3113},{},[3114],{"type":57,"value":3115},"    bmi.bmiHeader.biCompression = BI_RGB;\n",{"type":51,"tag":666,"props":3117,"children":3118},{"class":668,"line":758},[3119],{"type":51,"tag":666,"props":3120,"children":3121},{},[3122],{"type":57,"value":1065},{"type":51,"tag":666,"props":3124,"children":3125},{"class":668,"line":767},[3126],{"type":51,"tag":666,"props":3127,"children":3128},{},[3129],{"type":57,"value":3130},"    RECT rect;\n",{"type":51,"tag":666,"props":3132,"children":3133},{"class":668,"line":776},[3134],{"type":51,"tag":666,"props":3135,"children":3136},{},[3137],{"type":57,"value":3138},"    GetClientRect(hwnd, &rect);\n",{"type":51,"tag":666,"props":3140,"children":3141},{"class":668,"line":785},[3142],{"type":51,"tag":666,"props":3143,"children":3144},{},[3145],{"type":57,"value":1065},{"type":51,"tag":666,"props":3147,"children":3148},{"class":668,"line":794},[3149],{"type":51,"tag":666,"props":3150,"children":3151},{},[3152],{"type":57,"value":3153},"    StretchDIBits(hdc,\n",{"type":51,"tag":666,"props":3155,"children":3156},{"class":668,"line":803},[3157],{"type":51,"tag":666,"props":3158,"children":3159},{},[3160],{"type":57,"value":3161},"        0, 0, rect.right, rect.bottom,  \u002F\u002F Destination\n",{"type":51,"tag":666,"props":3163,"children":3164},{"class":668,"line":812},[3165],{"type":51,"tag":666,"props":3166,"children":3167},{},[3168],{"type":57,"value":3169},"        0, 0, width, height,              \u002F\u002F Source\n",{"type":51,"tag":666,"props":3171,"children":3172},{"class":668,"line":821},[3173],{"type":51,"tag":666,"props":3174,"children":3175},{},[3176],{"type":57,"value":3177},"        rgbBuffer, &bmi,\n",{"type":51,"tag":666,"props":3179,"children":3180},{"class":668,"line":830},[3181],{"type":51,"tag":666,"props":3182,"children":3183},{},[3184],{"type":57,"value":3185},"        DIB_RGB_COLORS, SRCCOPY);\n",{"type":51,"tag":666,"props":3187,"children":3188},{"class":668,"line":838},[3189],{"type":51,"tag":666,"props":3190,"children":3191},{},[3192],{"type":57,"value":1065},{"type":51,"tag":666,"props":3194,"children":3195},{"class":668,"line":847},[3196],{"type":51,"tag":666,"props":3197,"children":3198},{},[3199],{"type":57,"value":3200},"    ReleaseDC(hwnd, hdc);\n",{"type":51,"tag":666,"props":3202,"children":3203},{"class":668,"line":855},[3204],{"type":51,"tag":666,"props":3205,"children":3206},{},[3207],{"type":57,"value":1092},{"type":51,"tag":60,"props":3209,"children":3210},{},[3211,3216],{"type":51,"tag":69,"props":3212,"children":3213},{},[3214],{"type":57,"value":3215},"Disadvantages",{"type":57,"value":1669},{"type":51,"tag":200,"props":3218,"children":3219},{},[3220,3232,3243,3254],{"type":51,"tag":128,"props":3221,"children":3222},{},[3223,3225,3230],{"type":57,"value":3224},"⚠️ ",{"type":51,"tag":69,"props":3226,"children":3227},{},[3228],{"type":57,"value":3229},"CPU intensive",{"type":57,"value":3231}," - YUV conversion can cause frame drops",{"type":51,"tag":128,"props":3233,"children":3234},{},[3235,3236,3241],{"type":57,"value":3224},{"type":51,"tag":69,"props":3237,"children":3238},{},[3239],{"type":57,"value":3240},"Artifacts",{"type":57,"value":3242}," - Manual rendering may show tearing\u002Fartifacts",{"type":51,"tag":128,"props":3244,"children":3245},{},[3246,3247,3252],{"type":57,"value":3224},{"type":51,"tag":69,"props":3248,"children":3249},{},[3250],{"type":57,"value":3251},"Complex",{"type":57,"value":3253}," - More code to maintain",{"type":51,"tag":128,"props":3255,"children":3256},{},[3257,3258,3263],{"type":57,"value":3224},{"type":51,"tag":69,"props":3259,"children":3260},{},[3261],{"type":57,"value":3262},"Performance",{"type":57,"value":3264}," - Slower than Canvas API",{"type":51,"tag":60,"props":3266,"children":3267},{},[3268,3273],{"type":51,"tag":69,"props":3269,"children":3270},{},[3271],{"type":57,"value":3272},"Use Raw Data When",{"type":57,"value":1669},{"type":51,"tag":200,"props":3275,"children":3276},{},[3277,3282,3287,3292,3297],{"type":51,"tag":128,"props":3278,"children":3279},{},[3280],{"type":57,"value":3281},"Adding video filters\u002Feffects",{"type":51,"tag":128,"props":3283,"children":3284},{},[3285],{"type":57,"value":3286},"Recording to custom formats",{"type":51,"tag":128,"props":3288,"children":3289},{},[3290],{"type":57,"value":3291},"Computer vision processing",{"type":51,"tag":128,"props":3293,"children":3294},{},[3295],{"type":57,"value":3296},"Custom compositing",{"type":51,"tag":128,"props":3298,"children":3299},{},[3300],{"type":57,"value":3301},"Streaming to non-standard outputs",{"type":51,"tag":520,"props":3303,"children":3305},{"id":3304},"self-video-vs-remote-users",[3306],{"type":57,"value":3307},"Self Video vs Remote Users",{"type":51,"tag":60,"props":3309,"children":3310},{},[3311,3316],{"type":51,"tag":69,"props":3312,"children":3313},{},[3314],{"type":57,"value":3315},"Self Video",{"type":57,"value":3317}," (your own camera):",{"type":51,"tag":60,"props":3319,"children":3320},{},[3321],{"type":51,"tag":69,"props":3322,"children":3323},{},[3324],{"type":57,"value":3325},"Option A: Canvas API",{"type":51,"tag":655,"props":3327,"children":3329},{"className":657,"code":3328,"language":659,"meta":660,"style":660},"IZoomVideoSDKSession* session = sdk->getSessionInfo();\nIZoomVideoSDKUser* myself = session->getMyself();\nIZoomVideoSDKCanvas* canvas = myself->GetVideoCanvas();\ncanvas->subscribeWithView(selfVideoHwnd, aspect, resolution);\n",[3330],{"type":51,"tag":327,"props":3331,"children":3332},{"__ignoreMap":660},[3333,3341,3349,3356],{"type":51,"tag":666,"props":3334,"children":3335},{"class":668,"line":669},[3336],{"type":51,"tag":666,"props":3337,"children":3338},{},[3339],{"type":57,"value":3340},"IZoomVideoSDKSession* session = sdk->getSessionInfo();\n",{"type":51,"tag":666,"props":3342,"children":3343},{"class":668,"line":678},[3344],{"type":51,"tag":666,"props":3345,"children":3346},{},[3347],{"type":57,"value":3348},"IZoomVideoSDKUser* myself = session->getMyself();\n",{"type":51,"tag":666,"props":3350,"children":3351},{"class":668,"line":687},[3352],{"type":51,"tag":666,"props":3353,"children":3354},{},[3355],{"type":57,"value":2364},{"type":51,"tag":666,"props":3357,"children":3358},{"class":668,"line":696},[3359],{"type":51,"tag":666,"props":3360,"children":3361},{},[3362],{"type":57,"value":2372},{"type":51,"tag":60,"props":3364,"children":3365},{},[3366,3371],{"type":51,"tag":69,"props":3367,"children":3368},{},[3369],{"type":57,"value":3370},"Option B: Video Preview",{"type":57,"value":3372}," (for self only)",{"type":51,"tag":655,"props":3374,"children":3376},{"className":657,"code":3375,"language":659,"meta":660,"style":660},"IZoomVideoSDKVideoHelper* videoHelper = sdk->getVideoHelper();\nvideoHelper->startVideo();  \u002F\u002F Start transmission\n\n\u002F\u002F For preview rendering\nvideoHelper->startVideoCanvasPreview(selfVideoHwnd, aspect, resolution);\n",[3377],{"type":51,"tag":327,"props":3378,"children":3379},{"__ignoreMap":660},[3380,3388,3396,3403,3411],{"type":51,"tag":666,"props":3381,"children":3382},{"class":668,"line":669},[3383],{"type":51,"tag":666,"props":3384,"children":3385},{},[3386],{"type":57,"value":3387},"IZoomVideoSDKVideoHelper* videoHelper = sdk->getVideoHelper();\n",{"type":51,"tag":666,"props":3389,"children":3390},{"class":668,"line":678},[3391],{"type":51,"tag":666,"props":3392,"children":3393},{},[3394],{"type":57,"value":3395},"videoHelper->startVideo();  \u002F\u002F Start transmission\n",{"type":51,"tag":666,"props":3397,"children":3398},{"class":668,"line":687},[3399],{"type":51,"tag":666,"props":3400,"children":3401},{"emptyLinePlaceholder":709},[3402],{"type":57,"value":712},{"type":51,"tag":666,"props":3404,"children":3405},{"class":668,"line":696},[3406],{"type":51,"tag":666,"props":3407,"children":3408},{},[3409],{"type":57,"value":3410},"\u002F\u002F For preview rendering\n",{"type":51,"tag":666,"props":3412,"children":3413},{"class":668,"line":705},[3414],{"type":51,"tag":666,"props":3415,"children":3416},{},[3417],{"type":57,"value":3418},"videoHelper->startVideoCanvasPreview(selfVideoHwnd, aspect, resolution);\n",{"type":51,"tag":60,"props":3420,"children":3421},{},[3422,3427],{"type":51,"tag":69,"props":3423,"children":3424},{},[3425],{"type":57,"value":3426},"Remote Users",{"type":57,"value":3428}," (other participants):",{"type":51,"tag":60,"props":3430,"children":3431},{},[3432,3437],{"type":51,"tag":69,"props":3433,"children":3434},{},[3435],{"type":57,"value":3436},"Canvas API",{"type":57,"value":3438}," (recommended):",{"type":51,"tag":655,"props":3440,"children":3442},{"className":657,"code":3441,"language":659,"meta":660,"style":660},"\u002F\u002F In onUserJoin callback\nvoid onUserJoin(IZoomVideoSDKUserHelper*, IVideoSDKVector\u003CIZoomVideoSDKUser*>* userList) {\n    for (int i = 0; i \u003C userList->GetCount(); i++) {\n        IZoomVideoSDKUser* user = userList->GetItem(i);\n        IZoomVideoSDKCanvas* canvas = user->GetVideoCanvas();\n        canvas->subscribeWithView(userVideoHwnd, aspect, resolution);\n    }\n}\n",[3443],{"type":51,"tag":327,"props":3444,"children":3445},{"__ignoreMap":660},[3446,3454,3462,3470,3478,3486,3494,3501],{"type":51,"tag":666,"props":3447,"children":3448},{"class":668,"line":669},[3449],{"type":51,"tag":666,"props":3450,"children":3451},{},[3452],{"type":57,"value":3453},"\u002F\u002F In onUserJoin callback\n",{"type":51,"tag":666,"props":3455,"children":3456},{"class":668,"line":678},[3457],{"type":51,"tag":666,"props":3458,"children":3459},{},[3460],{"type":57,"value":3461},"void onUserJoin(IZoomVideoSDKUserHelper*, IVideoSDKVector\u003CIZoomVideoSDKUser*>* userList) {\n",{"type":51,"tag":666,"props":3463,"children":3464},{"class":668,"line":687},[3465],{"type":51,"tag":666,"props":3466,"children":3467},{},[3468],{"type":57,"value":3469},"    for (int i = 0; i \u003C userList->GetCount(); i++) {\n",{"type":51,"tag":666,"props":3471,"children":3472},{"class":668,"line":696},[3473],{"type":51,"tag":666,"props":3474,"children":3475},{},[3476],{"type":57,"value":3477},"        IZoomVideoSDKUser* user = userList->GetItem(i);\n",{"type":51,"tag":666,"props":3479,"children":3480},{"class":668,"line":705},[3481],{"type":51,"tag":666,"props":3482,"children":3483},{},[3484],{"type":57,"value":3485},"        IZoomVideoSDKCanvas* canvas = user->GetVideoCanvas();\n",{"type":51,"tag":666,"props":3487,"children":3488},{"class":668,"line":715},[3489],{"type":51,"tag":666,"props":3490,"children":3491},{},[3492],{"type":57,"value":3493},"        canvas->subscribeWithView(userVideoHwnd, aspect, resolution);\n",{"type":51,"tag":666,"props":3495,"children":3496},{"class":668,"line":724},[3497],{"type":51,"tag":666,"props":3498,"children":3499},{},[3500],{"type":57,"value":1056},{"type":51,"tag":666,"props":3502,"children":3503},{"class":668,"line":732},[3504],{"type":51,"tag":666,"props":3505,"children":3506},{},[3507],{"type":57,"value":1092},{"type":51,"tag":520,"props":3509,"children":3511},{"id":3510},"event-driven-subscription-pattern",[3512],{"type":57,"value":3513},"Event-Driven Subscription Pattern",{"type":51,"tag":60,"props":3515,"children":3516},{},[3517,3518,3522,3524,3529,3531,3536],{"type":57,"value":3224},{"type":51,"tag":69,"props":3519,"children":3520},{},[3521],{"type":57,"value":174},{"type":57,"value":3523},": Video subscription must be ",{"type":51,"tag":69,"props":3525,"children":3526},{},[3527],{"type":57,"value":3528},"event-driven",{"type":57,"value":3530}," and ",{"type":51,"tag":69,"props":3532,"children":3533},{},[3534],{"type":57,"value":3535},"manual",{"type":57,"value":2122},{"type":51,"tag":60,"props":3538,"children":3539},{},[3540,3545],{"type":51,"tag":69,"props":3541,"children":3542},{},[3543],{"type":57,"value":3544},"Key Events",{"type":57,"value":1669},{"type":51,"tag":124,"props":3547,"children":3548},{},[3549,3563,3577,3590],{"type":51,"tag":128,"props":3550,"children":3551},{},[3552,3561],{"type":51,"tag":69,"props":3553,"children":3554},{},[3555],{"type":51,"tag":327,"props":3556,"children":3558},{"className":3557},[],[3559],{"type":57,"value":3560},"onSessionJoin",{"type":57,"value":3562}," - Subscribe to self video",{"type":51,"tag":128,"props":3564,"children":3565},{},[3566,3575],{"type":51,"tag":69,"props":3567,"children":3568},{},[3569],{"type":51,"tag":327,"props":3570,"children":3572},{"className":3571},[],[3573],{"type":57,"value":3574},"onUserJoin",{"type":57,"value":3576}," - Subscribe to new remote users",{"type":51,"tag":128,"props":3578,"children":3579},{},[3580,3588],{"type":51,"tag":69,"props":3581,"children":3582},{},[3583],{"type":51,"tag":327,"props":3584,"children":3586},{"className":3585},[],[3587],{"type":57,"value":332},{"type":57,"value":3589}," - Re-subscribe when video turns on\u002Foff",{"type":51,"tag":128,"props":3591,"children":3592},{},[3593,3602],{"type":51,"tag":69,"props":3594,"children":3595},{},[3596],{"type":51,"tag":327,"props":3597,"children":3599},{"className":3598},[],[3600],{"type":57,"value":3601},"onUserLeave",{"type":57,"value":3603}," - Unsubscribe and cleanup",{"type":51,"tag":60,"props":3605,"children":3606},{},[3607,3612],{"type":51,"tag":69,"props":3608,"children":3609},{},[3610],{"type":57,"value":3611},"Complete Pattern",{"type":57,"value":1669},{"type":51,"tag":655,"props":3614,"children":3616},{"className":657,"code":3615,"language":659,"meta":660,"style":660},"class MainFrame : public IZoomVideoSDKDelegate {\nprivate:\n    std::map\u003CIZoomVideoSDKUser*, IZoomVideoSDKCanvas*> subscribedUsers_;\n    HWND videoWindow_;\n    \npublic:\n    void onSessionJoin() override {\n        \u002F\u002F Start your own video\n        IZoomVideoSDKVideoHelper* videoHelper = sdk->getVideoHelper();\n        videoHelper->startVideo();\n        \n        \u002F\u002F Subscribe to self video\n        IZoomVideoSDKUser* myself = sdk->getSessionInfo()->getMyself();\n        SubscribeToUser(myself);\n    }\n    \n    void onUserJoin(IZoomVideoSDKUserHelper*, \n                    IVideoSDKVector\u003CIZoomVideoSDKUser*>* userList) override {\n        \u002F\u002F Get current user to exclude self\n        IZoomVideoSDKUser* myself = sdk->getSessionInfo()->getMyself();\n        \n        for (int i = 0; i \u003C userList->GetCount(); i++) {\n            IZoomVideoSDKUser* user = userList->GetItem(i);\n            \n            \u002F\u002F IMPORTANT: Only subscribe to REMOTE users!\n            if (user != myself) {\n                SubscribeToUser(user);\n            }\n        }\n    }\n    \n    void onUserVideoStatusChanged(IZoomVideoSDKVideoHelper*, \n                                  IVideoSDKVector\u003CIZoomVideoSDKUser*>* userList) override {\n        IZoomVideoSDKUser* myself = sdk->getSessionInfo()->getMyself();\n        \n        for (int i = 0; i \u003C userList->GetCount(); i++) {\n            IZoomVideoSDKUser* user = userList->GetItem(i);\n            if (user != myself) {\n                \u002F\u002F Re-subscribe when video status changes\n                SubscribeToUser(user);\n            }\n        }\n    }\n    \n    void onUserLeave(IZoomVideoSDKUserHelper*, \n                    IVideoSDKVector\u003CIZoomVideoSDKUser*>* userList) override {\n        for (int i = 0; i \u003C userList->GetCount(); i++) {\n            IZoomVideoSDKUser* user = userList->GetItem(i);\n            UnsubscribeFromUser(user);\n        }\n    }\n    \n    void onSessionLeave() override {\n        \u002F\u002F Cleanup all subscriptions\n        for (auto& pair : subscribedUsers_) {\n            IZoomVideoSDKCanvas* canvas = pair.second;\n            if (canvas) {\n                canvas->unSubscribeWithView(videoWindow_);\n            }\n        }\n        subscribedUsers_.clear();\n    }\n    \nprivate:\n    void SubscribeToUser(IZoomVideoSDKUser* user) {\n        if (!user || subscribedUsers_.find(user) != subscribedUsers_.end())\n            return;\n            \n        IZoomVideoSDKCanvas* canvas = user->GetVideoCanvas();\n        if (canvas) {\n            ZoomVideoSDKErrors ret = canvas->subscribeWithView(\n                videoWindow_,\n                ZoomVideoSDKVideoAspect_PanAndScan,\n                ZoomVideoSDKResolution_Auto\n            );\n            \n            if (ret == ZoomVideoSDKErrors_Success) {\n                subscribedUsers_[user] = canvas;\n            }\n        }\n    }\n    \n    void UnsubscribeFromUser(IZoomVideoSDKUser* user) {\n        auto it = subscribedUsers_.find(user);\n        if (it != subscribedUsers_.end()) {\n            IZoomVideoSDKCanvas* canvas = it->second;\n            if (canvas) {\n                canvas->unSubscribeWithView(videoWindow_);\n            }\n            subscribedUsers_.erase(it);\n        }\n    }\n};\n",[3617],{"type":51,"tag":327,"props":3618,"children":3619},{"__ignoreMap":660},[3620,3628,3636,3644,3652,3659,3666,3674,3682,3690,3698,3705,3713,3721,3729,3736,3743,3751,3759,3767,3774,3781,3789,3797,3804,3812,3820,3828,3836,3843,3850,3857,3865,3873,3880,3887,3894,3901,3908,3916,3923,3930,3937,3944,3951,3959,3966,3973,3980,3989,3997,4005,4013,4022,4031,4040,4049,4058,4067,4075,4083,4092,4100,4108,4116,4125,4134,4143,4151,4159,4168,4177,4186,4195,4204,4213,4221,4230,4239,4247,4255,4263,4271,4280,4289,4298,4307,4315,4323,4331,4340,4348,4356],{"type":51,"tag":666,"props":3621,"children":3622},{"class":668,"line":669},[3623],{"type":51,"tag":666,"props":3624,"children":3625},{},[3626],{"type":57,"value":3627},"class MainFrame : public IZoomVideoSDKDelegate {\n",{"type":51,"tag":666,"props":3629,"children":3630},{"class":668,"line":678},[3631],{"type":51,"tag":666,"props":3632,"children":3633},{},[3634],{"type":57,"value":3635},"private:\n",{"type":51,"tag":666,"props":3637,"children":3638},{"class":668,"line":687},[3639],{"type":51,"tag":666,"props":3640,"children":3641},{},[3642],{"type":57,"value":3643},"    std::map\u003CIZoomVideoSDKUser*, IZoomVideoSDKCanvas*> subscribedUsers_;\n",{"type":51,"tag":666,"props":3645,"children":3646},{"class":668,"line":696},[3647],{"type":51,"tag":666,"props":3648,"children":3649},{},[3650],{"type":57,"value":3651},"    HWND videoWindow_;\n",{"type":51,"tag":666,"props":3653,"children":3654},{"class":668,"line":705},[3655],{"type":51,"tag":666,"props":3656,"children":3657},{},[3658],{"type":57,"value":1065},{"type":51,"tag":666,"props":3660,"children":3661},{"class":668,"line":715},[3662],{"type":51,"tag":666,"props":3663,"children":3664},{},[3665],{"type":57,"value":2582},{"type":51,"tag":666,"props":3667,"children":3668},{"class":668,"line":724},[3669],{"type":51,"tag":666,"props":3670,"children":3671},{},[3672],{"type":57,"value":3673},"    void onSessionJoin() override {\n",{"type":51,"tag":666,"props":3675,"children":3676},{"class":668,"line":732},[3677],{"type":51,"tag":666,"props":3678,"children":3679},{},[3680],{"type":57,"value":3681},"        \u002F\u002F Start your own video\n",{"type":51,"tag":666,"props":3683,"children":3684},{"class":668,"line":741},[3685],{"type":51,"tag":666,"props":3686,"children":3687},{},[3688],{"type":57,"value":3689},"        IZoomVideoSDKVideoHelper* videoHelper = sdk->getVideoHelper();\n",{"type":51,"tag":666,"props":3691,"children":3692},{"class":668,"line":750},[3693],{"type":51,"tag":666,"props":3694,"children":3695},{},[3696],{"type":57,"value":3697},"        videoHelper->startVideo();\n",{"type":51,"tag":666,"props":3699,"children":3700},{"class":668,"line":758},[3701],{"type":51,"tag":666,"props":3702,"children":3703},{},[3704],{"type":57,"value":2614},{"type":51,"tag":666,"props":3706,"children":3707},{"class":668,"line":767},[3708],{"type":51,"tag":666,"props":3709,"children":3710},{},[3711],{"type":57,"value":3712},"        \u002F\u002F Subscribe to self video\n",{"type":51,"tag":666,"props":3714,"children":3715},{"class":668,"line":776},[3716],{"type":51,"tag":666,"props":3717,"children":3718},{},[3719],{"type":57,"value":3720},"        IZoomVideoSDKUser* myself = sdk->getSessionInfo()->getMyself();\n",{"type":51,"tag":666,"props":3722,"children":3723},{"class":668,"line":785},[3724],{"type":51,"tag":666,"props":3725,"children":3726},{},[3727],{"type":57,"value":3728},"        SubscribeToUser(myself);\n",{"type":51,"tag":666,"props":3730,"children":3731},{"class":668,"line":794},[3732],{"type":51,"tag":666,"props":3733,"children":3734},{},[3735],{"type":57,"value":1056},{"type":51,"tag":666,"props":3737,"children":3738},{"class":668,"line":803},[3739],{"type":51,"tag":666,"props":3740,"children":3741},{},[3742],{"type":57,"value":1065},{"type":51,"tag":666,"props":3744,"children":3745},{"class":668,"line":812},[3746],{"type":51,"tag":666,"props":3747,"children":3748},{},[3749],{"type":57,"value":3750},"    void onUserJoin(IZoomVideoSDKUserHelper*, \n",{"type":51,"tag":666,"props":3752,"children":3753},{"class":668,"line":821},[3754],{"type":51,"tag":666,"props":3755,"children":3756},{},[3757],{"type":57,"value":3758},"                    IVideoSDKVector\u003CIZoomVideoSDKUser*>* userList) override {\n",{"type":51,"tag":666,"props":3760,"children":3761},{"class":668,"line":830},[3762],{"type":51,"tag":666,"props":3763,"children":3764},{},[3765],{"type":57,"value":3766},"        \u002F\u002F Get current user to exclude self\n",{"type":51,"tag":666,"props":3768,"children":3769},{"class":668,"line":838},[3770],{"type":51,"tag":666,"props":3771,"children":3772},{},[3773],{"type":57,"value":3720},{"type":51,"tag":666,"props":3775,"children":3776},{"class":668,"line":847},[3777],{"type":51,"tag":666,"props":3778,"children":3779},{},[3780],{"type":57,"value":2614},{"type":51,"tag":666,"props":3782,"children":3783},{"class":668,"line":855},[3784],{"type":51,"tag":666,"props":3785,"children":3786},{},[3787],{"type":57,"value":3788},"        for (int i = 0; i \u003C userList->GetCount(); i++) {\n",{"type":51,"tag":666,"props":3790,"children":3791},{"class":668,"line":864},[3792],{"type":51,"tag":666,"props":3793,"children":3794},{},[3795],{"type":57,"value":3796},"            IZoomVideoSDKUser* user = userList->GetItem(i);\n",{"type":51,"tag":666,"props":3798,"children":3799},{"class":668,"line":873},[3800],{"type":51,"tag":666,"props":3801,"children":3802},{},[3803],{"type":57,"value":2826},{"type":51,"tag":666,"props":3805,"children":3806},{"class":668,"line":881},[3807],{"type":51,"tag":666,"props":3808,"children":3809},{},[3810],{"type":57,"value":3811},"            \u002F\u002F IMPORTANT: Only subscribe to REMOTE users!\n",{"type":51,"tag":666,"props":3813,"children":3814},{"class":668,"line":890},[3815],{"type":51,"tag":666,"props":3816,"children":3817},{},[3818],{"type":57,"value":3819},"            if (user != myself) {\n",{"type":51,"tag":666,"props":3821,"children":3822},{"class":668,"line":899},[3823],{"type":51,"tag":666,"props":3824,"children":3825},{},[3826],{"type":57,"value":3827},"                SubscribeToUser(user);\n",{"type":51,"tag":666,"props":3829,"children":3830},{"class":668,"line":908},[3831],{"type":51,"tag":666,"props":3832,"children":3833},{},[3834],{"type":57,"value":3835},"            }\n",{"type":51,"tag":666,"props":3837,"children":3838},{"class":668,"line":917},[3839],{"type":51,"tag":666,"props":3840,"children":3841},{},[3842],{"type":57,"value":3006},{"type":51,"tag":666,"props":3844,"children":3845},{"class":668,"line":926},[3846],{"type":51,"tag":666,"props":3847,"children":3848},{},[3849],{"type":57,"value":1056},{"type":51,"tag":666,"props":3851,"children":3852},{"class":668,"line":935},[3853],{"type":51,"tag":666,"props":3854,"children":3855},{},[3856],{"type":57,"value":1065},{"type":51,"tag":666,"props":3858,"children":3859},{"class":668,"line":944},[3860],{"type":51,"tag":666,"props":3861,"children":3862},{},[3863],{"type":57,"value":3864},"    void onUserVideoStatusChanged(IZoomVideoSDKVideoHelper*, \n",{"type":51,"tag":666,"props":3866,"children":3867},{"class":668,"line":953},[3868],{"type":51,"tag":666,"props":3869,"children":3870},{},[3871],{"type":57,"value":3872},"                                  IVideoSDKVector\u003CIZoomVideoSDKUser*>* userList) override {\n",{"type":51,"tag":666,"props":3874,"children":3875},{"class":668,"line":961},[3876],{"type":51,"tag":666,"props":3877,"children":3878},{},[3879],{"type":57,"value":3720},{"type":51,"tag":666,"props":3881,"children":3882},{"class":668,"line":970},[3883],{"type":51,"tag":666,"props":3884,"children":3885},{},[3886],{"type":57,"value":2614},{"type":51,"tag":666,"props":3888,"children":3889},{"class":668,"line":978},[3890],{"type":51,"tag":666,"props":3891,"children":3892},{},[3893],{"type":57,"value":3788},{"type":51,"tag":666,"props":3895,"children":3896},{"class":668,"line":987},[3897],{"type":51,"tag":666,"props":3898,"children":3899},{},[3900],{"type":57,"value":3796},{"type":51,"tag":666,"props":3902,"children":3903},{"class":668,"line":996},[3904],{"type":51,"tag":666,"props":3905,"children":3906},{},[3907],{"type":57,"value":3819},{"type":51,"tag":666,"props":3909,"children":3910},{"class":668,"line":1005},[3911],{"type":51,"tag":666,"props":3912,"children":3913},{},[3914],{"type":57,"value":3915},"                \u002F\u002F Re-subscribe when video status changes\n",{"type":51,"tag":666,"props":3917,"children":3918},{"class":668,"line":1014},[3919],{"type":51,"tag":666,"props":3920,"children":3921},{},[3922],{"type":57,"value":3827},{"type":51,"tag":666,"props":3924,"children":3925},{"class":668,"line":1023},[3926],{"type":51,"tag":666,"props":3927,"children":3928},{},[3929],{"type":57,"value":3835},{"type":51,"tag":666,"props":3931,"children":3932},{"class":668,"line":1032},[3933],{"type":51,"tag":666,"props":3934,"children":3935},{},[3936],{"type":57,"value":3006},{"type":51,"tag":666,"props":3938,"children":3939},{"class":668,"line":1041},[3940],{"type":51,"tag":666,"props":3941,"children":3942},{},[3943],{"type":57,"value":1056},{"type":51,"tag":666,"props":3945,"children":3946},{"class":668,"line":1050},[3947],{"type":51,"tag":666,"props":3948,"children":3949},{},[3950],{"type":57,"value":1065},{"type":51,"tag":666,"props":3952,"children":3953},{"class":668,"line":1059},[3954],{"type":51,"tag":666,"props":3955,"children":3956},{},[3957],{"type":57,"value":3958},"    void onUserLeave(IZoomVideoSDKUserHelper*, \n",{"type":51,"tag":666,"props":3960,"children":3961},{"class":668,"line":1068},[3962],{"type":51,"tag":666,"props":3963,"children":3964},{},[3965],{"type":57,"value":3758},{"type":51,"tag":666,"props":3967,"children":3968},{"class":668,"line":1077},[3969],{"type":51,"tag":666,"props":3970,"children":3971},{},[3972],{"type":57,"value":3788},{"type":51,"tag":666,"props":3974,"children":3975},{"class":668,"line":1086},[3976],{"type":51,"tag":666,"props":3977,"children":3978},{},[3979],{"type":57,"value":3796},{"type":51,"tag":666,"props":3981,"children":3983},{"class":668,"line":3982},49,[3984],{"type":51,"tag":666,"props":3985,"children":3986},{},[3987],{"type":57,"value":3988},"            UnsubscribeFromUser(user);\n",{"type":51,"tag":666,"props":3990,"children":3992},{"class":668,"line":3991},50,[3993],{"type":51,"tag":666,"props":3994,"children":3995},{},[3996],{"type":57,"value":3006},{"type":51,"tag":666,"props":3998,"children":4000},{"class":668,"line":3999},51,[4001],{"type":51,"tag":666,"props":4002,"children":4003},{},[4004],{"type":57,"value":1056},{"type":51,"tag":666,"props":4006,"children":4008},{"class":668,"line":4007},52,[4009],{"type":51,"tag":666,"props":4010,"children":4011},{},[4012],{"type":57,"value":1065},{"type":51,"tag":666,"props":4014,"children":4016},{"class":668,"line":4015},53,[4017],{"type":51,"tag":666,"props":4018,"children":4019},{},[4020],{"type":57,"value":4021},"    void onSessionLeave() override {\n",{"type":51,"tag":666,"props":4023,"children":4025},{"class":668,"line":4024},54,[4026],{"type":51,"tag":666,"props":4027,"children":4028},{},[4029],{"type":57,"value":4030},"        \u002F\u002F Cleanup all subscriptions\n",{"type":51,"tag":666,"props":4032,"children":4034},{"class":668,"line":4033},55,[4035],{"type":51,"tag":666,"props":4036,"children":4037},{},[4038],{"type":57,"value":4039},"        for (auto& pair : subscribedUsers_) {\n",{"type":51,"tag":666,"props":4041,"children":4043},{"class":668,"line":4042},56,[4044],{"type":51,"tag":666,"props":4045,"children":4046},{},[4047],{"type":57,"value":4048},"            IZoomVideoSDKCanvas* canvas = pair.second;\n",{"type":51,"tag":666,"props":4050,"children":4052},{"class":668,"line":4051},57,[4053],{"type":51,"tag":666,"props":4054,"children":4055},{},[4056],{"type":57,"value":4057},"            if (canvas) {\n",{"type":51,"tag":666,"props":4059,"children":4061},{"class":668,"line":4060},58,[4062],{"type":51,"tag":666,"props":4063,"children":4064},{},[4065],{"type":57,"value":4066},"                canvas->unSubscribeWithView(videoWindow_);\n",{"type":51,"tag":666,"props":4068,"children":4070},{"class":668,"line":4069},59,[4071],{"type":51,"tag":666,"props":4072,"children":4073},{},[4074],{"type":57,"value":3835},{"type":51,"tag":666,"props":4076,"children":4078},{"class":668,"line":4077},60,[4079],{"type":51,"tag":666,"props":4080,"children":4081},{},[4082],{"type":57,"value":3006},{"type":51,"tag":666,"props":4084,"children":4086},{"class":668,"line":4085},61,[4087],{"type":51,"tag":666,"props":4088,"children":4089},{},[4090],{"type":57,"value":4091},"        subscribedUsers_.clear();\n",{"type":51,"tag":666,"props":4093,"children":4095},{"class":668,"line":4094},62,[4096],{"type":51,"tag":666,"props":4097,"children":4098},{},[4099],{"type":57,"value":1056},{"type":51,"tag":666,"props":4101,"children":4103},{"class":668,"line":4102},63,[4104],{"type":51,"tag":666,"props":4105,"children":4106},{},[4107],{"type":57,"value":1065},{"type":51,"tag":666,"props":4109,"children":4111},{"class":668,"line":4110},64,[4112],{"type":51,"tag":666,"props":4113,"children":4114},{},[4115],{"type":57,"value":3635},{"type":51,"tag":666,"props":4117,"children":4119},{"class":668,"line":4118},65,[4120],{"type":51,"tag":666,"props":4121,"children":4122},{},[4123],{"type":57,"value":4124},"    void SubscribeToUser(IZoomVideoSDKUser* user) {\n",{"type":51,"tag":666,"props":4126,"children":4128},{"class":668,"line":4127},66,[4129],{"type":51,"tag":666,"props":4130,"children":4131},{},[4132],{"type":57,"value":4133},"        if (!user || subscribedUsers_.find(user) != subscribedUsers_.end())\n",{"type":51,"tag":666,"props":4135,"children":4137},{"class":668,"line":4136},67,[4138],{"type":51,"tag":666,"props":4139,"children":4140},{},[4141],{"type":57,"value":4142},"            return;\n",{"type":51,"tag":666,"props":4144,"children":4146},{"class":668,"line":4145},68,[4147],{"type":51,"tag":666,"props":4148,"children":4149},{},[4150],{"type":57,"value":2826},{"type":51,"tag":666,"props":4152,"children":4154},{"class":668,"line":4153},69,[4155],{"type":51,"tag":666,"props":4156,"children":4157},{},[4158],{"type":57,"value":3485},{"type":51,"tag":666,"props":4160,"children":4162},{"class":668,"line":4161},70,[4163],{"type":51,"tag":666,"props":4164,"children":4165},{},[4166],{"type":57,"value":4167},"        if (canvas) {\n",{"type":51,"tag":666,"props":4169,"children":4171},{"class":668,"line":4170},71,[4172],{"type":51,"tag":666,"props":4173,"children":4174},{},[4175],{"type":57,"value":4176},"            ZoomVideoSDKErrors ret = canvas->subscribeWithView(\n",{"type":51,"tag":666,"props":4178,"children":4180},{"class":668,"line":4179},72,[4181],{"type":51,"tag":666,"props":4182,"children":4183},{},[4184],{"type":57,"value":4185},"                videoWindow_,\n",{"type":51,"tag":666,"props":4187,"children":4189},{"class":668,"line":4188},73,[4190],{"type":51,"tag":666,"props":4191,"children":4192},{},[4193],{"type":57,"value":4194},"                ZoomVideoSDKVideoAspect_PanAndScan,\n",{"type":51,"tag":666,"props":4196,"children":4198},{"class":668,"line":4197},74,[4199],{"type":51,"tag":666,"props":4200,"children":4201},{},[4202],{"type":57,"value":4203},"                ZoomVideoSDKResolution_Auto\n",{"type":51,"tag":666,"props":4205,"children":4207},{"class":668,"line":4206},75,[4208],{"type":51,"tag":666,"props":4209,"children":4210},{},[4211],{"type":57,"value":4212},"            );\n",{"type":51,"tag":666,"props":4214,"children":4216},{"class":668,"line":4215},76,[4217],{"type":51,"tag":666,"props":4218,"children":4219},{},[4220],{"type":57,"value":2826},{"type":51,"tag":666,"props":4222,"children":4224},{"class":668,"line":4223},77,[4225],{"type":51,"tag":666,"props":4226,"children":4227},{},[4228],{"type":57,"value":4229},"            if (ret == ZoomVideoSDKErrors_Success) {\n",{"type":51,"tag":666,"props":4231,"children":4233},{"class":668,"line":4232},78,[4234],{"type":51,"tag":666,"props":4235,"children":4236},{},[4237],{"type":57,"value":4238},"                subscribedUsers_[user] = canvas;\n",{"type":51,"tag":666,"props":4240,"children":4242},{"class":668,"line":4241},79,[4243],{"type":51,"tag":666,"props":4244,"children":4245},{},[4246],{"type":57,"value":3835},{"type":51,"tag":666,"props":4248,"children":4250},{"class":668,"line":4249},80,[4251],{"type":51,"tag":666,"props":4252,"children":4253},{},[4254],{"type":57,"value":3006},{"type":51,"tag":666,"props":4256,"children":4258},{"class":668,"line":4257},81,[4259],{"type":51,"tag":666,"props":4260,"children":4261},{},[4262],{"type":57,"value":1056},{"type":51,"tag":666,"props":4264,"children":4266},{"class":668,"line":4265},82,[4267],{"type":51,"tag":666,"props":4268,"children":4269},{},[4270],{"type":57,"value":1065},{"type":51,"tag":666,"props":4272,"children":4274},{"class":668,"line":4273},83,[4275],{"type":51,"tag":666,"props":4276,"children":4277},{},[4278],{"type":57,"value":4279},"    void UnsubscribeFromUser(IZoomVideoSDKUser* user) {\n",{"type":51,"tag":666,"props":4281,"children":4283},{"class":668,"line":4282},84,[4284],{"type":51,"tag":666,"props":4285,"children":4286},{},[4287],{"type":57,"value":4288},"        auto it = subscribedUsers_.find(user);\n",{"type":51,"tag":666,"props":4290,"children":4292},{"class":668,"line":4291},85,[4293],{"type":51,"tag":666,"props":4294,"children":4295},{},[4296],{"type":57,"value":4297},"        if (it != subscribedUsers_.end()) {\n",{"type":51,"tag":666,"props":4299,"children":4301},{"class":668,"line":4300},86,[4302],{"type":51,"tag":666,"props":4303,"children":4304},{},[4305],{"type":57,"value":4306},"            IZoomVideoSDKCanvas* canvas = it->second;\n",{"type":51,"tag":666,"props":4308,"children":4310},{"class":668,"line":4309},87,[4311],{"type":51,"tag":666,"props":4312,"children":4313},{},[4314],{"type":57,"value":4057},{"type":51,"tag":666,"props":4316,"children":4318},{"class":668,"line":4317},88,[4319],{"type":51,"tag":666,"props":4320,"children":4321},{},[4322],{"type":57,"value":4066},{"type":51,"tag":666,"props":4324,"children":4326},{"class":668,"line":4325},89,[4327],{"type":51,"tag":666,"props":4328,"children":4329},{},[4330],{"type":57,"value":3835},{"type":51,"tag":666,"props":4332,"children":4334},{"class":668,"line":4333},90,[4335],{"type":51,"tag":666,"props":4336,"children":4337},{},[4338],{"type":57,"value":4339},"            subscribedUsers_.erase(it);\n",{"type":51,"tag":666,"props":4341,"children":4343},{"class":668,"line":4342},91,[4344],{"type":51,"tag":666,"props":4345,"children":4346},{},[4347],{"type":57,"value":3006},{"type":51,"tag":666,"props":4349,"children":4351},{"class":668,"line":4350},92,[4352],{"type":51,"tag":666,"props":4353,"children":4354},{},[4355],{"type":57,"value":1056},{"type":51,"tag":666,"props":4357,"children":4359},{"class":668,"line":4358},93,[4360],{"type":51,"tag":666,"props":4361,"children":4362},{},[4363],{"type":57,"value":2714},{"type":51,"tag":60,"props":4365,"children":4366},{},[4367,4372],{"type":51,"tag":69,"props":4368,"children":4369},{},[4370],{"type":57,"value":4371},"Key Points",{"type":57,"value":1669},{"type":51,"tag":200,"props":4374,"children":4375},{},[4376,4381,4386,4391,4396],{"type":51,"tag":128,"props":4377,"children":4378},{},[4379],{"type":57,"value":4380},"✅ Subscribe in response to events (onUserJoin, onUserVideoStatusChanged)",{"type":51,"tag":128,"props":4382,"children":4383},{},[4384],{"type":57,"value":4385},"✅ Always exclude current user from remote subscriptions",{"type":51,"tag":128,"props":4387,"children":4388},{},[4389],{"type":57,"value":4390},"✅ Unsubscribe on onUserLeave",{"type":51,"tag":128,"props":4392,"children":4393},{},[4394],{"type":57,"value":4395},"✅ Clean up all subscriptions on onSessionLeave",{"type":51,"tag":128,"props":4397,"children":4398},{},[4399],{"type":57,"value":4400},"✅ Track subscriptions in a map for lifecycle management",{"type":51,"tag":520,"props":4402,"children":4404},{"id":4403},"️-screen-share-subscription-different-from-video",[4405],{"type":57,"value":4406},"⚠️ Screen Share Subscription (DIFFERENT from Video!)",{"type":51,"tag":60,"props":4408,"children":4409},{},[4410,4414,4416,4422,4424,4430],{"type":51,"tag":69,"props":4411,"children":4412},{},[4413],{"type":57,"value":174},{"type":57,"value":4415},": Screen share subscription uses ",{"type":51,"tag":327,"props":4417,"children":4419},{"className":4418},[],[4420],{"type":57,"value":4421},"IZoomVideoSDKShareAction",{"type":57,"value":4423}," from the callback, NOT ",{"type":51,"tag":327,"props":4425,"children":4427},{"className":4426},[],[4428],{"type":57,"value":4429},"user->GetShareCanvas()",{"type":57,"value":4431},"!",{"type":51,"tag":655,"props":4433,"children":4435},{"className":657,"code":4434,"language":659,"meta":660,"style":660},"\u002F\u002F WRONG - This won't work for remote screen shares!\nuser->GetShareCanvas()->subscribeWithView(hwnd, ...);\n\n\u002F\u002F CORRECT - Use IZoomVideoSDKShareAction from onUserShareStatusChanged callback\nvoid onUserShareStatusChanged(IZoomVideoSDKShareHelper* pShareHelper,\n                               IZoomVideoSDKUser* pUser,\n                               IZoomVideoSDKShareAction* pShareAction) {\n    if (!pShareAction) return;\n    \n    ZoomVideoSDKShareStatus status = pShareAction->getShareStatus();\n    \n    if (status == ZoomVideoSDKShareStatus_Start || \n        status == ZoomVideoSDKShareStatus_Resume) {\n        \u002F\u002F Subscribe to the share using Canvas API\n        IZoomVideoSDKCanvas* shareCanvas = pShareAction->getShareCanvas();\n        if (shareCanvas) {\n            shareCanvas->subscribeWithView(shareWindow_, \n                ZoomVideoSDKVideoAspect_Original);\n        }\n    }\n    else if (status == ZoomVideoSDKShareStatus_Stop) {\n        \u002F\u002F Unsubscribe when share stops\n        IZoomVideoSDKCanvas* shareCanvas = pShareAction->getShareCanvas();\n        if (shareCanvas) {\n            shareCanvas->unSubscribeWithView(shareWindow_);\n        }\n    }\n}\n",[4436],{"type":51,"tag":327,"props":4437,"children":4438},{"__ignoreMap":660},[4439,4447,4455,4462,4470,4478,4486,4494,4502,4509,4517,4524,4532,4540,4548,4556,4564,4572,4580,4587,4594,4602,4610,4617,4624,4632,4639,4646],{"type":51,"tag":666,"props":4440,"children":4441},{"class":668,"line":669},[4442],{"type":51,"tag":666,"props":4443,"children":4444},{},[4445],{"type":57,"value":4446},"\u002F\u002F WRONG - This won't work for remote screen shares!\n",{"type":51,"tag":666,"props":4448,"children":4449},{"class":668,"line":678},[4450],{"type":51,"tag":666,"props":4451,"children":4452},{},[4453],{"type":57,"value":4454},"user->GetShareCanvas()->subscribeWithView(hwnd, ...);\n",{"type":51,"tag":666,"props":4456,"children":4457},{"class":668,"line":687},[4458],{"type":51,"tag":666,"props":4459,"children":4460},{"emptyLinePlaceholder":709},[4461],{"type":57,"value":712},{"type":51,"tag":666,"props":4463,"children":4464},{"class":668,"line":696},[4465],{"type":51,"tag":666,"props":4466,"children":4467},{},[4468],{"type":57,"value":4469},"\u002F\u002F CORRECT - Use IZoomVideoSDKShareAction from onUserShareStatusChanged callback\n",{"type":51,"tag":666,"props":4471,"children":4472},{"class":668,"line":705},[4473],{"type":51,"tag":666,"props":4474,"children":4475},{},[4476],{"type":57,"value":4477},"void onUserShareStatusChanged(IZoomVideoSDKShareHelper* pShareHelper,\n",{"type":51,"tag":666,"props":4479,"children":4480},{"class":668,"line":715},[4481],{"type":51,"tag":666,"props":4482,"children":4483},{},[4484],{"type":57,"value":4485},"                               IZoomVideoSDKUser* pUser,\n",{"type":51,"tag":666,"props":4487,"children":4488},{"class":668,"line":724},[4489],{"type":51,"tag":666,"props":4490,"children":4491},{},[4492],{"type":57,"value":4493},"                               IZoomVideoSDKShareAction* pShareAction) {\n",{"type":51,"tag":666,"props":4495,"children":4496},{"class":668,"line":732},[4497],{"type":51,"tag":666,"props":4498,"children":4499},{},[4500],{"type":57,"value":4501},"    if (!pShareAction) return;\n",{"type":51,"tag":666,"props":4503,"children":4504},{"class":668,"line":741},[4505],{"type":51,"tag":666,"props":4506,"children":4507},{},[4508],{"type":57,"value":1065},{"type":51,"tag":666,"props":4510,"children":4511},{"class":668,"line":750},[4512],{"type":51,"tag":666,"props":4513,"children":4514},{},[4515],{"type":57,"value":4516},"    ZoomVideoSDKShareStatus status = pShareAction->getShareStatus();\n",{"type":51,"tag":666,"props":4518,"children":4519},{"class":668,"line":758},[4520],{"type":51,"tag":666,"props":4521,"children":4522},{},[4523],{"type":57,"value":1065},{"type":51,"tag":666,"props":4525,"children":4526},{"class":668,"line":767},[4527],{"type":51,"tag":666,"props":4528,"children":4529},{},[4530],{"type":57,"value":4531},"    if (status == ZoomVideoSDKShareStatus_Start || \n",{"type":51,"tag":666,"props":4533,"children":4534},{"class":668,"line":776},[4535],{"type":51,"tag":666,"props":4536,"children":4537},{},[4538],{"type":57,"value":4539},"        status == ZoomVideoSDKShareStatus_Resume) {\n",{"type":51,"tag":666,"props":4541,"children":4542},{"class":668,"line":785},[4543],{"type":51,"tag":666,"props":4544,"children":4545},{},[4546],{"type":57,"value":4547},"        \u002F\u002F Subscribe to the share using Canvas API\n",{"type":51,"tag":666,"props":4549,"children":4550},{"class":668,"line":794},[4551],{"type":51,"tag":666,"props":4552,"children":4553},{},[4554],{"type":57,"value":4555},"        IZoomVideoSDKCanvas* shareCanvas = pShareAction->getShareCanvas();\n",{"type":51,"tag":666,"props":4557,"children":4558},{"class":668,"line":803},[4559],{"type":51,"tag":666,"props":4560,"children":4561},{},[4562],{"type":57,"value":4563},"        if (shareCanvas) {\n",{"type":51,"tag":666,"props":4565,"children":4566},{"class":668,"line":812},[4567],{"type":51,"tag":666,"props":4568,"children":4569},{},[4570],{"type":57,"value":4571},"            shareCanvas->subscribeWithView(shareWindow_, \n",{"type":51,"tag":666,"props":4573,"children":4574},{"class":668,"line":821},[4575],{"type":51,"tag":666,"props":4576,"children":4577},{},[4578],{"type":57,"value":4579},"                ZoomVideoSDKVideoAspect_Original);\n",{"type":51,"tag":666,"props":4581,"children":4582},{"class":668,"line":830},[4583],{"type":51,"tag":666,"props":4584,"children":4585},{},[4586],{"type":57,"value":3006},{"type":51,"tag":666,"props":4588,"children":4589},{"class":668,"line":838},[4590],{"type":51,"tag":666,"props":4591,"children":4592},{},[4593],{"type":57,"value":1056},{"type":51,"tag":666,"props":4595,"children":4596},{"class":668,"line":847},[4597],{"type":51,"tag":666,"props":4598,"children":4599},{},[4600],{"type":57,"value":4601},"    else if (status == ZoomVideoSDKShareStatus_Stop) {\n",{"type":51,"tag":666,"props":4603,"children":4604},{"class":668,"line":855},[4605],{"type":51,"tag":666,"props":4606,"children":4607},{},[4608],{"type":57,"value":4609},"        \u002F\u002F Unsubscribe when share stops\n",{"type":51,"tag":666,"props":4611,"children":4612},{"class":668,"line":864},[4613],{"type":51,"tag":666,"props":4614,"children":4615},{},[4616],{"type":57,"value":4555},{"type":51,"tag":666,"props":4618,"children":4619},{"class":668,"line":873},[4620],{"type":51,"tag":666,"props":4621,"children":4622},{},[4623],{"type":57,"value":4563},{"type":51,"tag":666,"props":4625,"children":4626},{"class":668,"line":881},[4627],{"type":51,"tag":666,"props":4628,"children":4629},{},[4630],{"type":57,"value":4631},"            shareCanvas->unSubscribeWithView(shareWindow_);\n",{"type":51,"tag":666,"props":4633,"children":4634},{"class":668,"line":890},[4635],{"type":51,"tag":666,"props":4636,"children":4637},{},[4638],{"type":57,"value":3006},{"type":51,"tag":666,"props":4640,"children":4641},{"class":668,"line":899},[4642],{"type":51,"tag":666,"props":4643,"children":4644},{},[4645],{"type":57,"value":1056},{"type":51,"tag":666,"props":4647,"children":4648},{"class":668,"line":908},[4649],{"type":51,"tag":666,"props":4650,"children":4651},{},[4652],{"type":57,"value":1092},{"type":51,"tag":60,"props":4654,"children":4655},{},[4656],{"type":51,"tag":69,"props":4657,"children":4658},{},[4659],{"type":57,"value":4660},"Why is share different from video?",{"type":51,"tag":200,"props":4662,"children":4663},{},[4664,4680,4698],{"type":51,"tag":128,"props":4665,"children":4666},{},[4667,4672,4674],{"type":51,"tag":69,"props":4668,"children":4669},{},[4670],{"type":57,"value":4671},"Video",{"type":57,"value":4673},": Each user has one video stream → use ",{"type":51,"tag":327,"props":4675,"children":4677},{"className":4676},[],[4678],{"type":57,"value":4679},"user->GetVideoCanvas()",{"type":51,"tag":128,"props":4681,"children":4682},{},[4683,4688,4690,4696],{"type":51,"tag":69,"props":4684,"children":4685},{},[4686],{"type":57,"value":4687},"Share",{"type":57,"value":4689},": A user can have multiple share actions (multi-share) → use ",{"type":51,"tag":327,"props":4691,"children":4693},{"className":4692},[],[4694],{"type":57,"value":4695},"IZoomVideoSDKShareAction*",{"type":57,"value":4697}," from callback",{"type":51,"tag":128,"props":4699,"children":4700},{},[4701,4702,4707],{"type":57,"value":1840},{"type":51,"tag":327,"props":4703,"children":4705},{"className":4704},[],[4706],{"type":57,"value":4421},{"type":57,"value":4708}," object represents a specific share stream and contains the share status, type, and rendering interfaces",{"type":51,"tag":60,"props":4710,"children":4711},{},[4712,4717,4718],{"type":51,"tag":69,"props":4713,"children":4714},{},[4715],{"type":57,"value":4716},"See also",{"type":57,"value":75},{"type":51,"tag":77,"props":4719,"children":4721},{"href":4720},"examples\u002Fscreen-share-subscription.md",[4722],{"type":57,"value":4723},"Screen Share Subscription Example",{"type":51,"tag":520,"props":4725,"children":4727},{"id":4726},"multi-user-video-layout",[4728],{"type":57,"value":4729},"Multi-User Video Layout",{"type":51,"tag":60,"props":4731,"children":4732},{},[4733,4735,4740],{"type":57,"value":4734},"For multiple participants, you need ",{"type":51,"tag":69,"props":4736,"children":4737},{},[4738],{"type":57,"value":4739},"one HWND per user",{"type":57,"value":1669},{"type":51,"tag":655,"props":4742,"children":4744},{"className":657,"code":4743,"language":659,"meta":660,"style":660},"\u002F\u002F Create separate windows\u002Fpanels for each user\nHWND selfVideoWindow = CreateWindow(...);   \u002F\u002F Your video\nHWND user1Window = CreateWindow(...);       \u002F\u002F User 1's video\nHWND user2Window = CreateWindow(...);       \u002F\u002F User 2's video\n\n\u002F\u002F Subscribe each user to their own window\nmyself->GetVideoCanvas()->subscribeWithView(selfVideoWindow, ...);\nuser1->GetVideoCanvas()->subscribeWithView(user1Window, ...);\nuser2->GetVideoCanvas()->subscribeWithView(user2Window, ...);\n",[4745],{"type":51,"tag":327,"props":4746,"children":4747},{"__ignoreMap":660},[4748,4756,4764,4772,4780,4787,4795,4803,4811],{"type":51,"tag":666,"props":4749,"children":4750},{"class":668,"line":669},[4751],{"type":51,"tag":666,"props":4752,"children":4753},{},[4754],{"type":57,"value":4755},"\u002F\u002F Create separate windows\u002Fpanels for each user\n",{"type":51,"tag":666,"props":4757,"children":4758},{"class":668,"line":678},[4759],{"type":51,"tag":666,"props":4760,"children":4761},{},[4762],{"type":57,"value":4763},"HWND selfVideoWindow = CreateWindow(...);   \u002F\u002F Your video\n",{"type":51,"tag":666,"props":4765,"children":4766},{"class":668,"line":687},[4767],{"type":51,"tag":666,"props":4768,"children":4769},{},[4770],{"type":57,"value":4771},"HWND user1Window = CreateWindow(...);       \u002F\u002F User 1's video\n",{"type":51,"tag":666,"props":4773,"children":4774},{"class":668,"line":696},[4775],{"type":51,"tag":666,"props":4776,"children":4777},{},[4778],{"type":57,"value":4779},"HWND user2Window = CreateWindow(...);       \u002F\u002F User 2's video\n",{"type":51,"tag":666,"props":4781,"children":4782},{"class":668,"line":705},[4783],{"type":51,"tag":666,"props":4784,"children":4785},{"emptyLinePlaceholder":709},[4786],{"type":57,"value":712},{"type":51,"tag":666,"props":4788,"children":4789},{"class":668,"line":715},[4790],{"type":51,"tag":666,"props":4791,"children":4792},{},[4793],{"type":57,"value":4794},"\u002F\u002F Subscribe each user to their own window\n",{"type":51,"tag":666,"props":4796,"children":4797},{"class":668,"line":724},[4798],{"type":51,"tag":666,"props":4799,"children":4800},{},[4801],{"type":57,"value":4802},"myself->GetVideoCanvas()->subscribeWithView(selfVideoWindow, ...);\n",{"type":51,"tag":666,"props":4804,"children":4805},{"class":668,"line":732},[4806],{"type":51,"tag":666,"props":4807,"children":4808},{},[4809],{"type":57,"value":4810},"user1->GetVideoCanvas()->subscribeWithView(user1Window, ...);\n",{"type":51,"tag":666,"props":4812,"children":4813},{"class":668,"line":741},[4814],{"type":51,"tag":666,"props":4815,"children":4816},{},[4817],{"type":57,"value":4818},"user2->GetVideoCanvas()->subscribeWithView(user2Window, ...);\n",{"type":51,"tag":60,"props":4820,"children":4821},{},[4822,4827],{"type":51,"tag":69,"props":4823,"children":4824},{},[4825],{"type":57,"value":4826},"Layout Strategies",{"type":57,"value":1669},{"type":51,"tag":200,"props":4829,"children":4830},{},[4831,4836,4841,4846],{"type":51,"tag":128,"props":4832,"children":4833},{},[4834],{"type":57,"value":4835},"Grid layout (2x2, 3x3)",{"type":51,"tag":128,"props":4837,"children":4838},{},[4839],{"type":57,"value":4840},"Gallery view (scrollable)",{"type":51,"tag":128,"props":4842,"children":4843},{},[4844],{"type":57,"value":4845},"Active speaker (large) + thumbnails",{"type":51,"tag":128,"props":4847,"children":4848},{},[4849],{"type":57,"value":4850},"Picture-in-picture",{"type":51,"tag":520,"props":4852,"children":4854},{"id":4853},"common-video-issues",[4855],{"type":57,"value":4856},"Common Video Issues",{"type":51,"tag":1154,"props":4858,"children":4859},{},[4860,4880],{"type":51,"tag":1158,"props":4861,"children":4862},{},[4863],{"type":51,"tag":1162,"props":4864,"children":4865},{},[4866,4871,4876],{"type":51,"tag":1166,"props":4867,"children":4868},{},[4869],{"type":57,"value":4870},"Issue",{"type":51,"tag":1166,"props":4872,"children":4873},{},[4874],{"type":57,"value":4875},"Cause",{"type":51,"tag":1166,"props":4877,"children":4878},{},[4879],{"type":57,"value":1571},{"type":51,"tag":1177,"props":4881,"children":4882},{},[4883,4920,4938,4956,4974,5000],{"type":51,"tag":1162,"props":4884,"children":4885},{},[4886,4891,4902],{"type":51,"tag":1184,"props":4887,"children":4888},{},[4889],{"type":57,"value":4890},"Video not showing",{"type":51,"tag":1184,"props":4892,"children":4893},{},[4894,4896],{"type":57,"value":4895},"Not calling ",{"type":51,"tag":327,"props":4897,"children":4899},{"className":4898},[],[4900],{"type":57,"value":4901},"startVideo()",{"type":51,"tag":1184,"props":4903,"children":4904},{},[4905,4907,4913,4915],{"type":57,"value":4906},"Call ",{"type":51,"tag":327,"props":4908,"children":4910},{"className":4909},[],[4911],{"type":57,"value":4912},"videoHelper->startVideo()",{"type":57,"value":4914}," in ",{"type":51,"tag":327,"props":4916,"children":4918},{"className":4917},[],[4919],{"type":57,"value":3560},{"type":51,"tag":1162,"props":4921,"children":4922},{},[4923,4928,4933],{"type":51,"tag":1184,"props":4924,"children":4925},{},[4926],{"type":57,"value":4927},"Artifacts\u002Ftearing",{"type":51,"tag":1184,"props":4929,"children":4930},{},[4931],{"type":57,"value":4932},"Using Raw Data Pipe",{"type":51,"tag":1184,"props":4934,"children":4935},{},[4936],{"type":57,"value":4937},"Switch to Canvas API",{"type":51,"tag":1162,"props":4939,"children":4940},{},[4941,4946,4951],{"type":51,"tag":1184,"props":4942,"children":4943},{},[4944],{"type":57,"value":4945},"Poor performance",{"type":51,"tag":1184,"props":4947,"children":4948},{},[4949],{"type":57,"value":4950},"YUV conversion on UI thread",{"type":51,"tag":1184,"props":4952,"children":4953},{},[4954],{"type":57,"value":4955},"Use Canvas API or move conversion to worker thread",{"type":51,"tag":1162,"props":4957,"children":4958},{},[4959,4964,4969],{"type":51,"tag":1184,"props":4960,"children":4961},{},[4962],{"type":57,"value":4963},"Video freezes",{"type":51,"tag":1184,"props":4965,"children":4966},{},[4967],{"type":57,"value":4968},"Not processing Windows messages",{"type":51,"tag":1184,"props":4970,"children":4971},{},[4972],{"type":57,"value":4973},"Add message pump to main loop",{"type":51,"tag":1162,"props":4975,"children":4976},{},[4977,4982,4987],{"type":51,"tag":1184,"props":4978,"children":4979},{},[4980],{"type":57,"value":4981},"Can't see self",{"type":51,"tag":1184,"props":4983,"children":4984},{},[4985],{"type":57,"value":4986},"Subscribing to wrong user",{"type":51,"tag":1184,"props":4988,"children":4989},{},[4990,4992,4998],{"type":57,"value":4991},"Use ",{"type":51,"tag":327,"props":4993,"children":4995},{"className":4994},[],[4996],{"type":57,"value":4997},"session->getMyself()",{"type":57,"value":4999}," for self video",{"type":51,"tag":1162,"props":5001,"children":5002},{},[5003,5008,5013],{"type":51,"tag":1184,"props":5004,"children":5005},{},[5006],{"type":57,"value":5007},"Seeing self in remote list",{"type":51,"tag":1184,"props":5009,"children":5010},{},[5011],{"type":57,"value":5012},"Not excluding self",{"type":51,"tag":1184,"props":5014,"children":5015},{},[5016,5018,5024],{"type":57,"value":5017},"Check ",{"type":51,"tag":327,"props":5019,"children":5021},{"className":5020},[],[5022],{"type":57,"value":5023},"if (user != myself)",{"type":57,"value":5025}," before subscribing",{"type":51,"tag":109,"props":5027,"children":5029},{"id":5028},"complete-documentation-library",[5030],{"type":57,"value":5031},"Complete Documentation Library",{"type":51,"tag":60,"props":5033,"children":5034},{},[5035],{"type":57,"value":5036},"This skill includes comprehensive guides organized by category:",{"type":51,"tag":520,"props":5038,"children":5040},{"id":5039},"core-concepts-start-here",[5041],{"type":57,"value":5042},"Core Concepts (Start Here!)",{"type":51,"tag":200,"props":5044,"children":5045},{},[5046,5057,5069],{"type":51,"tag":128,"props":5047,"children":5048},{},[5049,5056],{"type":51,"tag":69,"props":5050,"children":5051},{},[5052],{"type":51,"tag":77,"props":5053,"children":5054},{"href":136},[5055],{"type":57,"value":139},{"type":57,"value":141},{"type":51,"tag":128,"props":5058,"children":5059},{},[5060,5067],{"type":51,"tag":69,"props":5061,"children":5062},{},[5063],{"type":51,"tag":77,"props":5064,"children":5065},{"href":211},[5066],{"type":57,"value":214},{"type":57,"value":5068}," - 5-level navigation guide",{"type":51,"tag":128,"props":5070,"children":5071},{},[5072,5079],{"type":51,"tag":69,"props":5073,"children":5074},{},[5075],{"type":51,"tag":77,"props":5076,"children":5077},{"href":362},[5078],{"type":57,"value":365},{"type":57,"value":367},{"type":51,"tag":520,"props":5081,"children":5083},{"id":5082},"complete-examples",[5084],{"type":57,"value":5085},"Complete Examples",{"type":51,"tag":200,"props":5087,"children":5088},{},[5089,5101,5113,5126,5138,5152,5166,5180,5193,5206],{"type":51,"tag":128,"props":5090,"children":5091},{},[5092,5099],{"type":51,"tag":69,"props":5093,"children":5094},{},[5095],{"type":51,"tag":77,"props":5096,"children":5097},{"href":150},[5098],{"type":57,"value":153},{"type":57,"value":5100}," - JWT auth + session join with full code",{"type":51,"tag":128,"props":5102,"children":5103},{},[5104,5111],{"type":51,"tag":69,"props":5105,"children":5106},{},[5107],{"type":51,"tag":77,"props":5108,"children":5109},{"href":185},[5110],{"type":57,"value":188},{"type":57,"value":5112}," - Canvas API video display",{"type":51,"tag":128,"props":5114,"children":5115},{},[5116,5124],{"type":51,"tag":69,"props":5117,"children":5118},{},[5119],{"type":51,"tag":77,"props":5120,"children":5121},{"href":4720},[5122],{"type":57,"value":5123},"Screen Share Subscription",{"type":57,"value":5125}," - View remote screen shares (DIFFERENT from video!)",{"type":51,"tag":128,"props":5127,"children":5128},{},[5129,5136],{"type":51,"tag":69,"props":5130,"children":5131},{},[5132],{"type":51,"tag":77,"props":5133,"children":5134},{"href":373},[5135],{"type":57,"value":376},{"type":57,"value":5137}," - YUV420 frame capture",{"type":51,"tag":128,"props":5139,"children":5140},{},[5141,5150],{"type":51,"tag":69,"props":5142,"children":5143},{},[5144],{"type":51,"tag":77,"props":5145,"children":5147},{"href":5146},"examples\u002Fraw-audio-capture.md",[5148],{"type":57,"value":5149},"Raw Audio Capture",{"type":57,"value":5151}," - PCM audio capture",{"type":51,"tag":128,"props":5153,"children":5154},{},[5155,5164],{"type":51,"tag":69,"props":5156,"children":5157},{},[5158],{"type":51,"tag":77,"props":5159,"children":5161},{"href":5160},"examples\u002Fsend-raw-video.md",[5162],{"type":57,"value":5163},"Send Raw Video",{"type":57,"value":5165}," - Virtual camera (inject custom video)",{"type":51,"tag":128,"props":5167,"children":5168},{},[5169,5178],{"type":51,"tag":69,"props":5170,"children":5171},{},[5172],{"type":51,"tag":77,"props":5173,"children":5175},{"href":5174},"examples\u002Fsend-raw-audio.md",[5176],{"type":57,"value":5177},"Send Raw Audio",{"type":57,"value":5179}," - Virtual mic (inject custom audio)",{"type":51,"tag":128,"props":5181,"children":5182},{},[5183,5191],{"type":51,"tag":69,"props":5184,"children":5185},{},[5186],{"type":51,"tag":77,"props":5187,"children":5189},{"href":5188},"examples\u002Fcloud-recording.md",[5190],{"type":57,"value":440},{"type":57,"value":5192}," - Cloud recording control",{"type":51,"tag":128,"props":5194,"children":5195},{},[5196,5204],{"type":51,"tag":69,"props":5197,"children":5198},{},[5199],{"type":51,"tag":77,"props":5200,"children":5202},{"href":5201},"examples\u002Fcommand-channel.md",[5203],{"type":57,"value":1299},{"type":57,"value":5205}," - Custom command messaging",{"type":51,"tag":128,"props":5207,"children":5208},{},[5209,5218],{"type":51,"tag":69,"props":5210,"children":5211},{},[5212],{"type":51,"tag":77,"props":5213,"children":5215},{"href":5214},"examples\u002Ftranscription.md",[5216],{"type":57,"value":5217},"Transcription",{"type":57,"value":5219}," - Live transcription\u002Fcaptions",{"type":51,"tag":520,"props":5221,"children":5223},{"id":5222},"ui-framework-integration",[5224],{"type":57,"value":5225},"UI Framework Integration",{"type":51,"tag":200,"props":5227,"children":5228},{},[5229,5243,5257,5271],{"type":51,"tag":128,"props":5230,"children":5231},{},[5232,5241],{"type":51,"tag":69,"props":5233,"children":5234},{},[5235],{"type":51,"tag":77,"props":5236,"children":5238},{"href":5237},"examples\u002Fdotnet-winforms\u002FREADME.md#option-1-win32-native-c---direct-sdk",[5239],{"type":57,"value":5240},"Win32 Native",{"type":57,"value":5242}," - Direct SDK usage with Canvas API (best performance)",{"type":51,"tag":128,"props":5244,"children":5245},{},[5246,5255],{"type":51,"tag":69,"props":5247,"children":5248},{},[5249],{"type":51,"tag":77,"props":5250,"children":5252},{"href":5251},"examples\u002Fdotnet-winforms\u002FREADME.md#option-2-winforms-c--ccli-wrapper",[5253],{"type":57,"value":5254},"WinForms (.NET)",{"type":57,"value":5256}," - C++\u002FCLI wrapper + Raw Data Pipe",{"type":51,"tag":128,"props":5258,"children":5259},{},[5260,5269],{"type":51,"tag":69,"props":5261,"children":5262},{},[5263],{"type":51,"tag":77,"props":5264,"children":5266},{"href":5265},"examples\u002Fdotnet-winforms\u002FREADME.md#option-3-wpf-c--ccli-wrapper",[5267],{"type":57,"value":5268},"WPF (.NET)",{"type":57,"value":5270}," - C++\u002FCLI wrapper + BitmapSource conversion",{"type":51,"tag":128,"props":5272,"children":5273},{},[5274,5283],{"type":51,"tag":69,"props":5275,"children":5276},{},[5277],{"type":51,"tag":77,"props":5278,"children":5280},{"href":5279},"examples\u002Fdotnet-winforms\u002FREADME.md#production-quality-review",[5281],{"type":57,"value":5282},"Production Quality Guidelines",{"type":57,"value":5284}," - Checklist and common issues",{"type":51,"tag":520,"props":5286,"children":5288},{"id":5287},"ccli-wrapper-patterns-wrapping-any-native-library",[5289],{"type":57,"value":5290},"C++\u002FCLI Wrapper Patterns (Wrapping ANY Native Library)",{"type":51,"tag":200,"props":5292,"children":5293},{},[5294,5308,5322,5336,5350,5364,5378,5392,5406,5420],{"type":51,"tag":128,"props":5295,"children":5296},{},[5297,5306],{"type":51,"tag":69,"props":5298,"children":5299},{},[5300],{"type":51,"tag":77,"props":5301,"children":5303},{"href":5302},"examples\u002Fdotnet-winforms\u002FREADME.md#ccli-wrapper-patterns-for-net-integration",[5304],{"type":57,"value":5305},"Complete Guide",{"type":57,"value":5307}," - 8 patterns for native→.NET interop",{"type":51,"tag":128,"props":5309,"children":5310},{},[5311,5320],{"type":51,"tag":69,"props":5312,"children":5313},{},[5314],{"type":51,"tag":77,"props":5315,"children":5317},{"href":5316},"examples\u002Fdotnet-winforms\u002FREADME.md#pattern-1-basic-wrapper-structure",[5318],{"type":57,"value":5319},"Pattern 1: Basic Structure",{"type":57,"value":5321}," - Project setup, class layout",{"type":51,"tag":128,"props":5323,"children":5324},{},[5325,5334],{"type":51,"tag":69,"props":5326,"children":5327},{},[5328],{"type":51,"tag":77,"props":5329,"children":5331},{"href":5330},"examples\u002Fdotnet-winforms\u002FREADME.md#pattern-2-opaque-void-pointers",[5332],{"type":57,"value":5333},"Pattern 2: void* Pointers",{"type":57,"value":5335}," - Hide native types",{"type":51,"tag":128,"props":5337,"children":5338},{},[5339,5348],{"type":51,"tag":69,"props":5340,"children":5341},{},[5342],{"type":51,"tag":77,"props":5343,"children":5345},{"href":5344},"examples\u002Fdotnet-winforms\u002FREADME.md#pattern-3-gcrootT-for-nativemanaged-callbacks",[5346],{"type":57,"value":5347},"Pattern 3: gcroot Callbacks",{"type":57,"value":5349}," - Native→Managed events",{"type":51,"tag":128,"props":5351,"children":5352},{},[5353,5362],{"type":51,"tag":69,"props":5354,"children":5355},{},[5356],{"type":51,"tag":77,"props":5357,"children":5359},{"href":5358},"examples\u002Fdotnet-winforms\u002FREADME.md#pattern-4-destructor--finalizer-idisposable",[5360],{"type":57,"value":5361},"Pattern 4: IDisposable",{"type":57,"value":5363}," - Cleanup pattern",{"type":51,"tag":128,"props":5365,"children":5366},{},[5367,5376],{"type":51,"tag":69,"props":5368,"children":5369},{},[5370],{"type":51,"tag":77,"props":5371,"children":5373},{"href":5372},"examples\u002Fdotnet-winforms\u002FREADME.md#pattern-5-string-conversion",[5374],{"type":57,"value":5375},"Pattern 5: Strings",{"type":57,"value":5377}," - String^ ↔ wstring\u002Fstring",{"type":51,"tag":128,"props":5379,"children":5380},{},[5381,5390],{"type":51,"tag":69,"props":5382,"children":5383},{},[5384],{"type":51,"tag":77,"props":5385,"children":5387},{"href":5386},"examples\u002Fdotnet-winforms\u002FREADME.md#pattern-6-arraybuffer-conversion",[5388],{"type":57,"value":5389},"Pattern 6: Arrays",{"type":57,"value":5391}," - pin_ptr, Marshal::Copy",{"type":51,"tag":128,"props":5393,"children":5394},{},[5395,5404],{"type":51,"tag":69,"props":5396,"children":5397},{},[5398],{"type":51,"tag":77,"props":5399,"children":5401},{"href":5400},"examples\u002Fdotnet-winforms\u002FREADME.md#pattern-7-thread-marshaling-native-thread--ui-thread",[5402],{"type":57,"value":5403},"Pattern 7: Threading",{"type":57,"value":5405}," - UI thread dispatch",{"type":51,"tag":128,"props":5407,"children":5408},{},[5409,5418],{"type":51,"tag":69,"props":5410,"children":5411},{},[5412],{"type":51,"tag":77,"props":5413,"children":5415},{"href":5414},"examples\u002Fdotnet-winforms\u002FREADME.md#pattern-8-lockbits-for-fast-image-manipulation",[5416],{"type":57,"value":5417},"Pattern 8: LockBits",{"type":57,"value":5419}," - Fast image conversion",{"type":51,"tag":128,"props":5421,"children":5422},{},[5423,5432],{"type":51,"tag":69,"props":5424,"children":5425},{},[5426],{"type":51,"tag":77,"props":5427,"children":5429},{"href":5428},"examples\u002Fdotnet-winforms\u002FREADME.md#common-wrapper-errors",[5430],{"type":57,"value":5431},"Common Errors",{"type":57,"value":5433}," - Troubleshooting",{"type":51,"tag":520,"props":5435,"children":5437},{"id":5436},"troubleshooting",[5438],{"type":57,"value":5439},"Troubleshooting",{"type":51,"tag":200,"props":5441,"children":5442},{},[5443,5460,5473],{"type":51,"tag":128,"props":5444,"children":5445},{},[5446,5453,5454,5458],{"type":51,"tag":69,"props":5447,"children":5448},{},[5449],{"type":51,"tag":77,"props":5450,"children":5451},{"href":164},[5452],{"type":57,"value":167},{"type":57,"value":169},{"type":51,"tag":69,"props":5455,"children":5456},{},[5457],{"type":57,"value":174},{"type":57,"value":5459},": Why callbacks don't fire",{"type":51,"tag":128,"props":5461,"children":5462},{},[5463,5471],{"type":51,"tag":69,"props":5464,"children":5465},{},[5466],{"type":51,"tag":77,"props":5467,"children":5468},{"href":311},[5469],{"type":57,"value":5470},"Build Errors",{"type":57,"value":5472}," - SDK header dependency fixes",{"type":51,"tag":128,"props":5474,"children":5475},{},[5476,5483],{"type":51,"tag":69,"props":5477,"children":5478},{},[5479],{"type":51,"tag":77,"props":5480,"children":5481},{"href":342},[5482],{"type":57,"value":345},{"type":57,"value":5484}," - Quick diagnostics & error codes",{"type":51,"tag":520,"props":5486,"children":5488},{"id":5487},"references",[5489],{"type":57,"value":5490},"References",{"type":51,"tag":200,"props":5492,"children":5493},{},[5494,5506,5517],{"type":51,"tag":128,"props":5495,"children":5496},{},[5497,5504],{"type":51,"tag":69,"props":5498,"children":5499},{},[5500],{"type":51,"tag":77,"props":5501,"children":5502},{"href":225},[5503],{"type":57,"value":88},{"type":57,"value":5505}," - 5-level API hierarchy, methods, error codes",{"type":51,"tag":128,"props":5507,"children":5508},{},[5509,5516],{"type":51,"tag":69,"props":5510,"children":5511},{},[5512],{"type":51,"tag":77,"props":5513,"children":5514},{"href":238},[5515],{"type":57,"value":241},{"type":57,"value":243},{"type":51,"tag":128,"props":5518,"children":5519},{},[5520,5527],{"type":51,"tag":69,"props":5521,"children":5522},{},[5523],{"type":51,"tag":77,"props":5524,"children":5525},{"href":279},[5526],{"type":57,"value":279},{"type":57,"value":5528}," - Complete navigation guide",{"type":51,"tag":520,"props":5530,"children":5532},{"id":5531},"most-critical-issues-from-real-debugging",[5533],{"type":57,"value":5534},"Most Critical Issues (From Real Debugging)",{"type":51,"tag":124,"props":5536,"children":5537},{},[5538,5561,5589],{"type":51,"tag":128,"props":5539,"children":5540},{},[5541,5546,5548],{"type":51,"tag":69,"props":5542,"children":5543},{},[5544],{"type":57,"value":5545},"Callbacks not firing",{"type":57,"value":5547}," → Missing Windows message loop (99% of issues)",{"type":51,"tag":200,"props":5549,"children":5550},{},[5551],{"type":51,"tag":128,"props":5552,"children":5553},{},[5554,5556],{"type":57,"value":5555},"See: ",{"type":51,"tag":77,"props":5557,"children":5558},{"href":164},[5559],{"type":57,"value":5560},"Windows Message Loop Guide",{"type":51,"tag":128,"props":5562,"children":5563},{},[5564,5569,5571],{"type":51,"tag":69,"props":5565,"children":5566},{},[5567],{"type":57,"value":5568},"Video subscribe returns error 2",{"type":57,"value":5570}," → Subscribing too early",{"type":51,"tag":200,"props":5572,"children":5573},{},[5574],{"type":51,"tag":128,"props":5575,"children":5576},{},[5577,5578,5582,5584],{"type":57,"value":5555},{"type":51,"tag":77,"props":5579,"children":5580},{"href":185},[5581],{"type":57,"value":188},{"type":57,"value":5583}," - Subscribe in ",{"type":51,"tag":327,"props":5585,"children":5587},{"className":5586},[],[5588],{"type":57,"value":332},{"type":51,"tag":128,"props":5590,"children":5591},{},[5592,5597,5599],{"type":51,"tag":69,"props":5593,"children":5594},{},[5595],{"type":57,"value":5596},"Abstract class errors",{"type":57,"value":5598}," → Missing virtual method implementations",{"type":51,"tag":200,"props":5600,"children":5601},{},[5602],{"type":51,"tag":128,"props":5603,"children":5604},{},[5605,5606],{"type":57,"value":5555},{"type":51,"tag":77,"props":5607,"children":5608},{"href":238},[5609],{"type":57,"value":241},{"type":51,"tag":520,"props":5611,"children":5613},{"id":5612},"key-insight",[5614],{"type":57,"value":5615},"Key Insight",{"type":51,"tag":60,"props":5617,"children":5618},{},[5619],{"type":51,"tag":69,"props":5620,"children":5621},{},[5622],{"type":57,"value":5623},"Once you learn the 3-step pattern, you can implement ANY feature:",{"type":51,"tag":124,"props":5625,"children":5626},{},[5627],{"type":51,"tag":128,"props":5628,"children":5629},{},[5630],{"type":57,"value":5631},"Get singleton → 2. Implement delegate → 3. Subscribe & use",{"type":51,"tag":60,"props":5633,"children":5634},{},[5635,5636],{"type":57,"value":5555},{"type":51,"tag":77,"props":5637,"children":5638},{"href":136},[5639],{"type":57,"value":139},{"type":51,"tag":109,"props":5641,"children":5643},{"id":5642},"resources",[5644],{"type":57,"value":5645},"Resources",{"type":51,"tag":200,"props":5647,"children":5648},{},[5649,5663,5676,5691,5705],{"type":51,"tag":128,"props":5650,"children":5651},{},[5652,5657,5658],{"type":51,"tag":69,"props":5653,"children":5654},{},[5655],{"type":57,"value":5656},"Official Docs",{"type":57,"value":75},{"type":51,"tag":77,"props":5659,"children":5661},{"href":79,"rel":5660},[81],[5662],{"type":57,"value":79},{"type":51,"tag":128,"props":5664,"children":5665},{},[5666,5670,5671],{"type":51,"tag":69,"props":5667,"children":5668},{},[5669],{"type":57,"value":88},{"type":57,"value":75},{"type":51,"tag":77,"props":5672,"children":5674},{"href":92,"rel":5673},[81],[5675],{"type":57,"value":92},{"type":51,"tag":128,"props":5677,"children":5678},{},[5679,5684,5685],{"type":51,"tag":69,"props":5680,"children":5681},{},[5682],{"type":57,"value":5683},"Dev Forum",{"type":57,"value":75},{"type":51,"tag":77,"props":5686,"children":5689},{"href":5687,"rel":5688},"https:\u002F\u002Fdevforum.zoom.us\u002F",[81],[5690],{"type":57,"value":5687},{"type":51,"tag":128,"props":5692,"children":5693},{},[5694,5699,5700],{"type":51,"tag":69,"props":5695,"children":5696},{},[5697],{"type":57,"value":5698},"GitHub Samples",{"type":57,"value":75},{"type":51,"tag":77,"props":5701,"children":5703},{"href":104,"rel":5702},[81],[5704],{"type":57,"value":104},{"type":51,"tag":128,"props":5706,"children":5707},{},[5708,5713,5714,5720],{"type":51,"tag":69,"props":5709,"children":5710},{},[5711],{"type":57,"value":5712},"Working Sample",{"type":57,"value":75},{"type":51,"tag":327,"props":5715,"children":5717},{"className":5716},[],[5718],{"type":57,"value":5719},"C:\\tempsdk\\zoom-video-sdk-windows-sample\\",{"type":57,"value":5721}," (complete implementation)",{"type":51,"tag":5723,"props":5724,"children":5725},"hr",{},[],{"type":51,"tag":60,"props":5727,"children":5728},{},[5729,5734,5736,5740],{"type":51,"tag":69,"props":5730,"children":5731},{},[5732],{"type":57,"value":5733},"Need help?",{"type":57,"value":5735}," Start with ",{"type":51,"tag":77,"props":5737,"children":5738},{"href":279},[5739],{"type":57,"value":279},{"type":57,"value":5741}," for complete navigation.",{"type":51,"tag":109,"props":5743,"children":5745},{"id":5744},"merged-from-video-sdkwindowsskillmd",[5746],{"type":57,"value":5747},"Merged from video-sdk\u002Fwindows\u002FSKILL.md",{"type":51,"tag":52,"props":5749,"children":5751},{"id":5750},"zoom-video-sdk-windows-complete-documentation-index",[5752],{"type":57,"value":5753},"Zoom Video SDK Windows - Complete Documentation Index",{"type":51,"tag":109,"props":5755,"children":5757},{"id":5756},"quick-start-path",[5758],{"type":57,"value":5759},"Quick Start Path",{"type":51,"tag":60,"props":5761,"children":5762},{},[5763],{"type":51,"tag":69,"props":5764,"children":5765},{},[5766],{"type":57,"value":5767},"If you're new to the SDK, follow this order:",{"type":51,"tag":124,"props":5769,"children":5771},{"start":5770},0,[5772,5786,5812,5838,5859,5884,5905],{"type":51,"tag":128,"props":5773,"children":5774},{},[5775,5780,5782],{"type":51,"tag":69,"props":5776,"children":5777},{},[5778],{"type":57,"value":5779},"Overview",{"type":57,"value":5781}," → ",{"type":51,"tag":77,"props":5783,"children":5784},{"href":266},[5785],{"type":57,"value":266},{"type":51,"tag":128,"props":5787,"children":5788},{},[5789,5794,5795,5799],{"type":51,"tag":69,"props":5790,"children":5791},{},[5792],{"type":57,"value":5793},"Read the architecture pattern",{"type":57,"value":5781},{"type":51,"tag":77,"props":5796,"children":5797},{"href":136},[5798],{"type":57,"value":136},{"type":51,"tag":200,"props":5800,"children":5801},{},[5802,5807],{"type":51,"tag":128,"props":5803,"children":5804},{},[5805],{"type":57,"value":5806},"Universal formula: Singleton → Delegate → Subscribe",{"type":51,"tag":128,"props":5808,"children":5809},{},[5810],{"type":57,"value":5811},"Once you understand this, you can implement any feature",{"type":51,"tag":128,"props":5813,"children":5814},{},[5815,5820,5821,5825],{"type":51,"tag":69,"props":5816,"children":5817},{},[5818],{"type":57,"value":5819},"Fix build errors",{"type":57,"value":5781},{"type":51,"tag":77,"props":5822,"children":5823},{"href":311},[5824],{"type":57,"value":311},{"type":51,"tag":200,"props":5826,"children":5827},{},[5828,5833],{"type":51,"tag":128,"props":5829,"children":5830},{},[5831],{"type":57,"value":5832},"SDK header dependencies",{"type":51,"tag":128,"props":5834,"children":5835},{},[5836],{"type":57,"value":5837},"Required include order",{"type":51,"tag":128,"props":5839,"children":5840},{},[5841,5846,5847,5851],{"type":51,"tag":69,"props":5842,"children":5843},{},[5844],{"type":57,"value":5845},"Implement session join",{"type":57,"value":5781},{"type":51,"tag":77,"props":5848,"children":5849},{"href":150},[5850],{"type":57,"value":150},{"type":51,"tag":200,"props":5852,"children":5853},{},[5854],{"type":51,"tag":128,"props":5855,"children":5856},{},[5857],{"type":57,"value":5858},"Complete working JWT + session join code",{"type":51,"tag":128,"props":5860,"children":5861},{},[5862,5867,5868,5872],{"type":51,"tag":69,"props":5863,"children":5864},{},[5865],{"type":57,"value":5866},"Fix callback issues",{"type":57,"value":5781},{"type":51,"tag":77,"props":5869,"children":5870},{"href":164},[5871],{"type":57,"value":164},{"type":51,"tag":200,"props":5873,"children":5874},{},[5875],{"type":51,"tag":128,"props":5876,"children":5877},{},[5878,5882],{"type":51,"tag":69,"props":5879,"children":5880},{},[5881],{"type":57,"value":174},{"type":57,"value":5883},": Why callbacks don't fire without Windows message loop",{"type":51,"tag":128,"props":5885,"children":5886},{},[5887,5892,5893,5897],{"type":51,"tag":69,"props":5888,"children":5889},{},[5890],{"type":57,"value":5891},"Implement video",{"type":57,"value":5781},{"type":51,"tag":77,"props":5894,"children":5895},{"href":185},[5896],{"type":57,"value":185},{"type":51,"tag":200,"props":5898,"children":5899},{},[5900],{"type":51,"tag":128,"props":5901,"children":5902},{},[5903],{"type":57,"value":5904},"Canvas API (SDK-rendered) vs Raw Data Pipe",{"type":51,"tag":128,"props":5906,"children":5907},{},[5908,5913,5914,5918],{"type":51,"tag":69,"props":5909,"children":5910},{},[5911],{"type":57,"value":5912},"Troubleshoot any issues",{"type":57,"value":5781},{"type":51,"tag":77,"props":5915,"children":5916},{"href":342},[5917],{"type":57,"value":342},{"type":51,"tag":200,"props":5919,"children":5920},{},[5921,5926],{"type":51,"tag":128,"props":5922,"children":5923},{},[5924],{"type":57,"value":5925},"Quick diagnostic checklist",{"type":51,"tag":128,"props":5927,"children":5928},{},[5929],{"type":57,"value":5930},"Error code tables",{"type":51,"tag":5723,"props":5932,"children":5933},{},[],{"type":51,"tag":109,"props":5935,"children":5937},{"id":5936},"documentation-structure",[5938],{"type":57,"value":5939},"Documentation Structure",{"type":51,"tag":655,"props":5941,"children":5945},{"className":5942,"code":5944,"language":57},[5943],"language-text","video-sdk\u002Fwindows\u002F\n├── SKILL.md                           # Main skill overview\n├── SKILL.md                           # This file - navigation guide\n├── windows.md                          # Secondary overview doc (pointer-style)\n│\n├── concepts\u002F                          # Core architectural patterns\n│   ├── sdk-architecture-pattern.md   # Universal formula for ANY feature\n│   ├── singleton-hierarchy.md        # 5-level navigation guide\n│   └── canvas-vs-raw-data.md         # SDK-rendered vs self-rendered choice\n│\n├── examples\u002F                          # Complete working code\n│   ├── session-join-pattern.md       # JWT auth + session join\n│   ├── video-rendering.md            # Canvas API video display\n│   ├── screen-share-subscription.md  # View remote screen shares\n│   ├── raw-video-capture.md          # YUV420 raw frame capture\n│   ├── raw-audio-capture.md          # PCM audio capture\n│   ├── send-raw-video.md             # Virtual camera (inject video)\n│   ├── send-raw-audio.md             # Virtual mic (inject audio)\n│   ├── cloud-recording.md            # Cloud recording control\n│   ├── command-channel.md            # Custom command messaging\n│   ├── transcription.md              # Live transcription\u002Fcaptions\n│   └── dotnet-winforms\u002F              # UI Framework integration\n│       └── README.md                 # Win32, WinForms, WPF patterns\n│                                     # C++\u002FCLI wrapper patterns\n│                                     # Production quality guidelines\n│\n├── troubleshooting\u002F                   # Problem solving guides\n│   ├── windows-message-loop.md       # CRITICAL - Why callbacks fail\n│   ├── build-errors.md               # Header dependency fixes\n│   └── common-issues.md              # Quick diagnostic workflow\n│\n└── references\u002F                        # Reference documentation\n    ├── windows-reference.md           # API hierarchy, methods, error codes\n    ├── delegate-methods.md            # All 80+ callback methods\n    └── samples.md                     # Official samples guide\n",[5946],{"type":51,"tag":327,"props":5947,"children":5948},{"__ignoreMap":660},[5949],{"type":57,"value":5944},{"type":51,"tag":5723,"props":5951,"children":5952},{},[],{"type":51,"tag":109,"props":5954,"children":5956},{"id":5955},"by-use-case",[5957],{"type":57,"value":5958},"By Use Case",{"type":51,"tag":520,"props":5960,"children":5962},{"id":5961},"i-want-to-build-a-video-app",[5963],{"type":57,"value":5964},"I want to build a video app",{"type":51,"tag":124,"props":5966,"children":5967},{},[5968,5977,5986,5995],{"type":51,"tag":128,"props":5969,"children":5970},{},[5971,5975],{"type":51,"tag":77,"props":5972,"children":5973},{"href":136},[5974],{"type":57,"value":139},{"type":57,"value":5976}," - Understand the pattern",{"type":51,"tag":128,"props":5978,"children":5979},{},[5980,5984],{"type":51,"tag":77,"props":5981,"children":5982},{"href":150},[5983],{"type":57,"value":153},{"type":57,"value":5985}," - Join sessions",{"type":51,"tag":128,"props":5987,"children":5988},{},[5989,5993],{"type":51,"tag":77,"props":5990,"children":5991},{"href":185},[5992],{"type":57,"value":188},{"type":57,"value":5994}," - Display video",{"type":51,"tag":128,"props":5996,"children":5997},{},[5998,6002],{"type":51,"tag":77,"props":5999,"children":6000},{"href":164},[6001],{"type":57,"value":167},{"type":57,"value":6003}," - Fix callback issues",{"type":51,"tag":520,"props":6005,"children":6007},{"id":6006},"im-getting-build-errors",[6008],{"type":57,"value":6009},"I'm getting build errors",{"type":51,"tag":124,"props":6011,"children":6012},{},[6013,6022,6031],{"type":51,"tag":128,"props":6014,"children":6015},{},[6016,6020],{"type":51,"tag":77,"props":6017,"children":6018},{"href":311},[6019],{"type":57,"value":314},{"type":57,"value":6021}," - SDK header dependencies",{"type":51,"tag":128,"props":6023,"children":6024},{},[6025,6029],{"type":51,"tag":77,"props":6026,"children":6027},{"href":238},[6028],{"type":57,"value":241},{"type":57,"value":6030}," - Abstract class errors",{"type":51,"tag":128,"props":6032,"children":6033},{},[6034,6038],{"type":51,"tag":77,"props":6035,"children":6036},{"href":342},[6037],{"type":57,"value":345},{"type":57,"value":6039}," - Linker errors",{"type":51,"tag":520,"props":6041,"children":6043},{"id":6042},"im-getting-runtime-errors",[6044],{"type":57,"value":6045},"I'm getting runtime errors",{"type":51,"tag":124,"props":6047,"children":6048},{},[6049,6058],{"type":51,"tag":128,"props":6050,"children":6051},{},[6052,6056],{"type":51,"tag":77,"props":6053,"children":6054},{"href":164},[6055],{"type":57,"value":167},{"type":57,"value":6057}," - Callbacks not firing",{"type":51,"tag":128,"props":6059,"children":6060},{},[6061,6065],{"type":51,"tag":77,"props":6062,"children":6063},{"href":342},[6064],{"type":57,"value":345},{"type":57,"value":6066}," - Error code tables",{"type":51,"tag":520,"props":6068,"children":6070},{"id":6069},"i-want-to-view-screen-shares",[6071],{"type":57,"value":6072},"I want to view screen shares",{"type":51,"tag":124,"props":6074,"children":6075},{},[6076,6089,6098],{"type":51,"tag":128,"props":6077,"children":6078},{},[6079,6083,6084],{"type":51,"tag":77,"props":6080,"children":6081},{"href":4720},[6082],{"type":57,"value":5123},{"type":57,"value":169},{"type":51,"tag":69,"props":6085,"children":6086},{},[6087],{"type":57,"value":6088},"DIFFERENT from video!",{"type":51,"tag":128,"props":6090,"children":6091},{},[6092,6096],{"type":51,"tag":77,"props":6093,"children":6094},{"href":136},[6095],{"type":57,"value":139},{"type":57,"value":6097}," - Event-driven pattern",{"type":51,"tag":128,"props":6099,"children":6100},{},[6101,6105],{"type":51,"tag":77,"props":6102,"children":6103},{"href":185},[6104],{"type":57,"value":188},{"type":57,"value":6106}," - Compare with video subscription",{"type":51,"tag":520,"props":6108,"children":6110},{"id":6109},"i-want-to-capture-raw-videoaudio",[6111],{"type":57,"value":6112},"I want to capture raw video\u002Faudio",{"type":51,"tag":124,"props":6114,"children":6115},{},[6116,6125,6133,6141],{"type":51,"tag":128,"props":6117,"children":6118},{},[6119,6123],{"type":51,"tag":77,"props":6120,"children":6121},{"href":362},[6122],{"type":57,"value":365},{"type":57,"value":6124}," - Choose your approach",{"type":51,"tag":128,"props":6126,"children":6127},{},[6128,6132],{"type":51,"tag":77,"props":6129,"children":6130},{"href":373},[6131],{"type":57,"value":376},{"type":57,"value":5137},{"type":51,"tag":128,"props":6134,"children":6135},{},[6136,6140],{"type":51,"tag":77,"props":6137,"children":6138},{"href":5146},[6139],{"type":57,"value":5149},{"type":57,"value":5151},{"type":51,"tag":128,"props":6142,"children":6143},{},[6144,6148],{"type":51,"tag":77,"props":6145,"children":6146},{"href":136},[6147],{"type":57,"value":139},{"type":57,"value":6149}," - Subscription pattern",{"type":51,"tag":520,"props":6151,"children":6153},{"id":6152},"i-want-to-send-custom-videoaudio-virtual-cameramic",[6154],{"type":57,"value":6155},"I want to send custom video\u002Faudio (virtual camera\u002Fmic)",{"type":51,"tag":124,"props":6157,"children":6158},{},[6159,6168,6177],{"type":51,"tag":128,"props":6160,"children":6161},{},[6162,6166],{"type":51,"tag":77,"props":6163,"children":6164},{"href":5160},[6165],{"type":57,"value":5163},{"type":57,"value":6167}," - Inject custom video frames",{"type":51,"tag":128,"props":6169,"children":6170},{},[6171,6175],{"type":51,"tag":77,"props":6172,"children":6173},{"href":5174},[6174],{"type":57,"value":5177},{"type":57,"value":6176}," - Inject custom audio",{"type":51,"tag":128,"props":6178,"children":6179},{},[6180,6184],{"type":51,"tag":77,"props":6181,"children":6182},{"href":136},[6183],{"type":57,"value":139},{"type":57,"value":6185}," - External source pattern",{"type":51,"tag":520,"props":6187,"children":6189},{"id":6188},"i-want-to-record-sessions",[6190],{"type":57,"value":6191},"I want to record sessions",{"type":51,"tag":124,"props":6193,"children":6194},{},[6195,6204],{"type":51,"tag":128,"props":6196,"children":6197},{},[6198,6202],{"type":51,"tag":77,"props":6199,"children":6200},{"href":5188},[6201],{"type":57,"value":440},{"type":57,"value":6203}," - Start\u002Fstop cloud recording",{"type":51,"tag":128,"props":6205,"children":6206},{},[6207,6211],{"type":51,"tag":77,"props":6208,"children":6209},{"href":225},[6210],{"type":57,"value":88},{"type":57,"value":6212}," - Recording helper methods",{"type":51,"tag":520,"props":6214,"children":6216},{"id":6215},"i-want-to-use-live-transcription",[6217],{"type":57,"value":6218},"I want to use live transcription",{"type":51,"tag":124,"props":6220,"children":6221},{},[6222,6231],{"type":51,"tag":128,"props":6223,"children":6224},{},[6225,6229],{"type":51,"tag":77,"props":6226,"children":6227},{"href":5214},[6228],{"type":57,"value":5217},{"type":57,"value":6230}," - Enable live captions",{"type":51,"tag":128,"props":6232,"children":6233},{},[6234,6238],{"type":51,"tag":77,"props":6235,"children":6236},{"href":238},[6237],{"type":57,"value":241},{"type":57,"value":6239}," - Transcription callbacks",{"type":51,"tag":520,"props":6241,"children":6243},{"id":6242},"i-want-custom-messaging-between-participants",[6244],{"type":57,"value":6245},"I want custom messaging between participants",{"type":51,"tag":124,"props":6247,"children":6248},{},[6249,6258],{"type":51,"tag":128,"props":6250,"children":6251},{},[6252,6256],{"type":51,"tag":77,"props":6253,"children":6254},{"href":5201},[6255],{"type":57,"value":1299},{"type":57,"value":6257}," - Send custom commands",{"type":51,"tag":128,"props":6259,"children":6260},{},[6261,6265],{"type":51,"tag":77,"props":6262,"children":6263},{"href":225},[6264],{"type":57,"value":88},{"type":57,"value":6266}," - Command channel methods",{"type":51,"tag":520,"props":6268,"children":6270},{"id":6269},"i-want-to-build-a-win32-native-app",[6271],{"type":57,"value":6272},"I want to build a Win32 native app",{"type":51,"tag":124,"props":6274,"children":6275},{},[6276,6286,6295],{"type":51,"tag":128,"props":6277,"children":6278},{},[6279,6284],{"type":51,"tag":77,"props":6280,"children":6281},{"href":5237},[6282],{"type":57,"value":6283},"Win32 Integration",{"type":57,"value":6285}," - Direct SDK + Canvas API",{"type":51,"tag":128,"props":6287,"children":6288},{},[6289,6293],{"type":51,"tag":77,"props":6290,"children":6291},{"href":185},[6292],{"type":57,"value":188},{"type":57,"value":6294}," - Canvas API patterns",{"type":51,"tag":128,"props":6296,"children":6297},{},[6298,6303],{"type":51,"tag":77,"props":6299,"children":6300},{"href":5279},[6301],{"type":57,"value":6302},"Production Guidelines",{"type":57,"value":6304}," - Best practices",{"type":51,"tag":520,"props":6306,"children":6308},{"id":6307},"i-want-to-build-a-winforms-net-app",[6309],{"type":57,"value":6310},"I want to build a WinForms (.NET) app",{"type":51,"tag":124,"props":6312,"children":6313},{},[6314,6324,6334],{"type":51,"tag":128,"props":6315,"children":6316},{},[6317,6322],{"type":51,"tag":77,"props":6318,"children":6319},{"href":5251},[6320],{"type":57,"value":6321},"WinForms Integration",{"type":57,"value":6323}," - C++\u002FCLI wrapper + Raw Data",{"type":51,"tag":128,"props":6325,"children":6326},{},[6327,6332],{"type":51,"tag":77,"props":6328,"children":6329},{"href":5302},[6330],{"type":57,"value":6331},"C++\u002FCLI Patterns",{"type":57,"value":6333}," - gcroot, Finalizer, LockBits",{"type":51,"tag":128,"props":6335,"children":6336},{},[6337,6341],{"type":51,"tag":77,"props":6338,"children":6339},{"href":5279},[6340],{"type":57,"value":6302},{"type":57,"value":6342}," - IDisposable, thread safety",{"type":51,"tag":520,"props":6344,"children":6346},{"id":6345},"i-want-to-build-a-wpf-net-app",[6347],{"type":57,"value":6348},"I want to build a WPF (.NET) app",{"type":51,"tag":124,"props":6350,"children":6351},{},[6352,6362,6373],{"type":51,"tag":128,"props":6353,"children":6354},{},[6355,6360],{"type":51,"tag":77,"props":6356,"children":6357},{"href":5265},[6358],{"type":57,"value":6359},"WPF Integration",{"type":57,"value":6361}," - C++\u002FCLI + BitmapSource",{"type":51,"tag":128,"props":6363,"children":6364},{},[6365,6371],{"type":51,"tag":77,"props":6366,"children":6368},{"href":6367},"examples\u002Fdotnet-winforms\u002FREADME.md#2-bitmap--bitmapsource-conversion",[6369],{"type":57,"value":6370},"Bitmap Conversion",{"type":57,"value":6372}," - Freeze(), Dispatcher",{"type":51,"tag":128,"props":6374,"children":6375},{},[6376,6380],{"type":51,"tag":77,"props":6377,"children":6378},{"href":5279},[6379],{"type":57,"value":6302},{"type":57,"value":6381}," - Performance optimization",{"type":51,"tag":520,"props":6383,"children":6385},{"id":6384},"i-want-to-use-c-net-framework-general",[6386],{"type":57,"value":6387},"I want to use C# \u002F .NET Framework (general)",{"type":51,"tag":124,"props":6389,"children":6390},{},[6391,6406,6415],{"type":51,"tag":128,"props":6392,"children":6393},{},[6394,6400,6401],{"type":51,"tag":77,"props":6395,"children":6397},{"href":6396},"examples\u002Fdotnet-winforms\u002FREADME.md",[6398],{"type":57,"value":6399},".NET Integration Overview",{"type":57,"value":169},{"type":51,"tag":69,"props":6402,"children":6403},{},[6404],{"type":57,"value":6405},"Complete C++\u002FCLI wrapper guide",{"type":51,"tag":128,"props":6407,"children":6408},{},[6409,6413],{"type":51,"tag":77,"props":6410,"children":6411},{"href":373},[6412],{"type":57,"value":376},{"type":57,"value":6414}," - YUV→RGB conversion patterns",{"type":51,"tag":128,"props":6416,"children":6417},{},[6418,6422],{"type":51,"tag":77,"props":6419,"children":6420},{"href":150},[6421],{"type":57,"value":153},{"type":57,"value":6423}," - SDK initialization flow",{"type":51,"tag":520,"props":6425,"children":6427},{"id":6426},"i-want-to-wrap-any-native-c-library-for-net",[6428],{"type":57,"value":6429},"I want to wrap ANY native C++ library for .NET",{"type":51,"tag":124,"props":6431,"children":6432},{},[6433,6447,6456,6464,6472],{"type":51,"tag":128,"props":6434,"children":6435},{},[6436,6441,6442],{"type":51,"tag":77,"props":6437,"children":6438},{"href":5302},[6439],{"type":57,"value":6440},"C++\u002FCLI Wrapper Patterns",{"type":57,"value":169},{"type":51,"tag":69,"props":6443,"children":6444},{},[6445],{"type":57,"value":6446},"Complete 8-pattern guide",{"type":51,"tag":128,"props":6448,"children":6449},{},[6450,6454],{"type":51,"tag":77,"props":6451,"children":6452},{"href":5316},[6453],{"type":57,"value":5319},{"type":57,"value":6455}," - Project setup + class layout",{"type":51,"tag":128,"props":6457,"children":6458},{},[6459,6463],{"type":51,"tag":77,"props":6460,"children":6461},{"href":5344},[6462],{"type":57,"value":5347},{"type":57,"value":5349},{"type":51,"tag":128,"props":6465,"children":6466},{},[6467,6471],{"type":51,"tag":77,"props":6468,"children":6469},{"href":5358},[6470],{"type":57,"value":5361},{"type":57,"value":5363},{"type":51,"tag":128,"props":6473,"children":6474},{},[6475,6479],{"type":51,"tag":77,"props":6476,"children":6477},{"href":5428},[6478],{"type":57,"value":5431},{"type":57,"value":5433},{"type":51,"tag":520,"props":6481,"children":6483},{"id":6482},"i-want-to-implement-a-specific-feature",[6484],{"type":57,"value":6485},"I want to implement a specific feature",{"type":51,"tag":124,"props":6487,"children":6488},{},[6489,6502,6511],{"type":51,"tag":128,"props":6490,"children":6491},{},[6492,6496,6497],{"type":51,"tag":77,"props":6493,"children":6494},{"href":136},[6495],{"type":57,"value":139},{"type":57,"value":169},{"type":51,"tag":69,"props":6498,"children":6499},{},[6500],{"type":57,"value":6501},"START HERE!",{"type":51,"tag":128,"props":6503,"children":6504},{},[6505,6509],{"type":51,"tag":77,"props":6506,"children":6507},{"href":211},[6508],{"type":57,"value":214},{"type":57,"value":6510}," - Navigate to the feature",{"type":51,"tag":128,"props":6512,"children":6513},{},[6514,6518],{"type":51,"tag":77,"props":6515,"children":6516},{"href":225},[6517],{"type":57,"value":88},{"type":57,"value":6519}," - Method signatures",{"type":51,"tag":5723,"props":6521,"children":6522},{},[],{"type":51,"tag":109,"props":6524,"children":6526},{"id":6525},"most-critical-documents",[6527],{"type":57,"value":6528},"Most Critical Documents",{"type":51,"tag":520,"props":6530,"children":6532},{"id":6531},"_1-sdk-architecture-pattern-master-document",[6533],{"type":57,"value":6534},"1. SDK Architecture Pattern (MASTER DOCUMENT)",{"type":51,"tag":60,"props":6536,"children":6537},{},[6538],{"type":51,"tag":69,"props":6539,"children":6540},{},[6541],{"type":51,"tag":77,"props":6542,"children":6543},{"href":136},[6544],{"type":57,"value":136},{"type":51,"tag":60,"props":6546,"children":6547},{},[6548],{"type":57,"value":6549},"The universal 3-step pattern:",{"type":51,"tag":124,"props":6551,"children":6552},{},[6553,6558,6563],{"type":51,"tag":128,"props":6554,"children":6555},{},[6556],{"type":57,"value":6557},"Get singleton (SDK, helpers, session, users)",{"type":51,"tag":128,"props":6559,"children":6560},{},[6561],{"type":57,"value":6562},"Implement delegate (event callbacks)",{"type":51,"tag":128,"props":6564,"children":6565},{},[6566],{"type":57,"value":6567},"Subscribe and use",{"type":51,"tag":520,"props":6569,"children":6571},{"id":6570},"_2-windows-message-loop-most-common-issue",[6572],{"type":57,"value":6573},"2. Windows Message Loop (MOST COMMON ISSUE)",{"type":51,"tag":60,"props":6575,"children":6576},{},[6577],{"type":51,"tag":69,"props":6578,"children":6579},{},[6580],{"type":51,"tag":77,"props":6581,"children":6582},{"href":164},[6583],{"type":57,"value":164},{"type":51,"tag":60,"props":6585,"children":6586},{},[6587],{"type":57,"value":6588},"99% of \"callbacks not firing\" issues are caused by missing Windows message loop.",{"type":51,"tag":520,"props":6590,"children":6592},{"id":6591},"_3-singleton-hierarchy-navigation-map",[6593],{"type":57,"value":6594},"3. Singleton Hierarchy (NAVIGATION MAP)",{"type":51,"tag":60,"props":6596,"children":6597},{},[6598],{"type":51,"tag":69,"props":6599,"children":6600},{},[6601],{"type":51,"tag":77,"props":6602,"children":6603},{"href":211},[6604],{"type":57,"value":211},{"type":51,"tag":60,"props":6606,"children":6607},{},[6608],{"type":57,"value":6609},"5-level deep navigation showing how to reach every feature.",{"type":51,"tag":5723,"props":6611,"children":6612},{},[],{"type":51,"tag":109,"props":6614,"children":6616},{"id":6615},"key-learnings",[6617],{"type":57,"value":6618},"Key Learnings",{"type":51,"tag":520,"props":6620,"children":6622},{"id":6621},"critical-discoveries",[6623],{"type":57,"value":6624},"Critical Discoveries:",{"type":51,"tag":124,"props":6626,"children":6627},{},[6628,6657,6686,6715,6749,6798,6895],{"type":51,"tag":128,"props":6629,"children":6630},{},[6631,6636],{"type":51,"tag":69,"props":6632,"children":6633},{},[6634],{"type":57,"value":6635},"Windows Message Loop is MANDATORY",{"type":51,"tag":200,"props":6637,"children":6638},{},[6639,6644,6649],{"type":51,"tag":128,"props":6640,"children":6641},{},[6642],{"type":57,"value":6643},"SDK uses Windows message pump for callbacks",{"type":51,"tag":128,"props":6645,"children":6646},{},[6647],{"type":57,"value":6648},"Without it, callbacks are queued but never fire",{"type":51,"tag":128,"props":6650,"children":6651},{},[6652,6653],{"type":57,"value":5555},{"type":51,"tag":77,"props":6654,"children":6655},{"href":164},[6656],{"type":57,"value":5560},{"type":51,"tag":128,"props":6658,"children":6659},{},[6660,6665],{"type":51,"tag":69,"props":6661,"children":6662},{},[6663],{"type":57,"value":6664},"Subscribe in onUserVideoStatusChanged, NOT onUserJoin",{"type":51,"tag":200,"props":6666,"children":6667},{},[6668,6673,6678],{"type":51,"tag":128,"props":6669,"children":6670},{},[6671],{"type":57,"value":6672},"Video may not be ready when user joins",{"type":51,"tag":128,"props":6674,"children":6675},{},[6676],{"type":57,"value":6677},"Wait for video status change callback",{"type":51,"tag":128,"props":6679,"children":6680},{},[6681,6682],{"type":57,"value":5555},{"type":51,"tag":77,"props":6683,"children":6684},{"href":185},[6685],{"type":57,"value":188},{"type":51,"tag":128,"props":6687,"children":6688},{},[6689,6694],{"type":51,"tag":69,"props":6690,"children":6691},{},[6692],{"type":57,"value":6693},"Two Rendering Paths",{"type":51,"tag":200,"props":6695,"children":6696},{},[6697,6702,6707],{"type":51,"tag":128,"props":6698,"children":6699},{},[6700],{"type":57,"value":6701},"Canvas API: SDK renders to your HWND (recommended)",{"type":51,"tag":128,"props":6703,"children":6704},{},[6705],{"type":57,"value":6706},"Raw Data Pipe: You receive YUV frames (advanced)",{"type":51,"tag":128,"props":6708,"children":6709},{},[6710,6711],{"type":57,"value":5555},{"type":51,"tag":77,"props":6712,"children":6713},{"href":362},[6714],{"type":57,"value":365},{"type":51,"tag":128,"props":6716,"children":6717},{},[6718,6723],{"type":51,"tag":69,"props":6719,"children":6720},{},[6721],{"type":57,"value":6722},"Helpers Control YOUR Streams Only",{"type":51,"tag":200,"props":6724,"children":6725},{},[6726,6736,6741],{"type":51,"tag":128,"props":6727,"children":6728},{},[6729,6734],{"type":51,"tag":327,"props":6730,"children":6732},{"className":6731},[],[6733],{"type":57,"value":4912},{"type":57,"value":6735}," starts YOUR camera",{"type":51,"tag":128,"props":6737,"children":6738},{},[6739],{"type":57,"value":6740},"To see others, subscribe to their Canvas\u002FPipe",{"type":51,"tag":128,"props":6742,"children":6743},{},[6744,6745],{"type":57,"value":5555},{"type":51,"tag":77,"props":6746,"children":6747},{"href":211},[6748],{"type":57,"value":214},{"type":51,"tag":128,"props":6750,"children":6751},{},[6752,6757],{"type":51,"tag":69,"props":6753,"children":6754},{},[6755],{"type":57,"value":6756},"UI Framework Integration Differs by Platform",{"type":51,"tag":200,"props":6758,"children":6759},{},[6760,6770,6780,6790],{"type":51,"tag":128,"props":6761,"children":6762},{},[6763,6768],{"type":51,"tag":69,"props":6764,"children":6765},{},[6766],{"type":57,"value":6767},"Win32",{"type":57,"value":6769},": Direct SDK, Canvas API (SDK renders to HWND) - best performance",{"type":51,"tag":128,"props":6771,"children":6772},{},[6773,6778],{"type":51,"tag":69,"props":6774,"children":6775},{},[6776],{"type":57,"value":6777},"WinForms",{"type":57,"value":6779},": C++\u002FCLI wrapper, Raw Data Pipe, YUV→Bitmap, InvokeRequired",{"type":51,"tag":128,"props":6781,"children":6782},{},[6783,6788],{"type":51,"tag":69,"props":6784,"children":6785},{},[6786],{"type":57,"value":6787},"WPF",{"type":57,"value":6789},": Same wrapper + Bitmap→BitmapSource, Dispatcher, Freeze()",{"type":51,"tag":128,"props":6791,"children":6792},{},[6793,6794],{"type":57,"value":5555},{"type":51,"tag":77,"props":6795,"children":6796},{"href":6396},[6797],{"type":57,"value":5225},{"type":51,"tag":128,"props":6799,"children":6800},{},[6801,6806],{"type":51,"tag":69,"props":6802,"children":6803},{},[6804],{"type":57,"value":6805},"C++\u002FCLI Wrapper Patterns (for ANY native library → .NET)",{"type":51,"tag":200,"props":6807,"children":6808},{},[6809,6820,6831,6851,6870,6881,6886],{"type":51,"tag":128,"props":6810,"children":6811},{},[6812,6818],{"type":51,"tag":327,"props":6813,"children":6815},{"className":6814},[],[6816],{"type":57,"value":6817},"void*",{"type":57,"value":6819}," pointers - hide native types from managed headers",{"type":51,"tag":128,"props":6821,"children":6822},{},[6823,6829],{"type":51,"tag":327,"props":6824,"children":6826},{"className":6825},[],[6827],{"type":57,"value":6828},"gcroot\u003CT^>",{"type":57,"value":6830}," - prevent GC from collecting managed references in native code",{"type":51,"tag":128,"props":6832,"children":6833},{},[6834,6836,6842,6843,6849],{"type":57,"value":6835},"Finalizer + Destructor - ",{"type":51,"tag":327,"props":6837,"children":6839},{"className":6838},[],[6840],{"type":57,"value":6841},"~Class()",{"type":57,"value":3530},{"type":51,"tag":327,"props":6844,"children":6846},{"className":6845},[],[6847],{"type":57,"value":6848},"!Class()",{"type":57,"value":6850}," for IDisposable cleanup",{"type":51,"tag":128,"props":6852,"children":6853},{},[6854,6860,6862,6868],{"type":51,"tag":327,"props":6855,"children":6857},{"className":6856},[],[6858],{"type":57,"value":6859},"pin_ptr",{"type":57,"value":6861}," + ",{"type":51,"tag":327,"props":6863,"children":6865},{"className":6864},[],[6866],{"type":57,"value":6867},"Marshal::Copy",{"type":57,"value":6869}," - array\u002Fbuffer conversion",{"type":51,"tag":128,"props":6871,"children":6872},{},[6873,6879],{"type":51,"tag":327,"props":6874,"children":6876},{"className":6875},[],[6877],{"type":57,"value":6878},"LockBits",{"type":57,"value":6880}," - 100x faster than SetPixel for image manipulation",{"type":51,"tag":128,"props":6882,"children":6883},{},[6884],{"type":57,"value":6885},"Thread marshaling - InvokeRequired (WinForms) \u002F Dispatcher (WPF)",{"type":51,"tag":128,"props":6887,"children":6888},{},[6889,6890],{"type":57,"value":5555},{"type":51,"tag":77,"props":6891,"children":6892},{"href":5302},[6893],{"type":57,"value":6894},"C++\u002FCLI Wrapper Guide",{"type":51,"tag":128,"props":6896,"children":6897},{},[6898,6903],{"type":51,"tag":69,"props":6899,"children":6900},{},[6901],{"type":57,"value":6902},"Audio Connection Timing",{"type":51,"tag":200,"props":6904,"children":6905},{},[6906,6918,6936],{"type":51,"tag":128,"props":6907,"children":6908},{},[6909,6911,6916],{"type":57,"value":6910},"Set ",{"type":51,"tag":327,"props":6912,"children":6914},{"className":6913},[],[6915],{"type":57,"value":1719},{"type":57,"value":6917}," during join",{"type":51,"tag":128,"props":6919,"children":6920},{},[6921,6922,6928,6929,6934],{"type":57,"value":4906},{"type":51,"tag":327,"props":6923,"children":6925},{"className":6924},[],[6926],{"type":57,"value":6927},"startAudio()",{"type":57,"value":4914},{"type":51,"tag":327,"props":6930,"children":6932},{"className":6931},[],[6933],{"type":57,"value":3560},{"type":57,"value":6935}," callback",{"type":51,"tag":128,"props":6937,"children":6938},{},[6939,6940],{"type":57,"value":5555},{"type":51,"tag":77,"props":6941,"children":6942},{"href":5279},[6943],{"type":57,"value":6302},{"type":51,"tag":5723,"props":6945,"children":6946},{},[],{"type":51,"tag":109,"props":6948,"children":6950},{"id":6949},"quick-reference",[6951],{"type":57,"value":6952},"Quick Reference",{"type":51,"tag":520,"props":6954,"children":6956},{"id":6955},"my-code-wont-compile",[6957],{"type":57,"value":6958},"\"My code won't compile\"",{"type":51,"tag":60,"props":6960,"children":6961},{},[6962,6964],{"type":57,"value":6963},"→ ",{"type":51,"tag":77,"props":6965,"children":6966},{"href":311},[6967],{"type":57,"value":314},{"type":51,"tag":520,"props":6969,"children":6971},{"id":6970},"callbacks-never-fire",[6972],{"type":57,"value":6973},"\"Callbacks never fire\"",{"type":51,"tag":60,"props":6975,"children":6976},{},[6977,6978],{"type":57,"value":6963},{"type":51,"tag":77,"props":6979,"children":6980},{"href":164},[6981],{"type":57,"value":167},{"type":51,"tag":520,"props":6983,"children":6985},{"id":6984},"video-subscription-returns-error-2",[6986],{"type":57,"value":6987},"\"Video subscription returns error 2\"",{"type":51,"tag":60,"props":6989,"children":6990},{},[6991,6992,6996],{"type":57,"value":6963},{"type":51,"tag":77,"props":6993,"children":6994},{"href":185},[6995],{"type":57,"value":188},{"type":57,"value":6997}," - Subscribe in onUserVideoStatusChanged",{"type":51,"tag":520,"props":6999,"children":7001},{"id":7000},"abstract-class-error",[7002],{"type":57,"value":7003},"\"Abstract class error\"",{"type":51,"tag":60,"props":7005,"children":7006},{},[7007,7008],{"type":57,"value":6963},{"type":51,"tag":77,"props":7009,"children":7010},{"href":238},[7011],{"type":57,"value":241},{"type":51,"tag":520,"props":7013,"children":7015},{"id":7014},"how-do-i-implement-feature",[7016,7018,7023],{"type":57,"value":7017},"\"How do I implement ",{"type":51,"tag":666,"props":7019,"children":7020},{},[7021],{"type":57,"value":7022},"feature",{"type":57,"value":7024},"?\"",{"type":51,"tag":60,"props":7026,"children":7027},{},[7028,7029],{"type":57,"value":6963},{"type":51,"tag":77,"props":7030,"children":7031},{"href":136},[7032],{"type":57,"value":139},{"type":51,"tag":520,"props":7034,"children":7036},{"id":7035},"how-do-i-navigate-to-controller",[7037,7039,7044],{"type":57,"value":7038},"\"How do I navigate to ",{"type":51,"tag":666,"props":7040,"children":7041},{},[7042],{"type":57,"value":7043},"controller",{"type":57,"value":7024},{"type":51,"tag":60,"props":7046,"children":7047},{},[7048,7049],{"type":57,"value":6963},{"type":51,"tag":77,"props":7050,"children":7051},{"href":211},[7052],{"type":57,"value":214},{"type":51,"tag":520,"props":7054,"children":7056},{"id":7055},"what-error-code-means-what",[7057],{"type":57,"value":7058},"\"What error code means what?\"",{"type":51,"tag":60,"props":7060,"children":7061},{},[7062,7063],{"type":57,"value":6963},{"type":51,"tag":77,"props":7064,"children":7065},{"href":342},[7066],{"type":57,"value":345},{"type":51,"tag":5723,"props":7068,"children":7069},{},[],{"type":51,"tag":109,"props":7071,"children":7073},{"id":7072},"document-version",[7074],{"type":57,"value":7075},"Document Version",{"type":51,"tag":60,"props":7077,"children":7078},{},[7079,7081],{"type":57,"value":7080},"Based on ",{"type":51,"tag":69,"props":7082,"children":7083},{},[7084],{"type":57,"value":7085},"Zoom Video SDK for Windows v2.x",{"type":51,"tag":5723,"props":7087,"children":7088},{},[],{"type":51,"tag":60,"props":7090,"children":7091},{},[7092],{"type":51,"tag":69,"props":7093,"children":7094},{},[7095],{"type":57,"value":7096},"Happy coding!",{"type":51,"tag":60,"props":7098,"children":7099},{},[7100,7102,7106],{"type":57,"value":7101},"Remember: The ",{"type":51,"tag":77,"props":7103,"children":7104},{"href":136},[7105],{"type":57,"value":139},{"type":57,"value":7107}," is your key to unlocking the entire SDK. Read it first!",{"type":51,"tag":109,"props":7109,"children":7111},{"id":7110},"operations",[7112],{"type":57,"value":7113},"Operations",{"type":51,"tag":200,"props":7115,"children":7116},{},[7117],{"type":51,"tag":128,"props":7118,"children":7119},{},[7120,7125],{"type":51,"tag":77,"props":7121,"children":7123},{"href":7122},"RUNBOOK.md",[7124],{"type":57,"value":7122},{"type":57,"value":7126}," - 5-minute preflight and debugging checklist.",{"type":51,"tag":7128,"props":7129,"children":7130},"style",{},[7131],{"type":57,"value":7132},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":7134,"total":7320},[7135,7156,7170,7182,7201,7214,7235,7255,7269,7284,7292,7305],{"slug":7136,"name":7136,"fn":7137,"description":7138,"org":7139,"tags":7140,"stars":7153,"repoUrl":7154,"updatedAt":7155},"algorithmic-art","create algorithmic art with p5.js","Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.",{"slug":9,"name":10,"logoUrl":11,"githubOrg":12},[7141,7144,7147,7150],{"name":7142,"slug":7143,"type":17},"Creative","creative",{"name":7145,"slug":7146,"type":17},"Design","design",{"name":7148,"slug":7149,"type":17},"Generative Art","generative-art",{"name":7151,"slug":7152,"type":17},"JavaScript","javascript",161831,"https:\u002F\u002Fgithub.com\u002Fanthropics\u002Fskills","2026-04-06T17:56:15.455818",{"slug":7157,"name":7157,"fn":7158,"description":7159,"org":7160,"tags":7161,"stars":7153,"repoUrl":7154,"updatedAt":7169},"brand-guidelines","apply Anthropic brand colors and typography","Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.",{"slug":9,"name":10,"logoUrl":11,"githubOrg":12},[7162,7165,7166],{"name":7163,"slug":7164,"type":17},"Branding","branding",{"name":7145,"slug":7146,"type":17},{"name":7167,"slug":7168,"type":17},"Typography","typography","2026-04-06T17:56:05.042852",{"slug":7171,"name":7171,"fn":7172,"description":7173,"org":7174,"tags":7175,"stars":7153,"repoUrl":7154,"updatedAt":7181},"canvas-design","create posters and visual art as PNG or PDF","Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations.",{"slug":9,"name":10,"logoUrl":11,"githubOrg":12},[7176,7177,7178],{"name":7142,"slug":7143,"type":17},{"name":7145,"slug":7146,"type":17},{"name":7179,"slug":7180,"type":17},"PDF","pdf","2026-04-06T17:56:03.794732",{"slug":7183,"name":7183,"fn":7184,"description":7185,"org":7186,"tags":7187,"stars":7153,"repoUrl":7154,"updatedAt":7200},"claude-api","build apps with the Claude API","Reference for the Claude API \u002F Anthropic SDK — model ids, pricing, params, streaming, tool use, MCP, agents, caching, token counting, model migration.\nTRIGGER — read BEFORE opening the target file; don't skip because it \"looks like a one-liner\" — whenever: the prompt names Claude\u002FAnthropic in any form (Claude, Anthropic, Fable, Opus, Sonnet, Haiku, `anthropic`, `@anthropic-ai`, `claude-*`, `us.anthropic.*`, `[1m]`); the user asks about an LLM (pricing\u002Fmodel choice\u002Flimits\u002Fcaching) — never answer from memory; OR the task is LLM-shaped with provider unstated (agent\u002FMCP\u002Ftool-definition\u002Fmulti-agent\u002FRAG\u002FLLM-judge\u002Fcomputer-use; generate\u002Fsummarize\u002Fextract\u002Fclassify\u002Frewrite\u002Fconverse over NL; debugging refusals\u002Fcutoffs\u002Fstreaming\u002Ftool-calls\u002Ftokens).\nSKIP only when another provider is being worked on (overrides all triggers): OpenAI\u002FGPT\u002FGemini\u002FLlama\u002FMistral\u002FCohere\u002FOllama named in the query; OR `grep -rE 'openai|langchain_openai|google.generativeai|genai|mistralai|cohere|ollama'` over the project hits (run this grep FIRST if no provider named — don't Read the file).",{"slug":9,"name":10,"logoUrl":11,"githubOrg":12},[7188,7191,7192,7195,7197],{"name":7189,"slug":7190,"type":17},"Agents","agents",{"name":10,"slug":9,"type":17},{"name":7193,"slug":7194,"type":17},"Anthropic SDK","anthropic-sdk",{"name":7196,"slug":7183,"type":17},"Claude API",{"name":7198,"slug":7199,"type":17},"LLM","llm","2026-07-28T05:36:08.213335",{"slug":7202,"name":7202,"fn":7203,"description":7204,"org":7205,"tags":7206,"stars":7153,"repoUrl":7154,"updatedAt":7213},"doc-coauthoring","co-author documentation and technical specs","Guide users through a structured workflow for co-authoring documentation. Use when user wants to write documentation, proposals, technical specs, decision docs, or similar structured content. This workflow helps users efficiently transfer context, refine content through iteration, and verify the doc works for readers. Trigger when user mentions writing docs, creating proposals, drafting specs, or similar documentation tasks.",{"slug":9,"name":10,"logoUrl":11,"githubOrg":12},[7207,7210],{"name":7208,"slug":7209,"type":17},"Documentation","documentation",{"name":7211,"slug":7212,"type":17},"Technical Writing","technical-writing","2026-04-06T17:56:14.18897",{"slug":7215,"name":7215,"fn":7216,"description":7217,"org":7218,"tags":7219,"stars":7153,"repoUrl":7154,"updatedAt":7234},"docx","create and edit Word documents","Use this skill whenever the user wants to create, read, edit, or manipulate Word documents (.docx files) or Word templates (.dotx files). Triggers include: any mention of 'Word doc', 'word document', '.docx', '.dotx', or requests to produce professional documents with formatting like tables of contents, headings, page numbers, or letterheads. Also use when extracting or reorganizing content from .docx or .dotx files, inserting or replacing images in documents, performing find-and-replace in Word files, working with tracked changes or comments, or converting content into a polished Word document. If the user asks for a 'report', 'memo', 'letter', 'template', or similar deliverable as a Word or .docx file, use this skill. Do NOT use for PDFs, spreadsheets, Google Docs, or general coding tasks unrelated to document generation.",{"slug":9,"name":10,"logoUrl":11,"githubOrg":12},[7220,7223,7225,7228,7231],{"name":7221,"slug":7222,"type":17},"Documents","documents",{"name":7224,"slug":7215,"type":17},"DOCX",{"name":7226,"slug":7227,"type":17},"Office","office",{"name":7229,"slug":7230,"type":17},"Templates","templates",{"name":7232,"slug":7233,"type":17},"Word","word","2026-07-18T05:16:23.136271",{"slug":7236,"name":7236,"fn":7237,"description":7238,"org":7239,"tags":7240,"stars":7153,"repoUrl":7154,"updatedAt":7254},"frontend-design","design production-grade frontend interfaces","Guidance for distinctive, intentional visual design when building new UI or reshaping an existing one. Helps with aesthetic direction, typography, and making choices that don't read as templated defaults.",{"slug":9,"name":10,"logoUrl":11,"githubOrg":12},[7241,7242,7245,7248,7251],{"name":7145,"slug":7146,"type":17},{"name":7243,"slug":7244,"type":17},"Frontend","frontend",{"name":7246,"slug":7247,"type":17},"React","react",{"name":7249,"slug":7250,"type":17},"Tailwind CSS","tailwind-css",{"name":7252,"slug":7253,"type":17},"UI Components","ui-components","2026-04-06T17:56:16.723469",{"slug":7256,"name":7256,"fn":7257,"description":7258,"org":7259,"tags":7260,"stars":7153,"repoUrl":7154,"updatedAt":7268},"internal-comms","write internal company communications","A set of resources to help me write all kinds of internal communications, using the formats that my company likes to use. Claude should use this skill whenever asked to write some sort of internal communications (status reports, leadership updates, 3P updates, company newsletters, FAQs, incident reports, project updates, etc.).",{"slug":9,"name":10,"logoUrl":11,"githubOrg":12},[7261,7264,7265],{"name":7262,"slug":7263,"type":17},"Communications","communications",{"name":7229,"slug":7230,"type":17},{"name":7266,"slug":7267,"type":17},"Writing","writing","2026-04-06T17:56:20.695522",{"slug":7270,"name":7270,"fn":7271,"description":7272,"org":7273,"tags":7274,"stars":7153,"repoUrl":7154,"updatedAt":7283},"mcp-builder","build MCP servers","Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node\u002FTypeScript (MCP SDK).",{"slug":9,"name":10,"logoUrl":11,"githubOrg":12},[7275,7276,7279,7280],{"name":7189,"slug":7190,"type":17},{"name":7277,"slug":7278,"type":17},"API Development","api-development",{"name":7198,"slug":7199,"type":17},{"name":7281,"slug":7282,"type":17},"MCP","mcp","2026-04-06T17:56:10.357665",{"slug":7180,"name":7180,"fn":7285,"description":7286,"org":7287,"tags":7288,"stars":7153,"repoUrl":7154,"updatedAt":7291},"read edit and manipulate PDF files","Use this skill whenever the user wants to do anything with PDF files. This includes reading or extracting text\u002Ftables from PDFs, combining or merging multiple PDFs into one, splitting PDFs apart, rotating pages, adding watermarks, creating new PDFs, filling PDF forms, encrypting\u002Fdecrypting PDFs, extracting images, and OCR on scanned PDFs to make them searchable. If the user mentions a .pdf file or asks to produce one, use this skill.",{"slug":9,"name":10,"logoUrl":11,"githubOrg":12},[7289,7290],{"name":7221,"slug":7222,"type":17},{"name":7179,"slug":7180,"type":17},"2026-04-06T17:56:02.483316",{"slug":7293,"name":7293,"fn":7294,"description":7295,"org":7296,"tags":7297,"stars":7153,"repoUrl":7154,"updatedAt":7304},"pptx","create and edit PowerPoint presentations","Use this skill any time a .pptx or .potx file is involved in any way — as input, output, or both. This includes: creating slide decks, pitch decks, or presentations; reading, parsing, or extracting text from any .pptx or .potx file (even if the extracted content will be used elsewhere, like in an email or summary); editing, modifying, or updating existing presentations; combining or splitting slide files; working with templates (.potx), layouts, speaker notes, or comments. Trigger whenever the user mentions \"deck,\" \"slides,\" \"presentation,\" or references a .pptx or .potx filename, regardless of what they plan to do with the content afterward. If a .pptx or .potx file needs to be opened, created, or touched, use this skill.",{"slug":9,"name":10,"logoUrl":11,"githubOrg":12},[7298,7301],{"name":7299,"slug":7300,"type":17},"PowerPoint","powerpoint",{"name":7302,"slug":7303,"type":17},"Presentations","presentations","2026-07-18T05:16:24.1471",{"slug":7306,"name":7306,"fn":7307,"description":7308,"org":7309,"tags":7310,"stars":7153,"repoUrl":7154,"updatedAt":7319},"skill-creator","create and optimize agent skills","Create new skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill from scratch, edit, or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy.",{"slug":9,"name":10,"logoUrl":11,"githubOrg":12},[7311,7312,7313,7316,7318],{"name":7189,"slug":7190,"type":17},{"name":7208,"slug":7209,"type":17},{"name":7314,"slug":7315,"type":17},"Evals","evals",{"name":3262,"slug":7317,"type":17},"performance",{"name":7211,"slug":7212,"type":17},"2026-04-19T06:45:40.804",490,{"items":7322,"total":7428},[7323,7337,7353,7369,7384,7403,7415],{"slug":7324,"name":7324,"fn":7325,"description":7326,"org":7327,"tags":7328,"stars":27,"repoUrl":28,"updatedAt":7336},"accessibility-review","run WCAG accessibility audits","Run a WCAG 2.1 AA accessibility audit on a design or page. Trigger with \"audit accessibility\", \"check a11y\", \"is this accessible?\", or when reviewing a design for color contrast, keyboard navigation, touch target size, or screen reader behavior before handoff.",{"slug":9,"name":10,"logoUrl":11,"githubOrg":12},[7329,7332,7333],{"name":7330,"slug":7331,"type":17},"Accessibility","accessibility",{"name":7145,"slug":7146,"type":17},{"name":7334,"slug":7335,"type":17},"WCAG","wcag","2026-04-06T17:58:05.682394",{"slug":7338,"name":7338,"fn":7339,"description":7340,"org":7341,"tags":7342,"stars":27,"repoUrl":28,"updatedAt":7352},"account-research","research accounts for sales intel","Research a company or person and get actionable sales intel. Works standalone with web search, supercharged when you connect enrichment tools or your CRM. Trigger with \"research [company]\", \"look up [person]\", \"intel on [prospect]\", \"who is [name] at [company]\", or \"tell me about [company]\".",{"slug":9,"name":10,"logoUrl":11,"githubOrg":12},[7343,7346,7349],{"name":7344,"slug":7345,"type":17},"CRM","crm",{"name":7347,"slug":7348,"type":17},"Research","research",{"name":7350,"slug":7351,"type":17},"Sales","sales","2026-04-06T17:56:41.410418",{"slug":7354,"name":7354,"fn":7355,"description":7356,"org":7357,"tags":7358,"stars":27,"repoUrl":28,"updatedAt":7368},"analyze","answer data questions and run analyses","Answer data questions -- from quick lookups to full analyses. Use when looking up a single metric, investigating what's driving a trend or drop, comparing segments over time, or preparing a formal data report for stakeholders.",{"slug":9,"name":10,"logoUrl":11,"githubOrg":12},[7359,7362,7365],{"name":7360,"slug":7361,"type":17},"Analytics","analytics",{"name":7363,"slug":7364,"type":17},"Data Analysis","data-analysis",{"name":7366,"slug":7367,"type":17},"SQL","sql","2026-04-06T17:57:21.593647",{"slug":7370,"name":7370,"fn":7371,"description":7372,"org":7373,"tags":7374,"stars":27,"repoUrl":28,"updatedAt":7383},"architecture","create and evaluate architecture decision records","Create or evaluate an architecture decision record (ADR). Use when choosing between technologies (e.g., Kafka vs SQS), documenting a design decision with trade-offs and consequences, reviewing a system design proposal, or designing a new component from requirements and constraints.",{"slug":9,"name":10,"logoUrl":11,"githubOrg":12},[7375,7378,7379,7380],{"name":7376,"slug":7377,"type":17},"ADR","adr",{"name":546,"slug":7370,"type":17},{"name":7208,"slug":7209,"type":17},{"name":7381,"slug":7382,"type":17},"Engineering","engineering","2026-04-06T17:57:49.26444",{"slug":7385,"name":7385,"fn":7386,"description":7387,"org":7388,"tags":7389,"stars":27,"repoUrl":28,"updatedAt":7402},"audit-support","support SOX 404 control testing","Support SOX 404 compliance with control testing methodology, sample selection, and documentation standards. Use when generating testing workpapers, selecting audit samples, classifying control deficiencies, or preparing for internal or external audits.",{"slug":9,"name":10,"logoUrl":11,"githubOrg":12},[7390,7393,7396,7399],{"name":7391,"slug":7392,"type":17},"Audit","audit",{"name":7394,"slug":7395,"type":17},"Finance","finance",{"name":7397,"slug":7398,"type":17},"Regulatory Compliance","regulatory-compliance",{"name":7400,"slug":7401,"type":17},"SOX","sox","2026-04-06T17:57:36.714815",{"slug":7404,"name":7404,"fn":7405,"description":7406,"org":7407,"tags":7408,"stars":27,"repoUrl":28,"updatedAt":7414},"brand-review","review content against brand voice","Review content against your brand voice, style guide, and messaging pillars, flagging deviations by severity with specific before\u002Fafter fixes. Use when checking a draft before it ships, when auditing copy for voice consistency and terminology, or when screening for unsubstantiated claims, missing disclaimers, and other legal flags.",{"slug":9,"name":10,"logoUrl":11,"githubOrg":12},[7409,7410,7413],{"name":7163,"slug":7164,"type":17},{"name":7411,"slug":7412,"type":17},"Marketing","marketing",{"name":7266,"slug":7267,"type":17},"2026-04-06T17:58:19.548331",{"slug":7416,"name":7416,"fn":7417,"description":7418,"org":7419,"tags":7420,"stars":27,"repoUrl":28,"updatedAt":7427},"brand-voice-enforcement","enforce brand voice in content","This skill applies brand guidelines to content creation. It should be used when the user asks to \"write an email\", \"draft a proposal\", \"create a pitch deck\", \"write a LinkedIn post\", \"draft a presentation\", \"write a Slack message\", \"draft sales content\", or any content creation request where brand voice should be applied. Also triggers on \"on-brand\", \"brand voice\", \"enforce voice\", \"apply brand guidelines\", \"brand-aligned content\", \"write in our voice\", \"use our brand tone\", \"make this sound like us\", \"rewrite this in our tone\", or \"this doesn't sound on-brand\". Not for generating guidelines from scratch (use guideline-generation) or discovering brand materials (use discover-brand).\n",{"slug":9,"name":10,"logoUrl":11,"githubOrg":12},[7421,7422,7423,7426],{"name":7163,"slug":7164,"type":17},{"name":7262,"slug":7263,"type":17},{"name":7424,"slug":7425,"type":17},"Content Creation","content-creation",{"name":7266,"slug":7267,"type":17},"2026-04-06T18:00:23.528956",200]