knowledge-work-plugins 之 Zoom Video SDK for Windows 官方示例应用完全指南:20 个 Sample 选型、代码模式与构建实战
2026/9/14 14:25:27 网站建设 项目流程

knowledge-work-plugins 之 Zoom Video SDK for Windows 官方示例应用完全指南:20 个 Sample 选型、代码模式与构建实战

【免费下载链接】knowledge-work-pluginsOpen source repository of plugins primarily intended for knowledge workers to use in Claude Cowork项目地址: https://gitcode.com/GitHub_Trending/kn/knowledge-work-plugins

本篇技术指南以 knowledge-work-plugins 仓库中 partner-built/zoom-plugin/skills/video-sdk/windows 技能库的官方示例参考文档为核心,系统讲解 Zoom Video SDK Windows 端(C++)官方示例工程的完整清单、推荐学习路径、关键代码模式与构建配置。读完本文,你将能够:根据业务需求(原始音视频采集、自定义音视频注入、云录制、信令、转写等)快速选定对应示例工程作为起点,理解贯穿所有示例的"单例获取 → 委托实现 → 订阅使用"通用架构,并掌握在 Visual Studio 中编译运行这些示例所需的全部前提与配置细节。


一、示例总览:20 个官方 Sample 一览

Zoom Video SDK Windows 官方示例仓库(videosdk-windows-rawdata-sample)提供了覆盖 SDK 主要能力的示例工程。下表汇总了全部示例的名称、功能定位与核心特性,是选型时的首要参考:

示例描述关键特性
VSDK_SkeletonDemo最小化会话加入最简单的入门起点
VSDK_getRawVideo采集原始视频YUV420 帧提取
VSDK_getRawAudio采集原始音频PCM 音频提取
VSDK_getRawShare采集屏幕共享共享内容捕获
VSDK_sendRawVideo发送自定义视频虚拟摄像头注入
VSDK_sendRawAudio发送自定义音频虚拟麦克风注入
VSDK_sendRawShare发送自定义共享自定义屏幕共享源
VSDK_CloudRecording云录制启停云端录制
VSDK_CommandChannel自定义消息收发自定义命令
VSDK_CallInPSTN 呼入电话拨入支持
VSDK_CalloutPSTN 呼出电话拨出支持
VSDK_ServiceQuality网络统计质量监控
VSDK_TranscriptionAndTranslation实时转写实时字幕
VSDK_MultiStreamVideo多路视频流多摄像头支持
VSDK_PreviewCameraAndMicrophone设备预览入会前设备测试
VSDK_Share2ndCameraAsMultiCam第二摄像头多摄像头共享
VSDK_Share2ndCameraAsShareScreenDemo摄像头作为共享摄像头内容共享
VSDK_ShareScreenPreprocessorDemo共享预处理自定义共享处理
VSDK_RTMSDemo实时消息RTMS 集成
VSDK_DuilibDemo2完整 UI 演示完整 GUI 应用

官方示例仓库与文档的链接信息可在技能库的 SKILL.md 与 windows.md 中查阅,本文聚焦于这些示例的本地化解读与代码模式。

从示例清单可以看出,官方示例覆盖了 SDK 的四大能力域:原始数据采集(Raw Data Capture)、原始数据注入(Raw Data Injection)、通信(Communication)与录制/流媒体/高级特性,下文第三节将按类别展开。


二、推荐学习路径:五个阶段吃透核心示例

官方建议的学习路径遵循"先跑通最小闭环,再逐项深入"的原则,与技能库中 concepts/sdk-architecture-pattern.md 所总结的"单例 → 委托 → 订阅"三段式架构一脉相承。

阶段 1:从 VSDK_SkeletonDemo 起步

这是代码量最小、最纯粹的会话加入示例,演示了以下 SDK 基础能力:

  • SDK 初始化(CreateZoomVideoSDKObj+initialize
  • JWT 鉴权(token字段)
  • 会话加入/离开(joinSession/leaveSession
  • Windows 消息循环(回调驱动的关键前提)
  • 基础委托实现(IZoomVideoSDKDelegate

需要掌握的核心模式:

// 1. 创建 SDK IZoomVideoSDK* sdk = CreateZoomVideoSDKObj(); // 2. 初始化 ZoomVideoSDKInitParams params; params.domain = L"https://zoom.us"; sdk->initialize(params); // 3. 添加委托 sdk->addListener(myDelegate); // 4. 加入会话 ZoomVideoSDKSessionContext ctx; ctx.sessionName = L"session"; ctx.token = L"jwt"; ctx.audioOption.connect = false; sdk->joinSession(ctx); // 5. 消息循环(关键!) while (running) { MSG msg; while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } Sleep(10); }

为什么消息循环"关键"?技能库中的 troubleshooting/windows-message-loop.md 明确指出:Zoom Video SDK 依赖 Windows 消息机制派发回调。事件发生时,SDK 将消息投递到调用joinSession()所在线程的消息队列;若没有PeekMessage/GetMessage驱动的消息循环,onSessionJoin()onError()等回调永远不会触发——表现为"joinSession()返回成功但无任何回调"。因此:

  • 消息循环必须与调用 SDK 方法的线程同一线程
  • 回调内禁止阻塞(不要sleep或忙等);
  • GUI 应用(WinMain 标准消息循环)天然满足,控制台/自定义主循环必须显式补充。

阶段 2:视频采集 VSDK_getRawVideo

该示例演示如何捕获远端用户的原始 YUV420 视频帧,包含:

  • IZoomVideoSDKRawDataPipeDelegate接口实现
  • onRawDataFrameReceived()回调
  • YUV 缓冲区提取(Y、U、V 三平面)
  • 分辨率与旋转角处理

核心模式:

class VideoCapture : public IZoomVideoSDKRawDataPipeDelegate { void onRawDataFrameReceived(YUVRawDataI420* data) override { int width =>void onMixedAudioRawDataReceived(AudioRawData* data) override { char* buffer =>// 初始化 SDK IZoomVideoSDK* sdk = CreateZoomVideoSDKObj(); ZoomVideoSDKInitParams params; params.domain = L"https://zoom.us"; params.videoRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap; sdk->initialize(params);

内存模式注意事项:技能库 SKILL.md 特别强调,原始数据的内存模式应始终使用堆模式(ZoomVideoSDKRawDataMemoryModeHeap),并同时为视频、共享、音频三路分别设置:

params.videoRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap; params.shareRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap; params.audioRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap;

堆模式(而非栈模式)可避免大尺寸视频帧导致的内存问题;此外还可通过params.enableLog = trueparams.logFilePrefix开启日志以辅助排查。

2. 委托注册

必须始终在加入会话之前注册委托

sdk->addListener(new MyDelegate()); sdk->joinSession(context);

若在joinSession()之后才调用addListener(),将错过早期事件(examples/session-join-pattern.md 中明确标注此为错误用法)。同时注意:IZoomVideoSDKDelegate拥有 70~80+ 个纯虚方法,全部必须实现(哪怕为空实现),否则会产生抽象类编译错误。

3. 音频连接策略

官方推荐"先入会、后连音频"的两段式:入会时设置audioOption.connect = false,在onSessionJoin()回调中再调用startAudio()

context.audioOption.connect = false; // 入会配置 void onSessionJoin() override { sdk->getAudioHelper()->startAudio(); // 在此连接 }

该策略分离了会话加入与音频初始化,可提高可靠性并便于错误处理。同理,自己的摄像头应在onSessionJoin中通过videoHelper->startVideo()开启。

4. 消息循环

所有示例都包含消息循环,这是回调触发的必要前提(前文已详述):

while (!g_exit) { MSG msg; while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } Sleep(10); }

五、构建与配置

前置条件

  1. Visual Studio 2019 或 2022(安装"使用 C++ 的桌面开发"工作负载,含 MSVC v142/v143 编译器与 Windows 10/11 SDK)
  2. Windows SDK 10.0.19041.0 及以上
  3. Zoom Video SDK(从 Zoom Marketplace 下载)

构建步骤

  1. 打开解决方案文件(.sln
  2. 将平台设置为x64
  3. 将配置设置为Release
  4. 生成解决方案(Ctrl+Shift+B)
  5. 将 SDK DLL 拷贝到输出目录

技能库 SKILL.md 补充了运行时环境的基线:Windows 10(1903 或更高)或 Windows 11,支持 x64(推荐)、x86 与 ARM64 架构;若使用 C#/.NET 应用,还需 .NET Framework 4.8 及以上与 C++/CLI 支持。

配置文件

每个示例通过config.json提供运行参数:

{ "jwt": "your-jwt-token", "session_name": "test-session", "password": "", "user_name": "Bot" }

在 examples/session-join-pattern.md 的完整实现中,LoadConfig()会读取该 JSON(使用 jsoncpp),将jwtsession_namepassworduser_name(默认"Bot")映射为全局宽字符串,再填入ZoomVideoSDKSessionContext完成入会。若文件无法打开或 SDK 初始化失败,程序会立即退出并返回错误码。


六、进阶深化:示例背后的 SDK 实现细节

理解示例代码后,可进一步结合技能库参考文档深入底层实现。

6.1 五层 API 层级与"导航式"访问

references/windows-reference.md 将 SDK 建模为五层深的单例对象树,所有功能都通过"导航"而非"构造"获取:

  • Level 1 入口CreateZoomVideoSDKObj() → IZoomVideoSDK*,提供initializejoinSessionaddListenergetVideoHelpergetAudioHelpergetShareHelpergetChatHelpergetCmdChannelgetRecordingHelper等入口;
  • Level 2 核心 Helper 与会话IZoomVideoSDKSessiongetMyselfgetRemoteUsers)、IZoomVideoSDKVideoHelper(仅控制自己的摄像头)、IZoomVideoSDKAudioHelperIZoomVideoSDKShareHelper
  • Level 3 用户与渲染对象IZoomVideoSDKUserGetVideoCanvasGetVideoPipegetVideoStatus)、IZoomVideoSDKCanvas(SDK 渲染)、IZoomVideoSDKRawDataPipe(原始 YUV)、IZoomVideoSDKShareAction(共享控制);
  • Level 4 设备/聊天/回调IZoomVideoSDKCameraDeviceIZoomVideoSDKChatHelperIZoomVideoSDKRawDataPipeDelegate
  • Level 5 原始数据与工具YUVRawDataI420AudioRawDataIZoomVideoSDKUserHelperIZoomVideoSDKCmdChannel等。

关键区分VideoHelper/AudioHelper只控制自己的音视频流(startVideo()开启自己的摄像头);观看远端参会人的视频,必须通过其user->GetVideoCanvas()->subscribeWithView(hwnd, aspect, resolution)user->GetVideoPipe()->subscribe(resolution, delegate)订阅。屏幕共享则更特殊:远端共享必须使用onUserShareStatusChanged回调中的IZoomVideoSDKShareAction(而非user->GetShareCanvas()),因为一个用户可能同时存在多个共享流。

6.2 两种渲染/处理路线:Canvas API 与 Raw Data Pipe

路线接口适用场景
Canvas APIIZoomVideoSDKCanvas::subscribeWithView(HWND)标准应用、画质最佳、实现最简单
Raw Data PipeIZoomVideoSDKRawDataPipe::subscribe(delegate)自定义处理、特效、录制、计算机视觉

Canvas API 由 SDK 直接渲染到窗口句柄,无需 YUV 转换,支持ZoomVideoSDKVideoAspect_Original / FullFilled / PanAndScan / LetterBox等纵横比与ZoomVideoSDKResolution_90P / 180P / 360P / 720P / 1080P / Auto等分辨率选项;Raw Data Pipe 则向委托回调交付YUVRawDataI420帧,交由应用自行转换渲染(GDI/DirectX/OpenGL 均可)。

6.3 原始视频处理的进阶要点(对应 VSDK_getRawVideo)

examples/raw-video-capture.md 给出了 YUV420(I420 平面)的内存布局:Y 平面为全分辨率(width × height字节),U/V 平面各为四分之一分辨率((width/2) × (height/2)字节),单帧总大小为width × height × 1.5字节:

分辨率Y 缓冲区U 缓冲区V 缓冲区总计
720p(1280×720)921,600230,400230,4001,382,400
1080p(1920×1080)2,073,600518,400518,4003,110,400
360p(640×360)230,40057,60057,600345,600

YUVRawDataI420的主要方法包括GetYBuffer/GetUBuffer/GetVBuffer(三平面指针)、GetStreamWidth/GetStreamHeight(帧尺寸)、GetRotation(0/90/180/270)、GetTimeStamp(时间戳)以及CanAddRef/AddRef/Release(引用计数,用于跨回调异步处理)。采集到的.yuv文件可用 FFplay 回放或 FFmpeg 转码:

ffplay -video_size 1280x720 -pixel_format yuv420p -f rawvideo video.yuv ffmpeg -video_size 1280x720 -pixel_format yuv420p -framerate 30 -f rawvideo -i video.yuv -c:v libx264 output.mp4

性能优化建议:预分配 RGB 缓冲区(仅尺寸变化时重分配);回调内使用AddRef()将帧投递到独立处理线程,处理完Release();AI 处理订阅低分辨率(ZoomVideoSDKResolution_360P),显示则用高分辨率 Canvas。

6.4 原始音频采集格式(对应 VSDK_getRawAudio)

examples/raw-audio-capture.md 明确音频格式为:PCM 未压缩、32000 Hz、16-bit 有符号、单声道或双声道、小端序,每次回调约 640~1280 字节(20~40ms 音频)。三种回调分别对应:

  • onMixedAudioRawDataReceived:全体参会人混合音频,适合整场录制;
  • onOneWayAudioRawDataReceived:逐用户音频(需特殊配置),适合按发言人转写;
  • onSharedAudioRawDataReceived:屏幕共享内容音频,与参会人音频分离。

AudioRawData提供GetBuffer()(PCM 缓冲区)、GetBufferLen()(字节数)、GetSampleRate()(通常 32000)与GetChannelNum()(1=单声道,2=双声道)。采集到的.pcm可用 FFplay 回放或转为 WAV:

ffplay -f s16le -ar 32000 -ac 1 audio.pcm ffmpeg -f s16le -ar 32000 -ac 1 -i audio.pcm output.wav

常见坑位:音频回调不触发(未在onSessionJoin连接音频)、FFmpeg 中错误使用 44100 Hz、静音(无人发言或全员静音,需检查onUserAudioStatusChanged)。

6.5 订阅时机与错误码(调试示例的关键依据)

references/windows-reference.md 强调两条时序铁律

  1. 不要在onUserJoin中订阅视频——此时视频可能尚未就绪,会触发 Error 2(Internal_Error)。正确做法是在onUserVideoStatusChanged中检查pipe->getVideoStatus().isOn为真后再订阅,并跳过自己(if (user == myself) continue;);
  2. 订阅过快会触发ZoomVideoSDKSubscribeFailReason_TooFrequentCall(=6),处理方式是在相邻订阅调用之间插入Sleep(200)

常用错误码速查:0 Success1 Wrong_Usage(错误状态调用)、2 Internal_Error(视频未就绪/过早订阅)、7 Invalid_Parameter(NULL 指针、非法 HWND)、8 Call_Too_Frequently(调用过于频繁)。

6.6 线程安全与生命周期

SDK 回调运行在 SDK 线程而非主线程:不要在回调中执行重操作、不要在回调中调用cleanup()、跨线程传递数据使用线程安全队列(如YUVRawDataI420的引用计数配合生产者-消费者队列)并加锁保护共享状态。退会时统一在onUserLeave/onSessionLeave中解除订阅并清理,最后按leaveSession(false)cleanup()DestroyZoomVideoSDKObj()的顺序释放。


七、相关文档导航

本文对应的示例参考文档位于 references/samples.md,技能库中与之配套的深度资料还包括:

  • SDK 架构模式:贯穿所有功能的"单例 → 委托 → 订阅"万能三段式
  • 会话加入模式:完整的 JWT 鉴权 + 入会代码(含main.cppconfig.json
  • 原始视频采集:YUV 捕获完整实现与 FFmpeg 处理
  • 原始音频采集:PCM 捕获完整实现与 FFplay 处理
  • 发送原始视频 / 发送原始音频:虚拟摄像头/虚拟麦克风注入实现
  • API 参考:五层 API 层级、方法签名、错误码与时序规则
  • 委托方法:全部回调方法
  • Windows 消息循环:回调不触发的第一排查项
  • 常见问题:快速诊断清单

行动建议:以VSDK_SkeletonDemo打通"初始化 → 委托 → 入会 → 消息循环"的最小闭环,再根据业务诉求选择VSDK_getRawVideoVSDK_getRawAudio切入原始数据采集;若需要向会话注入内容,则对应研读VSDK_sendRawVideo(虚拟摄像头)与VSDK_sendRawAudio(虚拟麦克风)。任何示例运行异常,优先检查消息循环是否存在、委托是否在入会前注册、订阅是否发生在视频就绪之后。

【免费下载链接】knowledge-work-pluginsOpen source repository of plugins primarily intended for knowledge workers to use in Claude Cowork项目地址: https://gitcode.com/GitHub_Trending/kn/knowledge-work-plugins

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询