Setting the file. One moment.
Subchapter 149.13
examples/session-join-pattern.mdMarkdown10 KBView on GitHub
Complete working example for joining a Zoom Video SDK session.
import ZoomVideo, { VideoQuality } from '@zoom/videosdk';
// State
let client = null;
let stream = null;
// Configuration
const config = {
language: 'en-US',
dependentAssets: 'Global', // or 'CDN', 'CN', or custom path
options: {
patchJsMedia: true,
// webrtc: true, // Enable for HD video
}
};
<!DOCTYPE html>
<html>
<head>
<title>Zoom Video SDK</title>
<!-- Some environments/ad blockers may block source.zoom.us. Allowlist or use a permitted fallback strategy. -->
<script src="js/zoom-video-sdk.min.js"></script>
</head>
<body>
<div id="my-video"></div>
<div id="participants"></div>
<script>
// CDN exports as WebVideoSDK.default
const ZoomVideo = WebVideoSDK.default;
const client = ZoomVideo.createClient();
let stream;
async function init() {
await client.init('en-US', 'Global', { patchJsMedia: true });
await client.join('topic', 'JWT', 'User');
stream = client.getMediaStream();
// Set up events and start media
// ... (same as NPM version)
}
init();
</script>
</body>
</html>import React, { useEffect, useRef, useState } from 'react';
import ZoomVideo, { VideoClient, Stream, VideoQuality } from '@zoom/videosdk';
interface Props {
topic: string;
signature: string;
userName: string;
}
export const VideoSession: React.FC<Props> = ({ topic, signature, userName }) => {
const [client, setClient] = useState<typeof VideoClient | null>(null);
const [stream, setStream] = useState<typeof Stream | null>(null);
const [isJoined, setIsJoined] = useState(false);
const videoContainerRef = useRef<HTMLDivElement>(null);
// Initialize SDK
useEffect(() => {
const init = async () => {
const zmClient = ZoomVideo.createClient();
await zmClient.init('en-US', 'Global', { patchJsMedia: true });
setClient(zmClient);
};
init();
return () => {
ZoomVideo.destroyClient();
};
}, []);
// Join session
useEffect(() => {
if (!client || isJoined) return;
const join = async () => {
await client.join(topic, signature, userName);
const mediaStream = client.getMediaStream();
setStream(mediaStream);
setIsJoined(true);
};
join();
}, [client, topic, signature, userName, isJoined]);
// Set up event listeners
useEffect(() => {
if (!client || !stream) return;
const handleVideoChange = async (payload: { action: string; userId: number }) => {
const { action, userId } = payload;
if (action === 'Start') {
const element = await stream.attachVideo(userId, VideoQuality.Video_360P);
videoContainerRef.current?.appendChild(element);
} else {
await stream.detachVideo(userId);
}
};
client.on('peer-video-state-change', handleVideoChange);
return () => {
client.off('peer-video-state-change', handleVideoChange);
};
}, [client, stream]);
// Start own video
useEffect(() => {
if (!stream) return;
const startVideo = async () => {
await stream.startVideo();
const currentUser = client!.getCurrentUserInfo();
const element = await stream.attachVideo(currentUser.userId, VideoQuality.Video_360P);
videoContainerRef.current?.appendChild(element);
};
startVideo();
}, [stream, client]);
return (
<div>
<div ref={videoContainerRef} className="video-container" />
<button onClick={() => client?.leave()}>Leave</button>
</div>
);
};createClient() → init() → join() → getMediaStream()getMediaStream() after join() completes