Hello Zoom Team,
I am currently using the Zoom Video UI Toolkit to manage UI components and session handling in my web application. I prefer to use the UI Toolkit instead of implementing everything manually via the Zoom Video SDK.
Now, I want to enable the Live Transcription (LTT) feature and receive its status updates through a callback. However, I do not want to use the Video SDK directly for implementing LTT—I just want the UI Toolkit to handle the feature and provide me with the necessary callback.
What I Have Done So Far:
• Integrated the Zoom Video UI Toolkit successfully.
• Added JavaScript files for handling session join/leave.
• Configured the features array in my config object to include ‘ltt’:
var config = {
videoSDKJWT: ‘’,
sessionName: ‘test’,
userName: ‘JavaScript’,
sessionPasscode: ‘123’,
features: [‘video’, ‘audio’, ‘settings’, ‘users’, ‘chat’, ‘ltt’], // Included LTT
options: { init: {}, audio: {}, video: {}, share: {} }
};
• Successfully joined a session using uitoolkit.joinSession(sessionContainer, config).
What I Need Help With:
1. How can I receive Live Transcription (LTT) status updates as a callback?
2. Does the UI Toolkit automatically handle LTT, or do I need to call any additional functions to enable it?
3. Is there an event like client.on(‘caption-status’, callback) that works within the UI Toolkit?
What I Want to Avoid:
• I do not want to use the Zoom Video SDK directly to manage Live Transcription.
• I want the UI Toolkit to handle everything related to LTT except for providing a callback when status changes.
Would appreciate any guidance on how to properly listen for LTT events using the UI Toolkit.
Do you have any API call which i can made and get all transcript from particular Session ??
Thanks in advance!
// Import UI toolkit
import uitoolkit from './@zoom/videosdk-ui-toolkit/index.js'
// Get ZoomVideo from CDN-loaded global object
const ZoomVideo = window.WebVideoSDK.default;
// Initialize variables
var sessionContainer = document.getElementById('sessionContainer');
var onMeetingEndedCallback = null;
// Initialize the Video SDK client as a singleton
const client = ZoomVideo.createClient();
var config = {
videoSDKJWT: '',
sessionName: 'test',
userName: 'JavaScript',
sessionPasscode: '123',
features: ['video', 'audio', 'settings', 'users', 'chat', 'ltt','liveTranscription'],
options: {
init: {
liveTranscription: true,
language: 'en-US',
},
audio: {},
video: {},
share: {}
},
virtualBackground: {
allowVirtualBackground: false,
allowVirtualBackgroundUpload: false,
},
// Add disclaimer for live transcription
ltt: 'Live transcription is now active'
};
// Initialize global functions
const zoomManager = {
joinSession: function(signature, sessionName, userName, password) {
console.log('Joining Session:', { sessionName, userName });
config.videoSDKJWT = signature;
config.sessionName = sessionName;
config.userName = userName;
config.sessionPasscode = password;
try {
client.init('en-US', `CDN`)
// Set up live transcription listener before joining
this.setupLiveTranscription();
uitoolkit.joinSession(sessionContainer, config);
console.log('Joined meeting successfully');
uitoolkit.onSessionClosed(this.handleSessionClosed);
return true;
} catch (error) {
console.error('Failed to join session:', error);
return false;
}
},
setupLiveTranscription: function() {
// Listen for caption events
client.on('caption-message', (payload) => {
console.log('Live Caption:', JSON.stringify(payload));
});
// Listen for caption status changes
client.on('caption-status', (status) => {
console.log('Caption Status Changed:', JSON.stringify(status));
});
},
closeSession: function() {
console.log('Closing session');
try {
uitoolkit.closeSession(sessionContainer);
return true;
} catch (error) {
console.error('Failed to close session:', error);
return false;
}
},
handleSessionClosed: function() {
console.log('Session closed callback');
uitoolkit.closeSession(sessionContainer);
if (typeof onMeetingEndedCallback === 'function') {
onMeetingEndedCallback();
}
},
setMeetingEndCallback: function(callback) {
console.log('Setting meeting end callback');
onMeetingEndedCallback = callback;
}
};
// Expose functions to window object
window.joinZoomSession = zoomManager.joinSession.bind(zoomManager);
window.closeSession = zoomManager.closeSession.bind(zoomManager);
window.setMeetingEndCallback = zoomManager.setMeetingEndCallback;
<!DOCTYPE html><html><head>
<!--
If you are serving your web app in a path other than the root, change the
href value below to reflect the base path you are serving from.
The path provided below has to start and end with a slash "/" in order for
it to work correctly.
For more details:
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
This is used to configure paths for PWA assets and html tags.
Topdoc is served from the subpath /onboarding/ instead of the root of a subdomain.
-->
<base href="$FLUTTER_BASE_HREF">
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="A new Flutter project.">
<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="topdoc">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<!-- Favicon -->
<link rel="icon" type="image/x-icon" href="favicon.ico">
<title>Topdoc - Doctor Dashboard</title>
<link rel="manifest" href="manifest.json">
<script>
// The value below is injected by flutter build, do not touch.
const serviceWorkerVersion = null;
</script>
<script src="https://source.zoom.us/videosdk/zoom-video-1.9.8.min.js"></script>
<!-- This script adds the flutter initialization JS code -->
<script src="flutter.js" defer=""></script>
<style id="splash-screen-style">
html, body {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
body {
margin: 0;
min-height: 100%;
background-color: #ffffff;
background-size: 100% 100%;
}
.center {
margin: 0;
position: absolute;
top: 45%;
left: 50%;
transform: translate(-50%, -50%);
}
.contain {
display: block;
width: 100%;
height: 100%;
object-fit: contain;
}
.stretch {
display: block;
width: 100%;
height: 100%;
}
.cover {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
.bottom {
position: absolute;
bottom: 0;
left: 50%;
-ms-transform: translate(-50%, 0);
transform: translate(-50%, 0);
}
.bottomLeft {
position: absolute;
bottom: 0;
left: 0;
}
.bottomRight {
position: absolute;
bottom: 0;
right: 0;
}
/* Loader styles */
.loader {
margin-top: 10px;
border: 4px solid #f3f3f3;
border-top: 4px solid #4F50F6;
border-radius: 50%;
width: 36px;
height: 36px;
display: block;
z-index: 10;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
<script id="splash-screen-script">
function removeSplashFromWeb() {
document.getElementById("splash")?.remove();
document.getElementById("splash-branding")?.remove();
document.getElementById("loader")?.remove();
document.body.style.background = "transparent";
}
</script>
<link rel="stylesheet" href="@zoom/videosdk-ui-toolkit/dist/videosdk-ui-toolkit.css">
</head>
<body>
<picture id="splash">
<source srcset="splash/img/light-1x.png 1x, splash/img/light-2x.png 2x, splash/img/light-3x.png 3x, splash/img/light-4x.png 4x" media="(prefers-color-scheme: light)">
<source srcset="splash/img/dark-1x.png 1x, splash/img/dark-2x.png 2x, splash/img/dark-3x.png 3x, splash/img/dark-4x.png 4x" media="(prefers-color-scheme: dark)">
<img class="center" aria-hidden="true" src="splash/img/light-1x.png" alt="">
</picture>
<script>
window.addEventListener('load', function(ev) {
// Download main.dart.js
_flutter.loader.loadEntrypoint({
serviceWorker: {
serviceWorkerVersion: serviceWorkerVersion,
},
onEntrypointLoaded: function(engineInitializer) {
engineInitializer.initializeEngine().then(function(appRunner) {
appRunner.runApp();
});
}
});
});
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open('flutter-app-cache').then((cache) => {
return cache.addAll([
'/index.html',
'/main.dart.js',
// Critical assets
]);
})
);
});
</script>
<script src="scripts.js" type="module"></script>
<script type="text/javascript">
window.flutterWebRenderer = "html";
</script>
<script type="text/javascript" id="hs-script-loader" async="" defer="" src="//js.hs-scripts.com/40823668.js"></script>
<script>
function joinZoomSession(signature, sessionName, userName, password) {
console.log('Joining')
joinSession(signature, sessionName, userName, password)
}
</script>
<div style="position: relative;">
<div id="sessionContainer" aria-hidden="false" style="background-color: white; width: 60%; margin: 0 auto;"></div>
<div class="loader" id="loader"></div>
</div>
<script src="@zoom/videosdk-ui-toolkit/index.js" type="module"></script>
</body></html>