Skip to content

Commit 8a1df6c

Browse files
Merge pull request #264041 from valindrae/acs-closed-captions
Update closed-captions-javascript.md
2 parents 2f55734 + bdd7c70 commit 8a1df6c

File tree

1 file changed

+139
-53
lines changed

1 file changed

+139
-53
lines changed
Lines changed: 139 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,169 @@
11
---
2-
title: Get started with Azure Communication Services closed caption on web
3-
titleSuffix: An Azure Communication Services quickstart document
4-
description: Learn about the Azure Communication Services Closed Captions in web apps
5-
author: RinaRish
6-
manager: visho
7-
services: azure-communication-services
8-
9-
ms.author: ektrishi
10-
ms.date: 02/03/2022
11-
ms.topic: include
2+
title: include file
3+
description: Web how-to guide for enabling Closed captions during an ACS call.
4+
author: Kunaal
125
ms.service: azure-communication-services
6+
ms.subservice: calling
7+
ms.topic: include
8+
ms.topic: include file
9+
ms.date: 12/19/2023
10+
ms.author: kpunjabi
1311
---
1412

1513
## Prerequisites
14+
- Azure account with an active subscription, for details see [Create an account for free.](https://azure.microsoft.com/free/)
15+
- Azure Communication Services resource. See [Create an Azure Communication Services resource](../../../../quickstarts/create-communication-resource.md?tabs=windows&pivots=platform-azp). Save the connection string for this resource.
16+
- An app with voice and video calling, refer to our [Voice](../../../../quickstarts/voice-video-calling/getting-started-with-calling.md) and [Video](../../../../quickstarts/voice-video-calling/get-started-with-video-calling.md) calling quickstarts.
17+
1618

17-
Refer to the [Voice Calling Quickstart](../../getting-started-with-calling.md?pivots=platform-web) to set up a sample app with voice calling.
19+
>[!NOTE]
20+
>Please note that you will need to have a voice calling app using Azure Communication Services calling SDKs to access the closed captions feature that is described in this guide.
1821
1922
## Models
20-
2123
| Name | Description |
22-
| - | - |
23-
| CaptionsCallFeature | API for call captions. |
24-
| StartCaptionsOptions | Used for representing options to start closed captions |
25-
| CaptionsHandler | Callback definition for handling the CaptionsReceivedEventType event. |
26-
| CaptionsInfo | Data structure received for each CaptionsReceivedEventType event. |
24+
| ---- | ----------- |
25+
| CaptionsCallFeature | API for Captions |
26+
| CaptionsCommon | Base class for captions |
27+
| StartCaptionOptions | Closed caption options like spoken language |
28+
| CaptionsHandler | Callback definition for handling CaptionsReceivedEventType event |
29+
| CaptionsInfo | Data structure received for each CaptionsReceivedEventType event |
2730

28-
## Methods
31+
## Get closed captions feature
2932

30-
### Start captions
33+
``` typescript
34+
let captionsCallFeature: SDK.CaptionsCallFeature = call.feature(SDK.Features.Captions);
35+
```
3136

32-
1. Get the ongoing call object established during the prerequisite steps.
33-
2. Get the captions feature object.
34-
3. Set the `captionsReceived` event handler via the `on` API.
35-
4. Call `startCaptions` on the feature object with the desired options.
36-
```js
37-
const captionsHandler = (data: CaptionsInfo) => { /* USER CODE HERE - E.G. RENDER TO DOM */ };
3837

39-
try {
40-
const callCaptionsApi = call.feature(Features.Captions);
41-
callCaptionsApi.on('captionsReceived', captionsHandler);
42-
if (!callCaptionsApi.isCaptionsActive) {
43-
await callCaptionsApi.startCaptions({ spokenLanguage: 'en-us' });
44-
}
45-
} catch (e) {
46-
console.log('Internal error occurred when Starting Captions');
38+
## Get captions object
39+
You need to get and cast the Captions object to utilize Captions specific features.
40+
``` typescript
41+
let captions: SDK.Captions;
42+
if (captionsCallFeature.captions.kind === 'Captions') {
43+
captions = captionsCallFeature.captions as SDK.Captions;
4744
}
4845
```
4946

50-
### Stopping captions
47+
## Subscribe to listeners
5148

52-
1. Get the captions feature object.
53-
2. Call `off` with the previous specified handler.
49+
### Add a listener to receive captions active/inactive status
50+
```typescript
51+
const captionsActiveChangedHandler = () => {
52+
if (captions.isCaptionsFeatureActive()) {
53+
/* USER CODE HERE - E.G. RENDER TO DOM */
54+
}
55+
}
56+
captions.on('CaptionsActiveChanged', captionsActiveChangedHandler);
57+
```
5458

55-
> [!NOTE]
56-
> Captions will still be processed, but this client will stop handling them.
59+
### Add a listener for captions data received
60+
Handle the returned CaptionsInfo data object.
61+
62+
Note: The object contains a resultType prop that indicates whether the data is a partial caption or a finalized version of the caption. ResultType `Partial` indicates live unedited caption, while `Final` indicates a finalized interpreted version of the sentence (i.e includes punctuation and capitalization).
63+
64+
```typescript
65+
const captionsReceivedHandler : CaptionsHandler = (data: CaptionsInfo) => {
66+
/** USER CODE HERE - E.G. RENDER TO DOM
67+
* data.resultType
68+
* data.speaker
69+
* data.spokenLanguage
70+
* data.spokenText
71+
* data.timeStamp
72+
*/
73+
// Example code:
74+
// Create a dom element, i.e. div, with id "captionArea" before proceeding with the sample code
75+
let mri: string;
76+
switch (data.speaker.identifier.kind) {
77+
case 'communicationUser': { mri = data.speaker.identifier.communicationUserId; break; }
78+
case 'phoneNumber': { mri = data.speaker.identifier.phoneNumber; break; }
79+
}
80+
const outgoingCaption = `prefix${mri.replace(/:/g, '').replace(/-/g, '')}`;
81+
82+
let captionArea = document.getElementById("captionArea");
83+
const captionText = `${data.timestamp.toUTCString()}
84+
${data.speaker.displayName}: ${data.spokenText}`;
85+
86+
let foundCaptionContainer = captionArea.querySelector(`.${outgoingCaption}[isNotFinal='true']`);
87+
if (!foundCaptionContainer) {
88+
let captionContainer = document.createElement('div');
89+
captionContainer.setAttribute('isNotFinal', 'true');
90+
captionContainer.style['borderBottom'] = '1px solid';
91+
captionContainer.style['whiteSpace'] = 'pre-line';
92+
captionContainer.textContent = captionText;
93+
captionContainer.classList.add(newClassName);
94+
95+
captionArea.appendChild(captionContainer);
96+
} else {
97+
foundCaptionContainer.textContent = captionText;
98+
99+
if (captionData.resultType === 'Final') {
100+
foundCaptionContainer.setAttribute('isNotFinal', 'false');
101+
}
102+
}
103+
};
104+
captions.on('CaptionsReceived', captionsReceivedHandler);
105+
```
57106

58-
```js
59-
const callCaptionsApi = call.feature(Features.Captions);
60-
callCaptionsApi.off('captionsReceived', captionsHandler);
107+
### Add a listener to receive spoken language changed status
108+
```typescript
109+
const spokenLanguageChangedHandler = () => {
110+
if (captions.activeSpokenLanguage !== currentSpokenLanguage) {
111+
/* USER CODE HERE - E.G. RENDER TO DOM */
112+
}
113+
}
114+
captions.on('SpokenLanguageChanged', spokenLanguageChangedHandler)
61115
```
62116

63-
### Get available languages
117+
## Start captions
118+
Once you have set up all your listeners, you can now start adding captions.
119+
``` typescript
120+
try {
121+
await captions.startCaptions({ spokenLanguage: 'en-us' });
122+
} catch (e) {
123+
/* USER ERROR HANDLING CODE HERE */
124+
}
125+
```
64126

65-
Access the `availableLanguages` property on the `call.feature(Features.Captions)` API.
127+
## Stop captions
66128

67-
```js
68-
const callCaptionsApi = call.feature(Features.Captions);
69-
const availableLanguages = callCaptionsApi.availableLanguages;
129+
``` typescript
130+
try {
131+
captions.stopCaptions();
132+
} catch (e) {
133+
/* USER ERROR HANDLING CODE HERE */
134+
}
70135
```
71136

72-
### Update language
137+
## Unsubscribe to listeners
138+
```typescript
139+
captions.off('CaptionsActiveChanged', captionsActiveChangedHandler);
140+
captions.off('CaptionsReceived', captionsReceivedHandler);
141+
```
73142

74-
Pass a value in from the available languages array to ensure that the requested language is supported.
143+
## Spoken language support
75144

76-
```js
77-
await callCaptionsApi.selectLanguage(availableLanguages[0]);
145+
### Get a list of supported spoken languages
146+
Get a list of supported spoken languages that your users can select from when enabling closed captions.
147+
The property returns an array of languages in bcp 47 format.
148+
``` typescript
149+
const spokenLanguages = captions.supportedSpokenLanguages;
78150
```
79151

80-
## Clean up
152+
## Set spoken language
81153

82-
If you want to clean up and remove a Communication Services subscription, you can delete the resource or resource group. Deleting the resource group also deletes any other resources associated with it.
83-
Learn more about [cleaning up resources here.](../../../create-communication-resource.md?pivots=platform-azp&tabs=windows#clean-up-resources)
154+
Pass a value in from the supported spoken languages array to ensure that the requested language is supported.
155+
By default, if contoso provides no language or an unsupported language, the spoken language defaults to 'en-us'.
156+
157+
``` typescript
158+
// bcp 47 formatted language code
159+
const language = 'en-us';
160+
161+
// Altneratively, pass a value from the supported spoken languages array
162+
const language = spokenLanguages[0];
163+
164+
try {
165+
captions.setSpokenLanguage(language);
166+
} catch (e) {
167+
/* USER ERROR HANDLING CODE HERE */
168+
}
169+
```

0 commit comments

Comments
 (0)