build-zoom-video-sdk-app
Reference skill for Zoom Video SDK. Use after routing to a custom-session workflow when the user needs full control over the video experience rather than an actual Zoom meeting.
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o build-zoom-video-sdk-app.zip https://jpskill.com/download/22709.zip && unzip -o build-zoom-video-sdk-app.zip && rm build-zoom-video-sdk-app.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/22709.zip -OutFile "$d\build-zoom-video-sdk-app.zip"; Expand-Archive "$d\build-zoom-video-sdk-app.zip" -DestinationPath $d -Force; ri "$d\build-zoom-video-sdk-app.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
build-zoom-video-sdk-app.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
build-zoom-video-sdk-appフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 10
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
[スキル名] build-zoom-video-sdk-app
完全にカスタムなビデオセッション製品のための背景リファレンスです。Meeting SDKとVideo SDKの境界がまだ不明確な場合は、まずplan-zoom-productを優先してください。
Zoomのインフラストラクチャを活用したカスタムビデオ体験を構築します。
ハードルーティングのガードレール(最初に読んでください)
- ユーザーがカスタムのリアルタイムビデオアプリの動作(トピック/セッションへの参加、カスタムレンダリング、アタッチ/デタッチ)を要求する場合は、Video SDKにルーティングしてください。
- Video SDKの参加フローでRESTミーティングエンドポイントに切り替えないでください。
- Video SDKはミーティングID、
join_url、またはMeeting SDKの参加ペイロードフィールド(meetingNumber、passWord)を使用しません。
Meeting SDK vs 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キーとシークレット
- 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() は join() の後にのみ機能します
const stream = client.getMediaStream();
await stream.startVideo();
await stream.startAudio();
CDNの使用(バンドラーなし)
警告: 広告ブロッカーは
source.zoom.usをブロックします。 問題を避けるためにSDKをセルフホストしてください。
# SDKをローカルにダウンロード
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はWebVideoSDKとしてエクスポートされ、ZoomVideoではありません
// .defaultプロパティを使用する必要があります
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() は join() の後にのみ機能します
const stream = client.getMediaStream();
await stream.startVideo();
await stream.startAudio();
CDNを使用したESモジュール(競合状態の修正)
CDNで<script type="module">を使用する場合、SDKがまだロードされていない可能性があります。
// 使用する前にSDKがロードされるのを待つ
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);
});
}
// 使用方法
await waitForSDK();
const ZoomVideo = WebVideoSDK.default;
const client = ZoomVideo.createClient();
SDKライフサイクル(重要な順序)
SDKには厳格なライフサイクルがあります。これに違反すると、サイレントな失敗が発生します。
1. クライアントの作成: client = ZoomVideo.createClient()
2. 初期化: await client.init('en-US', 'Global', options)
3. セッションへの参加: await client.join(topic, signature, userName, password)
4. ストリームの取得: stream = client.getMediaStream() ← 参加後のみ
5. メディアの開始: await stream.startVideo() / await stream.startAudio()
よくある間違い(サイレントな失敗):
// ❌ 間違い: 参加前にストリームを取得
const client = ZoomVideo.createClient();
await client.init('en-US', 'Global');
const stream = client.getMediaStream(); // undefinedを返します!
await client.join(...);
// ✅ 正しい: 参加後にストリームを取得
const client = ZoomVideo.createClient();
await client.init('en-US', 'Global');
await client.join(...);
const stream = client.getMediaStream(); // 動作します!
ビデオレンダリング(イベント駆動型)
SDKはイベント駆動型です。 イベントをリッスンし、それに応じてビデオをレンダリングする必要があります。
renderVideo()ではなくattachVideo()を使用してください
import { VideoQuality } from '@zoom/videosdk';
// カメラを起動
await stream.startVideo();
// ビデオをアタッチ - DOMに追加する要素を返します
const element = await stream.attachVideo(userId, VideoQuality.Video_360P);
container.appendChild(element);
// 完了したらデタッチ
await stream.detachVideo(userId);
必須イベント
// 他の参加者のビデオがオン/オフになったとき
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);
}
});
// 参加者が参加/退出したとき
client.on('user-added', (payload) => { /* bVideoOn を確認 */ });
client.on('user-removed', (payload) => { stream.detachVideo(payload.userId); });
完全なイベント処理パターンについては、web/references/web.mdを参照してください。
主要な概念
| 概念 | 説明 |
|---|---|
| Session | ビデオセッション(ミーティングではありません) |
| Topic | セッション識別子(任意の文字列を選択) |
| Signature | 認証用のJWT |
| MediaStream | オーディオ/ビデオストリーム制御 |
セッション作成モデル
重要
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
/build-zoom-video-sdk-app
Background reference for fully custom video-session products. Prefer plan-zoom-product first when the boundary between Meeting SDK and Video SDK is still unclear.
Build custom video experiences powered by Zoom's infrastructure.
Hard Routing Guardrail (Read First)
- If the user asks for custom real-time video app behavior (topic/session join, custom rendering, attach/detach), route to Video SDK.
- Do not switch to REST meeting endpoints for Video SDK join flows.
- Video SDK does not use Meeting IDs,
join_url, or Meeting SDK join payload fields (meetingNumber,passWord).
Meeting SDK vs Video SDK
| Feature | Meeting SDK | Video SDK |
|---|---|---|
| UI | Default Zoom UI or Custom UI | Fully custom UI (you build it) |
| Experience | Zoom meetings | Video sessions |
| Branding | Limited customization | Full branding control |
| Features | Full Zoom features | Core video features |
UI Options (Web)
Video SDK gives you full control over the UI:
| Option | Description |
|---|---|
| UI Toolkit | Pre-built React components (low-code) |
| Custom UI | Build your own UI using the SDK APIs |
Prerequisites
- Zoom Video SDK credentials from Marketplace
- SDK Key and Secret
- Web development environment
Need help with OAuth or signatures? See the zoom-oauth skill for authentication flows.
Need pre-join diagnostics on web? Use probe-sdk before Video SDK
join()to reduce first-minute failures.
Start troubleshooting fast: Use the 5-Minute Runbook before deep debugging.
Quick Start (Web)
NPM Usage (Bundler like 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 Usage (No Bundler)
WARNING: Ad blockers block
source.zoom.us. Self-host the SDK to avoid issues.
# 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();
ES Module with CDN (Race Condition Fix)
When using <script type="module"> with CDN, SDK may not be loaded yet:
// 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 Lifecycle (CRITICAL ORDER)
The SDK has a strict lifecycle. Violating it causes silent failures.
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()
Common Mistake (Silent Failure):
// ❌ 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!
Video Rendering (Event-Driven)
The SDK is event-driven. You must listen for events and render videos accordingly.
Use attachVideo() NOT 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);
Required Events
// 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); });
See web/references/web.md for complete event handling patterns.
Key Concepts
| Concept | Description |
|---|---|
| Session | Video session (not a meeting) |
| Topic | Session identifier (any string you choose) |
| Signature | JWT for authorization |
| MediaStream | Audio/video stream control |
Session Creation Model
Important: Video SDK sessions are created just-in-time, not in advance.
| Aspect | Video SDK | Meeting SDK |
|---|---|---|
| Pre-creation | NOT required | Create meeting via API first |
| Session start | First participant joins with topic | Join existing meeting ID |
| Topic | Any string (you define it) | Meeting ID from API |
| Scheduling | N/A - sessions are ad-hoc | Meetings can be scheduled |
How Sessions Work
- No pre-creation needed: Sessions don't exist until someone joins
- Topic = Session ID: Any participants joining with the same
topicstring join the same session - First join creates it: The session is created when the first participant joins
- No meeting ID: There's no numeric meeting ID like in Zoom Meetings
// 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');
Signature Endpoint Setup
The signature endpoint must be accessible from your frontend without CORS issues.
Option 1: Same-Origin Proxy (Recommended)
# 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', { ... });
Option 2: CORS Configuration
// Express.js backend
const cors = require('cors');
app.use(cors({
origin: ['https://your-domain.com'],
credentials: true
}));
WARNING: Mixed content (HTTPS page → HTTP API) will be blocked by browsers.
Use Cases
| Use Case | Description |
|---|---|
| Video SDK BYOS (Bring Your Own Storage) | Save recordings directly to your S3 bucket |
BYOS (Bring Your Own Storage)
Video SDK feature - Zoom saves cloud recordings directly to your Amazon S3 bucket. No downloading required.
Official docs: https://developers.zoom.us/docs/build/storage/
Prerequisites:
- Video SDK account with Cloud Recording add-on (Universal Credit includes this)
- AWS S3 bucket
Authentication options:
- AWS Access Key - simpler setup
- Cross Account Access - more secure (IAM role assumption)
S3 path structure:
Buckets/{bucketName}/cmr/byos/{YYYY}/{MM}/{DD}/{GUID}/cmr_byos/
Key benefits:
- Zero download bandwidth costs
- Direct storage during recording
- Config-only setup (no webhook/download code needed)
Setup location: Developer Portal → Account Settings → General → Communications Content Storage Location
See ../general/use-cases/video-sdk-bring-your-own-storage.md for complete setup guide.
Detailed References
UI & Components
- references/ui-toolkit.md - Pre-built UI components (Web)
- references/triage-intake.md - What to ask first (turn vague reports into answers)
- references/session-lifecycle.md - Correct API ordering + event-driven rendering
- references/licensing-and-entitlements.md - License/admin prerequisites
- references/token-contract-test-spec.md - Shared backend token contract and cross-platform smoke test
Platform Guides
- references/authorization.md - Video SDK JWT generation
- web/SKILL.md - Web Video SDK (JavaScript/TypeScript)
- web/SKILL.md - Complete documentation navigation
- web/examples/react-hooks.md - Official React hooks library
- web/examples/framework-integrations.md - Next.js, Vue/Nuxt patterns
- react-native/SKILL.md - React Native Video SDK (mobile wrapper, helper/event architecture)
- react-native/SKILL.md - React Native documentation navigation
- react-native/examples/session-join-pattern.md - Tokenized session join flow
- flutter/SKILL.md - Flutter Video SDK (mobile wrapper, event-driven architecture)
- flutter/SKILL.md - Flutter documentation navigation
- flutter/examples/session-join-pattern.md - Tokenized session join flow
- android/SKILL.md - Android Video SDK (native mobile custom UI, tokenized sessions)
- ios/SKILL.md - iOS Video SDK (native mobile custom UI, delegate-driven lifecycle)
- macos/SKILL.md - macOS Video SDK (desktop native apps, custom session windows)
- unity/SKILL.md - Unity Video SDK wrapper (game-engine integration, scene-driven UX)
- linux/SKILL.md - Linux Video SDK overview (C++ headless bots)
- linux/linux.md - Linux C++ SDK (headless bots, raw media capture/injection)
- linux/references/linux-reference.md - Linux API Reference
- windows/SKILL.md - Windows C++ SDK (desktop applications, raw media capture/injection)
- windows/references/windows-reference.md - Windows API Reference
- references/troubleshooting.md - Common issues and solutions
- references/forum-top-questions.md - Common forum question patterns (what to cover)
Sample Repositories
Official (by Zoom)
| Type | Repository | 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 | - |
Full list: See general/references/community-repos.md
Resources
- Official docs: https://developers.zoom.us/docs/video-sdk/
- Developer forum: https://devforum.zoom.us/
Environment Variables
- See references/environment-variables.md for standardized
.envkeys and where to find each value.
Linux Operations
- linux/RUNBOOK.md - Linux platform preflight and debugging checklist.
同梱ファイル
※ ZIPに含まれるファイル一覧。`SKILL.md` 本体に加え、参考資料・サンプル・スクリプトが入っている場合があります。
- 📄 SKILL.md (13,941 bytes)
- 📎 references/authorization.md (4,024 bytes)
- 📎 references/environment-variables.md (1,325 bytes)
- 📎 references/forum-top-questions.md (1,924 bytes)
- 📎 references/licensing-and-entitlements.md (760 bytes)
- 📎 references/session-lifecycle.md (959 bytes)
- 📎 references/token-contract-test-spec.md (1,606 bytes)
- 📎 references/triage-intake.md (1,226 bytes)
- 📎 references/troubleshooting.md (1,847 bytes)
- 📎 references/ui-toolkit.md (5,727 bytes)