/build-zoom-video-sdk-app
Référence en arrière-plan pour les produits de session vidéo entièrement personnalisés. Préférez d'abord plan-zoom-product quand la frontière entre Meeting SDK et Video SDK n'est pas encore claire.
Créez des expériences vidéo personnalisées alimentées par l'infrastructure Zoom.
Garde-fou de routage difficile (À lire en premier)
- Si l'utilisateur demande un comportement d'application vidéo en temps réel personnalisé (jointure de topic/session, rendu personnalisé, attachement/détachement), routez vers Video SDK.
- Ne basculez pas vers les endpoints REST meeting pour les flux de jointure Video SDK.
- Video SDK n'utilise pas les Meeting IDs,
join_url, ou les champs de payload de Meeting SDK (meetingNumber,passWord).
Meeting SDK vs Video SDK
| Fonctionnalité | Meeting SDK | Video SDK |
|---|---|---|
| UI | Zoom UI par défaut ou UI personnalisée | UI entièrement personnalisée (vous la construisez) |
| Expérience | Réunions Zoom | Sessions vidéo |
| Branding | Personnalisation limitée | Contrôle total du branding |
| Fonctionnalités | Toutes les fonctionnalités Zoom | Fonctionnalités vidéo essentielles |
Options d'UI (Web)
Video SDK vous donne le contrôle total de l'UI :
| Option | Description |
|---|---|
| UI Toolkit | Composants React pré-construits (low-code) |
| UI personnalisée | Construisez votre propre UI en utilisant les APIs SDK |
Prérequis
- Identifiants Zoom Video SDK depuis Marketplace
- SDK Key et Secret
- Environnement de développement web
Besoin d'aide avec OAuth ou les signatures ? Consultez la compétence zoom-oauth pour les flux d'authentification.
Besoin de diagnostics pré-jointure sur web ? Utilisez probe-sdk avant
join()Video SDK pour réduire les défaillances de première minute.
Commencez le dépannage rapidement : Utilisez le Runbook 5 minutes avant un débogage approfondi.
Démarrage rapide (Web)
Utilisation NPM (Bundler comme 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() FONCTIONNE UNIQUEMENT APRÈS join()
const stream = client.getMediaStream();
await stream.startVideo();
await stream.startAudio();
Utilisation CDN (Sans Bundler)
AVERTISSEMENT : Les bloqueurs de publicités bloquent
source.zoom.us. Auto-hébergez le SDK pour éviter les problèmes.
# Téléchargez le SDK localement
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 exporte en tant que WebVideoSDK, PAS ZoomVideo
// Doit utiliser la propriété .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() FONCTIONNE UNIQUEMENT APRÈS join()
const stream = client.getMediaStream();
await stream.startVideo();
await stream.startAudio();
Module ES avec CDN (Correction de condition de course)
Quand vous utilisez <script type="module"> avec CDN, le SDK peut ne pas être chargé :
// Attendez que le SDK se charge avant utilisation
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);
});
}
// Utilisation
await waitForSDK();
const ZoomVideo = WebVideoSDK.default;
const client = ZoomVideo.createClient();
Cycle de vie du SDK (ORDRE CRITIQUE)
Le SDK a un cycle de vie strict. Le violer provoque des défaillances silencieuses.
1. Créer le client : client = ZoomVideo.createClient()
2. Initialiser : await client.init('en-US', 'Global', options)
3. Joindre la session : await client.join(topic, signature, userName, password)
4. Obtenir le flux : stream = client.getMediaStream() ← UNIQUEMENT APRÈS JOIN
5. Démarrer le média : await stream.startVideo() / await stream.startAudio()
Erreur courante (Défaillance silencieuse) :
// ❌ INCORRECT : Obtenir le flux avant de joindre
const client = ZoomVideo.createClient();
await client.init('en-US', 'Global');
const stream = client.getMediaStream(); // Retourne undefined !
await client.join(...);
// ✅ CORRECT : Obtenir le flux après avoir joint
const client = ZoomVideo.createClient();
await client.init('en-US', 'Global');
await client.join(...);
const stream = client.getMediaStream(); // Fonctionne !
Rendu vidéo (Piloté par événements)
Le SDK est piloté par événements. Vous devez écouter les événements et effectuer le rendu des vidéos en conséquence.
Utilisez attachVideo() PAS renderVideo()
import { VideoQuality } from '@zoom/videosdk';
// Démarrez votre caméra
await stream.startVideo();
// Attacher la vidéo - retourne l'élément à ajouter au DOM
const element = await stream.attachVideo(userId, VideoQuality.Video_360P);
container.appendChild(element);
// Détacher quand terminer
await stream.detachVideo(userId);
Événements requis
// Quand la vidéo d'un autre participant s'allume/s'éteint
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);
}
});
// Quand les participants rejoignent/quittent
client.on('user-added', (payload) => { /* vérifier bVideoOn */ });
client.on('user-removed', (payload) => { stream.detachVideo(payload.userId); });
Voir web/references/web.md pour les modèles complets de gestion d'événements.
Concepts clés
| Concept | Description |
|---|---|
| Session | Session vidéo (pas une réunion) |
| Topic | Identifiant de session (toute chaîne de votre choix) |
| Signature | JWT pour l'autorisation |
| MediaStream | Contrôle du flux audio/vidéo |
Modèle de création de session
Important : Les sessions Video SDK sont créées à la demande, pas à l'avance.
| Aspect | Video SDK | Meeting SDK |
|---|---|---|
| Pré-création | NON requise | Créer la réunion via API en premier |
| Début de session | Le premier participant rejoint avec topic | Rejoindre le Meeting ID existant |
| Topic | Toute chaîne (vous la définissez) | Meeting ID depuis l'API |
| Planification | N/A - les sessions sont ad-hoc | Les réunions peuvent être planifiées |
Fonctionnement des sessions
- Aucune pré-création nécessaire : Les sessions n'existent pas jusqu'à ce que quelqu'un les rejoigne
- Topic = Session ID : Tout participant rejoignant avec la même chaîne
topicrejoint la même session - La première jointure la crée : La session est créée quand le premier participant la rejoint
- Pas de Meeting ID : Il n'y a pas de Meeting ID numérique comme dans Zoom Meetings
// La session est créée à la volée quand le premier utilisateur rejoint
// Toute chaîne peut être le topic - elle devient l'identifiant de session
await client.join('my-custom-session-123', signature, 'User Name');
// Les autres participants rejoignent la MÊME session en utilisant le MÊME topic
await client.join('my-custom-session-123', signature, 'Another User');
Configuration de l'endpoint de signature
L'endpoint de signature doit être accessible depuis votre frontend sans problèmes CORS.
Option 1 : Proxy de même origine (Recommandé)
# Configuration Nginx
location /api/ {
proxy_pass http://YOUR_BACKEND_HOST:3005/api/;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
// Frontend utilise URL relative (même origine)
const response = await fetch('/api/signature', { ... });
Option 2 : Configuration CORS
// Backend Express.js
const cors = require('cors');
app.use(cors({
origin: ['https://your-domain.com'],
credentials: true
}));
AVERTISSEMENT : Le contenu mixte (page HTTPS → API HTTP) sera bloqué par les navigateurs.
Cas d'usage
| Cas d'usage | Description |
|---|---|
| Video SDK BYOS (Apportez votre propre stockage) | Enregistrez directement dans votre bucket S3 |
BYOS (Apportez votre propre stockage)
Fonctionnalité Video SDK - Zoom enregistre les enregistrements cloud directement dans votre bucket Amazon S3. Aucun téléchargement requis.
Docs officielles : https://developers.zoom.us/docs/build/storage/
Prérequis :
- Compte Video SDK avec add-on Cloud Recording (Universal Credit inclut ceci)
- Bucket AWS S3
Options d'authentification :
- Clé d'accès AWS - configuration plus simple
- Accès entre comptes - plus sécurisé (assomption de rôle IAM)
Structure du chemin S3 :
Buckets/{bucketName}/cmr/byos/{YYYY}/{MM}/{DD}/{GUID}/cmr_byos/
Avantages clés :
- Zéro coût de bande passante de téléchargement
- Stockage direct pendant l'enregistrement
- Configuration uniquement (aucun code webhook/téléchargement nécessaire)
Lieu de configuration : Developer Portal → Account Settings → General → Communications Content Storage Location
Voir ../general/use-cases/video-sdk-bring-your-own-storage.md pour le guide de configuration complet.
Références détaillées
UI et composants
- references/ui-toolkit.md - Composants UI pré-construits (Web)
- references/triage-intake.md - Quoi demander en premier (transformer les rapports vagues en réponses)
- references/session-lifecycle.md - Ordre correct des API + rendu piloté par événements
- references/licensing-and-entitlements.md - Prérequis de licence/admin
- references/token-contract-test-spec.md - Contrat de token backend partagé et test de fumée multi-plateforme
Guides de plateforme
- references/authorization.md - Génération JWT Video SDK
- web/SKILL.md - Web Video SDK (JavaScript/TypeScript)
- web/SKILL.md - Navigation complète de la documentation
- web/examples/react-hooks.md - Bibliothèque officielle React hooks
- web/examples/framework-integrations.md - Modèles Next.js, Vue/Nuxt
- react-native/SKILL.md - React Native Video SDK (wrapper mobile, architecture helper/événement)
- react-native/SKILL.md - Navigation documentation React Native
- react-native/examples/session-join-pattern.md - Flux de jointure de session tokenisée
- flutter/SKILL.md - Flutter Video SDK (wrapper mobile, architecture piloté par événements)
- flutter/SKILL.md - Navigation documentation Flutter
- flutter/examples/session-join-pattern.md - Flux de jointure de session tokenisée
- android/SKILL.md - Android Video SDK (UI personnalisée mobile native, sessions tokenisées)
- ios/SKILL.md - iOS Video SDK (UI personnalisée mobile native, cycle de vie piloté par delegate)
- macos/SKILL.md - macOS Video SDK (applications desktop native, fenêtres de session personnalisées)
- unity/SKILL.md - Wrapper Unity Video SDK (intégration moteur de jeu, UX piloté par scène)
- linux/SKILL.md - Aperçu Linux Video SDK (bots headless C++)
- linux/linux.md - Linux C++ SDK (bots headless, capture/injection de médias bruts)
- linux/references/linux-reference.md - Référence API Linux
- windows/SKILL.md - Windows C++ SDK (applications desktop, capture/injection de médias bruts)
- windows/references/windows-reference.md - Référence API Windows
- references/troubleshooting.md - Problèmes courants et solutions
- references/forum-top-questions.md - Modèles de questions courantes du forum (quoi couvrir)
Référentiels d'exemple
Officiels (par Zoom)
| Type | Référentiel | Étoiles |
|---|---|---|
| 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 | - |
Liste complète : Voir general/references/community-repos.md
Ressources
- Docs officielles : https://developers.zoom.us/docs/video-sdk/
- Forum développeurs : https://devforum.zoom.us/
Variables d'environnement
- Voir references/environment-variables.md pour les clés
.envstandardisées et où trouver chaque valeur.
Opérations Linux
- linux/RUNBOOK.md - Checklist de préflight et débogage de plateforme Linux.