diff --git a/docs/javascript/v2/how-to-guides/set-up-video-conferencing/captions.mdx b/docs/javascript/v2/how-to-guides/set-up-video-conferencing/captions.mdx index 8b9b3389d..406fb93e1 100644 --- a/docs/javascript/v2/how-to-guides/set-up-video-conferencing/captions.mdx +++ b/docs/javascript/v2/how-to-guides/set-up-video-conferencing/captions.mdx @@ -11,84 +11,179 @@ nav: 1.24 ## How to implement closed captioning? -The `useTranscript` hook is implemented with the `onTranscript` callback as shown below: +Each transcript entry has the following structure: ```ts - export interface HMSTranscript { - // start time in second - start: number; - // end time in seconds - end: number; - // peer_id of the speaker - peer_id: string; - // transcription will continue to update the transcript until you receive final keyword - final: boolean; - // closed caption - transcript: string; - } +interface HMSTranscript { + start: number; // start time in seconds + end: number; // end time in seconds + peer_id: string; // peer_id of the speaker + final: boolean; // true when the transcript segment is finalized + transcript: string; // the caption text +} +``` + +The transcription engine sends interim results as the speaker talks, then a final result once the segment is complete. Interim results update the same segment in place, while final results indicate that a new segment will follow. + + + + + +In plain JavaScript, transcript data arrives as `NEW_MESSAGE` notifications of type `hms_transcript`. Subscribe via `hmsNotifications.onNotification`: + +```js +import { HMSNotificationTypes } from '@100mslive/hms-video-store'; - export interface useHMSTranscriptInput { - onTranscript?: (data: HMSTranscript[]) => void; - handleError?: hooksErrHandler; +const unsubscribe = hmsNotifications.onNotification((notification) => { + const msg = notification.data; + if (msg && msg.type === 'hms_transcript') { + const parsed = JSON.parse(msg.message); + const transcripts = parsed.results; // HMSTranscript[] + + transcripts.forEach((entry) => { + console.log( + `${entry.peer_id}: ${entry.transcript} (final: ${entry.final})` + ); + }); } +}, HMSNotificationTypes.NEW_MESSAGE); + +// call unsubscribe() when you no longer need transcript updates +``` + +To resolve the `peer_id` to a display name, use the store: - export const useTranscript = ({ onTranscript, handleError = logErrorHandler }: useHMSTranscriptInput); +```js +import { selectPeerNameByID } from '@100mslive/hms-video-store'; +const peerName = hmsStore.getState(selectPeerNameByID(entry.peer_id)); ``` + + + + +Use the `useTranscript` hook with the `onTranscript` callback: + +```jsx +import { useTranscript } from '@100mslive/react-sdk'; + +function CaptionsViewer() { + useTranscript({ + onTranscript: (transcripts) => { + // transcripts is HMSTranscript[] + transcripts.forEach((entry) => { + console.log( + `${entry.peer_id}: ${entry.transcript} (final: ${entry.final})` + ); + }); + }, + }); + + return null; +} +``` + + + ## How can you check if closed captions are enabled in a room? -```ts + + + + +```js +import { selectIsTranscriptionEnabled } from '@100mslive/hms-video-store'; + +// read once +const isCaptionEnabled = hmsStore.getState(selectIsTranscriptionEnabled); + +// or subscribe to changes +hmsStore.subscribe((enabled) => { + console.log('Captions enabled:', enabled); +}, selectIsTranscriptionEnabled); +``` + + + + + +```jsx import { selectIsTranscriptionEnabled, useHMSStore } from '@100mslive/react-sdk'; -// use this to check if caption is enabled for your room. -const isCaptionPresent: boolean = useHMSStore(selectIsTranscriptionEnabled); + +function CaptionStatus() { + const isCaptionEnabled = useHMSStore(selectIsTranscriptionEnabled); + return {isCaptionEnabled ? 'Captions ON' : 'Captions OFF'}; +} ``` + + ## How to toggle closed captions on or off? Closed captions can be dynamically enabled or disabled at runtime within a given room, depending on user requirements. This capability helps minimize unnecessary usage costs by ensuring that captions are enabled only when explicitly needed by the user(s). -```ts -// Currently 100ms supports closed captions type mode -export declare enum HMSTranscriptionMode { - CAPTION = 'caption' -} +### Check permission -export interface TranscriptionConfig { - mode: HMSTranscriptionMode; -} +Before starting or stopping transcription, verify that the local peer has the required permission: + + + + + +```js +import { + HMSTranscriptionMode, + selectIsTranscriptionAllowedByMode +} from '@100mslive/hms-video-store'; + +const isTranscriptionAllowed = hmsStore.getState( + selectIsTranscriptionAllowedByMode(HMSTranscriptionMode.CAPTION) +); +``` + + + + + +```jsx +import { + HMSTranscriptionMode, + selectIsTranscriptionAllowedByMode, + useHMSStore +} from '@100mslive/react-sdk'; -// admin/host role need to startTranscription if he had the access, here is how you will check if you had access to start transcription const isTranscriptionAllowed = useHMSStore( selectIsTranscriptionAllowedByMode(HMSTranscriptionMode.CAPTION) ); ``` -Use `hmsActions.startTranscription()` method to start the closed captions. + -```ts - async startCaption() { - try { - await hmsActions.startTranscription({ - mode: HMSTranscriptionMode.CAPTION, - }); - } catch(err) { - console.log(err); - } - } +### Start captions +Use `hmsActions.startTranscription()` to enable closed captions for the room: + +```js +try { + await hmsActions.startTranscription({ + mode: HMSTranscriptionMode.CAPTION, + }); +} catch (err) { + console.error('Failed to start captions:', err); +} ``` -Use `hmsActions.stopTranscription()` method to stop closed captions. +### Stop captions -```ts - async stopCaption() { - try { - await hmsActions.stopTranscription({ - mode: HMSTranscriptionMode.CAPTION, - }); - } catch(err) { - console.log(err); - } - } +Use `hmsActions.stopTranscription()` to disable closed captions: + +```js +try { + await hmsActions.stopTranscription({ + mode: HMSTranscriptionMode.CAPTION, + }); +} catch (err) { + console.error('Failed to stop captions:', err); +} ```