build-zoom-video-sdk-app

Par anthropics · knowledge-work-plugins

Skill de référence pour le Zoom Video SDK. À utiliser après le routage vers un workflow de session personnalisée, lorsque l'utilisateur a besoin d'un contrôle total sur l'expérience vidéo plutôt qu'une réunion Zoom classique.

npx skills add https://github.com/anthropics/knowledge-work-plugins --skill build-zoom-video-sdk-app

/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

  1. Aucune pré-création nécessaire : Les sessions n'existent pas jusqu'à ce que quelqu'un les rejoigne
  2. Topic = Session ID : Tout participant rejoignant avec la même chaîne topic rejoint la même session
  3. La première jointure la crée : La session est créée quand le premier participant la rejoint
  4. 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 :

  1. Clé d'accès AWS - configuration plus simple
  2. 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

Guides de plateforme

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

Variables d'environnement

Opérations Linux

Skills similaires