关于 build-zoom-video-sdk-app
为开发 Zoom Video SDK 自定义视频体验提供参考的技能,面向构建视频会话应用的开发者。涵盖平台实现、会话生命周期、渲染和存储配置,并强调 Video SDK 与 Meeting SDK 的区别。
主要功能
- 01自定义视频会话构建指南
- 02Web UI Toolkit 与自定义 UI
- 03跨平台 SDK 参考
- 04会话生命周期与事件处理
- 05BYOS 录制存储指南
适用场景
- 01规划自定义品牌的视频会话界面
- 02实现 Web 或移动端会话加入与媒体渲染
- 03将云录制直接保存到 Amazon S3
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ anthropics/ knowledge-work-plugins --skill build-zoom-video-sdk-app安装后在 Claude Code 中输入/build-zoom-video-sdk-app确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
android/android.mdRUNBOOK.mdandroid/concepts/architecture.mdlifecycle-workflow.mdandroid/examples/session-join-pattern.mdandroid/references/android-reference-map.mdenvironment-variables.mdversioning-and-compatibility.mdandroid/scenarios/high-level-scenarios.mdandroid/troubleshooting/common-issues.mdflutter/RUNBOOK.mdflutter/concepts/high-level-scenarios.mdlifecycle-workflow.mdsdk-architecture-pattern.mdflutter/examples/event-handling-pattern.mdsession-join-pattern.mdsetup-guide.mdflutter/references/flutter-reference.mdmodule-map.mdofficial-sources.mdflutter/troubleshooting/common-issues.mddeprecated-and-contradictions.mdversion-drift.mdios/ios.mdios/concepts/architecture.mdlifecycle-workflow.mdios/examples/session-join-pattern.mdios/references/environment-variables.mdios-reference-map.mdversioning-and-compatibility.md详细介绍
/build-zoom-video-sdk-app
完全自定义视频会话产品的背景参考。如果 Meeting SDK 与 Video SDK 之间的边界仍不清楚,请优先使用 plan-zoom-product。
构建由 Zoom 基础设施驱动的自定义视频体验。
硬性路由规则(请先阅读)
- 如果用户需要自定义实时视频应用行为(主题/会话加入、自定义渲染、attach/detach),请路由到 Video SDK。
- 不要为 Video SDK 的加入流程切换到 REST 会议端点。
- Video SDK 不使用会议 ID、
join_url或 Meeting SDK 的加入载荷字段(meetingNumber、passWord)。
Meeting SDK 与 Video SDK
| 功能 | Meeting SDK | Video SDK |
|---|---|---|
| UI | 默认 Zoom UI 或自定义 UI | 完全自定义 UI(由你构建) |
| 体验 | Zoom 会议 | 视频会话 |
| 品牌化 | 定制能力有限 | 完整的品牌控制 |
| 功能 | 完整的 Zoom 功能 | 核心视频功能 |
UI 选项(Web)
Video SDK 让你完全控制 UI:
| 选项 | 描述 |
|---|---|
| UI Toolkit | 预构建的 React 组件(低代码) |
| Custom UI | 使用 SDK API 构建你自己的 UI |
前提条件
- 来自 Marketplace 的 Zoom Video SDK 凭证
- SDK Key 和 Secret
- Web 开发环境
需要 OAuth 或签名方面的帮助? 请参阅 zoom-oauth 技能了解身份验证流程。
需要 Web 端加入前诊断? 在调用 Video SDK
join()之前使用 probe-sdk,以减少前一分钟的失败。
快速开始排查问题: 在深入调试之前,请使用 5 分钟排查手册。
快速开始(Web)
NPM 用法(Vite/Webpack 等打包工具)
import ZoomVideo from '@zoom/videosdk';
const client = ZoomVideo.createClient();
await client.init('en-US', 'Global', { patchJsMedia: true });
await client.join(topic, signature, userName, password);
// IMPORTANT: getMediaStream() ONLY works AFTER join()
const stream = client.getMediaStream();
await stream.startVideo();
await stream.startAudio();
CDN 用法(无打包工具)
警告:广告拦截器会拦截
source.zoom.us。请自行托管 SDK 以避免问题。
# Download SDK locally
curl "https://source.zoom.us/videosdk/zoom-video-1.12.0.min.js" -o js/zoom-video-sdk.min.js
<script src="js/zoom-video-sdk.min.js"></script>
// CDN exports as WebVideoSDK, NOT ZoomVideo
// Must use .default property
const ZoomVideo = WebVideoSDK.default;
const client = ZoomVideo.createClient();
await client.init('en-US', 'Global', { patchJsMedia: true });
await client.join(topic, signature, userName, password);
// IMPORTANT: getMediaStream() ONLY works AFTER join()
const stream = client.getMediaStream();
await stream.startVideo();
await stream.startAudio();
使用 CDN 的 ES Module(竞态条件修复)
在 CDN 中使用 <script type="module"> 时,SDK 可能尚未加载完成:
// Wait for SDK to load before using
function waitForSDK(timeout = 10000) {
return new Promise((resolve, reject) => {
if (typeof WebVideoSDK !== 'undefined') {
resolve();
return;
}
const start = Date.now();
const check = setInterval(() => {
if (typeof WebVideoSDK !== 'undefined') {
clearInterval(check);
resolve();
} else if (Date.now() - start > timeout) {
clearInterval(check);
reject(new Error('SDK failed to load'));
}
}, 100);
});
}
// Usage
await waitForSDK();
const ZoomVideo = WebVideoSDK.default;
const client = ZoomVideo.createClient();
SDK 生命周期(关键顺序)
SDK 具有严格的生命周期。违反它会导致静默失败。
1. Create client: client = ZoomVideo.createClient()
2. Initialize: await client.init('en-US', 'Global', options)
3. Join session: await client.join(topic, signature, userName, password)
4. Get stream: stream = client.getMediaStream() ← ONLY AFTER JOIN
5. Start media: await stream.startVideo() / await stream.startAudio()
常见错误(静默失败):
// ❌ WRONG: Getting stream before joining
const client = ZoomVideo.createClient();
await client.init('en-US', 'Global');
const stream = client.getMediaStream(); // Returns undefined!
await client.join(...);
// ✅ CORRECT: Get stream after joining
const client = ZoomVideo.createClient();
await client.init('en-US', 'Global');
await client.join(...);
const stream = client.getMediaStream(); // Works!
视频渲染(事件驱动)
SDK 是事件驱动的。 你必须监听事件并据此渲染视频。
使用 attachVideo() 而非 renderVideo()
import { VideoQuality } from '@zoom/videosdk';
// Start your camera
await stream.startVideo();
// Attach video - returns element to append to DOM
const element = await stream.attachVideo(userId, VideoQuality.Video_360P);
container.appendChild(element);
// Detach when done
await stream.detachVideo(userId);
必需事件
// When other participant's video turns on/off
client.on('peer-video-state-change', async (payload) => {
const { action, userId } = payload;
if (action === 'Start') {
const el = await stream.attachVideo(userId, VideoQuality.Video_360P);
container.appendChild(el);
} else {
await stream.detachVideo(userId);
}
});
// When participants join/leave
client.on('user-added', (payload) => { /* check bVideoOn */ });
client.on('user-removed', (payload) => { stream.detachVideo(payload.userId); });
完整的事件处理模式请参阅 web/references/web.md。
核心概念
| 概念 | 描述 |
|---|---|
| Session | 视频会话(不是会议) |
| Topic | 会话标识符(你可以选择任意字符串) |
| Signature | 用于授权的 JWT |
| MediaStream | 音视频流控制 |
会话创建模型
重要:Video SDK 会话是即时创建的,而不是预先创建。
| 方面 | Video SDK | Meeting SDK |
|---|---|---|
| 预先创建 | 不需要 | 需要先通过 API 创建会议 |
| 会话启动 | 第一位参与者使用 topic 加入 | 加入已有的会议 ID |
| Topic | 任意字符串(由你定义) | 来自 API 的会议 ID |
| 排期 | 不适用 - 会话是临时的 | 会议可以预约排期 |
会话的工作方式
- 无需预先创建:在有人加入之前,会话并不存在
- Topic 即会话 ID:使用相同
topic字符串加入的参与者会进入同一个会话 - 首次加入即创建:当第一位参与者加入时创建会话
- 没有会议 ID:不存在 Zoom Meetings 中那样的数字会议 ID
// Session is created on-the-fly when first user joins
// Any string can be the topic - it becomes the session identifier
await client.join('my-custom-session-123', signature, 'User Name');
// Other participants join the SAME session by using the SAME topic
await client.join('my-custom-session-123', signature, 'Another User');
签名端点设置
签名端点必须可以从你的前端访问,且不能出现 CORS 问题。
选项 1:同源代理(推荐)
# Nginx config
location /api/ {
proxy_pass http://YOUR_BACKEND_HOST:3005/api/;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
// Frontend uses relative URL (same origin)
const response = await fetch('/api/signature', { ... });
选项 2:CORS 配置
// Express.js backend
const cors = require('cors');
app.use(cors({
origin: ['https://your-domain.com'],
credentials: true
}));
警告: 混合内容(HTTPS 页面 → HTTP API)会被浏览器拦截。
使用场景
| 使用场景 | 描述 |
|---|---|
| Video SDK BYOS(自带存储) | 将录制内容直接保存到你的 S3 存储桶 |
BYOS(自带存储)
Video SDK 功能:Zoom 会将云端录制内容直接保存到你的 Amazon S3 存储桶,无需下载。
前提条件:
- 拥有 Cloud Recording 附加项的 Video SDK 账户(Universal Credit 已包含该项)
- AWS S3 存储桶
认证方式:
- AWS Access Key:设置更简单
- Cross Account Access:更安全(通过 IAM 角色扮演)
S3 路径结构:
Buckets/{bucketName}/cmr/byos/{YYYY}/{MM}/{DD}/{GUID}/cmr_byos/
主要优势:
- 零下载带宽成本
- 录制过程中直接存储
- 仅需配置即可完成设置(无需 webhook 或下载代码)
设置位置: Developer Portal → Account Settings → General → Communications Content Storage Location
完整设置指南请参阅 ../general/use-cases/video-sdk-bring-your-own-storage.md。
详细参考
UI 与组件
- references/ui-toolkit.md:预构建的 UI 组件(Web)
- references/triage-intake.md:首先需要询问的内容(将模糊的问题报告转化为可回答的问题)
- references/session-lifecycle.md:正确的 API 调用顺序与事件驱动渲染
- references/licensing-and-entitlements.md:许可证与管理员前提条件
- references/token-contract-test-spec.md:共享的后端 token 契约与跨平台冒烟测试
平台指南
- references/authorization.md - Video SDK JWT 生成
- web/SKILL.md - Web Video SDK(JavaScript/TypeScript)
- web/SKILL.md - 完整文档导航
- web/examples/react-hooks.md - 官方 React hooks 库
- web/examples/framework-integrations.md - Next.js、Vue/Nuxt 模式
- react-native/SKILL.md - React Native Video SDK(移动端封装,helper/事件架构)
- react-native/SKILL.md - React Native 文档导航
- react-native/examples/session-join-pattern.md - 基于令牌的会话加入流程
- flutter/SKILL.md - Flutter Video SDK(移动端封装,事件驱动架构)
- flutter/SKILL.md - Flutter 文档导航
- flutter/examples/session-join-pattern.md - 基于令牌的会话加入流程
- android/SKILL.md - Android Video SDK(原生移动端自定义 UI,基于令牌的会话)
- ios/SKILL.md - iOS Video SDK(原生移动端自定义 UI,delegate 驱动的生命周期)
- macos/SKILL.md - macOS Video SDK(桌面原生应用,自定义会话窗口)
- unity/SKILL.md - Unity Video SDK 封装(游戏引擎集成,场景驱动的用户体验)
- linux/SKILL.md - Linux Video SDK 概述(C++ 无头机器人)
- linux/linux.md - Linux C++ SDK(无头机器人,原始媒体采集/注入)
- linux/references/linux-reference.md - Linux API 参考
- windows/SKILL.md - Windows C++ SDK(桌面应用,原始媒体采集/注入)
- windows/references/windows-reference.md - Windows API 参考
- references/troubleshooting.md - 常见问题与解决方案
- references/forum-top-questions.md - 论坛常见问题模式(应覆盖的内容)
示例仓库
官方(由 Zoom 提供)
| 类型 | 仓库 | Stars |
|---|---|---|
| Web | videosdk-web-sample | 137 |
| Web NPM | videosdk-web | 56 |
| Auth | videosdk-auth-endpoint-sample | 23 |
| UI Toolkit Web | videosdk-zoom-ui-toolkit-web | 17 |
| UI Toolkit React | videosdk-zoom-ui-toolkit-react-sample | 17 |
| Next.js | videosdk-nextjs-quickstart | 16 |
| Telehealth | VideoSDK-Web-Telehealth | 11 |
| Linux | videosdk-linux-raw-recording-sample | - |
完整列表:参见 general/references/community-repos.md
资源
环境变量
- 标准化
.env键及各值的获取位置,参见 references/environment-variables.md。
Linux 操作
- linux/RUNBOOK.md - Linux 平台预检与调试清单。