Skip to content

Commit 37b6a0f

Browse files
junhao3268mickelr
andauthored
feat(Ai-assistant): auto detect spoken language (#4505)
Co-authored-by: mickelr <[email protected]>
1 parent 21004f3 commit 37b6a0f

File tree

12 files changed

+72
-3
lines changed

12 files changed

+72
-3
lines changed

packages/@webex/internal-plugin-voicea/README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,16 @@ await webex.internal.voicea.toggleManualCaption(false);
6666
Set Spoken Language
6767

6868
- Host can set the spoken language of the meeting
69+
- initial language: DEFAULT
70+
- auto detect spoken language: AUTO
71+
- host change language by manual and stop auto detect: MANUAL
6972
- Triggers voicea:spokenLanguageSet
7073

7174
```js
72-
webex.internal.voicea.setSpokenLanguage('en');
75+
webex.internal.voicea.setSpokenLanguage('en', 'DEFAULT');
76+
webex.internal.voicea.setSpokenLanguage('en', 'AUTO');
77+
webex.internal.voicea.setSpokenLanguage('en', 'MANUAL');
78+
7379
```
7480

7581
Set Caption Language

packages/@webex/internal-plugin-voicea/src/constants.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export const TRANSCRIPTION_TYPE = {
3737
MANUAL_CAPTION_INTERIM_RESULTS: 'manual_caption_interim_results',
3838
MANUAL_CAPTION_INTERIM_RESULT: 'manual_caption_interim_result',
3939
MANUAL_CAPTION_FINAL_RESULT: 'manual_caption_final_result',
40+
LANGUAGE_DETECTED: 'language_detected',
4041
};
4142

4243
export const VOICEA = 'voicea';
@@ -58,3 +59,9 @@ export const TOGGLE_MANUAL_CAPTION_STATUS = {
5859
IDLE: 'idle',
5960
SENDING: 'sending',
6061
};
62+
63+
export const LANGUAGE_ASSIGNMENT = {
64+
AUTO: 'AUTO',
65+
MANUAL: 'MANUAL',
66+
DEFAULT: 'DEFAULT',
67+
};

packages/@webex/internal-plugin-voicea/src/voicea.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
TURN_ON_CAPTION_STATUS,
1111
TOGGLE_MANUAL_CAPTION_STATUS,
1212
DEFAULT_SPOKEN_LANGUAGE,
13+
LANGUAGE_ASSIGNMENT,
1314
} from './constants';
1415
// eslint-disable-next-line no-unused-vars
1516
import {
@@ -197,6 +198,11 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
197198
});
198199
break;
199200

201+
case TRANSCRIPTION_TYPE.LANGUAGE_DETECTED:
202+
// @ts-ignore
203+
this.setSpokenLanguage(voiceaPayload.language, LANGUAGE_ASSIGNMENT.AUTO);
204+
break;
205+
200206
default:
201207
break;
202208
}
@@ -268,9 +274,13 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
268274
/**
269275
* Set Spoken Language for the meeting
270276
* @param {string} languageCode
277+
* @param {"DEFAULT" | "AUTO" | "MANUAL"} languageAssignment
271278
* @returns {Promise}
272279
*/
273-
public setSpokenLanguage = (languageCode: string): Promise<void> =>
280+
public setSpokenLanguage = (
281+
languageCode: string,
282+
languageAssignment = LANGUAGE_ASSIGNMENT.DEFAULT
283+
): Promise<void> =>
274284
// @ts-ignore
275285
this.request({
276286
method: 'PUT',
@@ -279,6 +289,7 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
279289
body: {
280290
transcribe: {
281291
spokenLanguage: languageCode,
292+
languageAssignment,
282293
},
283294
},
284295
}).then(() => {

packages/@webex/internal-plugin-voicea/src/voicea.types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ interface TranscriptionResponse {
7070
csis: number[];
7171
data: string;
7272
command_response: string;
73+
language: string;
7374
}
7475
/**
7576
* Type for CaptionLanguageResponse

packages/@webex/internal-plugin-voicea/test/unit/spec/voicea.js

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ describe('plugin-voicea', () => {
291291
describe('#setSpokenLanguage', () => {
292292
it('sets spoken language', async () => {
293293
const languageCode = 'en';
294+
let languageAssignment = 'DEFAULT';
294295
const triggerSpy = sinon.spy();
295296

296297
voiceaService.on(EVENT_TRIGGERS.SPOKEN_LANGUAGE_UPDATE, triggerSpy);
@@ -306,7 +307,8 @@ describe('plugin-voicea', () => {
306307
url: `${locusUrl}/controls/`,
307308
body: {
308309
transcribe: {
309-
spokenLanguage: languageCode
310+
spokenLanguage: languageCode,
311+
languageAssignment,
310312
}
311313
},
312314
})
@@ -880,6 +882,28 @@ describe('plugin-voicea', () => {
880882
timestamp: '11:00',
881883
});
882884
});
885+
886+
it('processes a language detected', async () => {
887+
voiceaService.on(EVENT_TRIGGERS.SPOKEN_LANGUAGE_UPDATE, triggerSpy);
888+
889+
const voiceaPayload = {
890+
id: '9bc51440-1a22-7c81-6add-4b6ff7b59f7c',
891+
meeting: 'fd5bd0fc-06fb-4fd1-982b-554c4368f101',
892+
type: 'language_detected',
893+
language: 'pl'
894+
};
895+
896+
// eslint-disable-next-line no-underscore-dangle
897+
await voiceaService.webex.internal.llm._emit('event:relay.event', {
898+
headers: {from: 'ws'},
899+
data: {relayType: 'voicea.transcription', voiceaPayload},
900+
});
901+
902+
assert.calledOnceWithExactly(functionSpy, voiceaPayload);
903+
904+
assert.calledOnceWithExactly(triggerSpy, {languageCode: 'pl'});
905+
});
906+
883907
});
884908

885909
describe('#processManualTranscription', () => {

packages/@webex/plugin-meetings/src/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -966,6 +966,7 @@ export const DISPLAY_HINTS = {
966966
MANUAL_CAPTION_STOP: 'MANUAL_CAPTION_STOP',
967967
MANUAL_CAPTION_STATUS_ACTIVE: 'MANUAL_CAPTION_STATUS_ACTIVE',
968968
DISPLAY_REAL_TIME_TRANSLATION: 'DISPLAY_REAL_TIME_TRANSLATION',
969+
SPOKEN_LANGUAGE_AUTO_DETECTION_ENABLED: 'SPOKEN_LANGUAGE_AUTO_DETECTION_ENABLED',
969970
ENABLE_CAPTION_PANEL: 'ENABLE_CAPTION_PANEL',
970971
DISPLAY_NON_ENGLISH_ASR: 'DISPLAY_NON_ENGLISH_ASR',
971972
TRANSCRIPTION_CONTROL_START: 'TRANSCRIPTION_CONTROL_START',

packages/@webex/plugin-meetings/src/meeting/in-meeting-actions.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ interface IInMeetingActions {
4444

4545
isManualCaptionActive?: boolean;
4646
isSaveTranscriptsEnabled?: boolean;
47+
isSpokenLanguageAutoDetectionEnabled?: boolean;
4748
isWebexAssistantActive?: boolean;
4849
canViewCaptionPanel?: boolean;
4950
isRealTimeTranslationEnabled?: boolean;
@@ -187,6 +188,8 @@ export default class InMeetingActions implements IInMeetingActions {
187188

188189
isSaveTranscriptsEnabled = null;
189190

191+
isSpokenLanguageAutoDetectionEnabled = null;
192+
190193
isWebexAssistantActive = null;
191194

192195
canViewCaptionPanel = null;
@@ -363,6 +366,7 @@ export default class InMeetingActions implements IInMeetingActions {
363366
canStopManualCaption: this.canStopManualCaption,
364367
isManualCaptionActive: this.isManualCaptionActive,
365368
isSaveTranscriptsEnabled: this.isSaveTranscriptsEnabled,
369+
isSpokenLanguageAutoDetectionEnabled: this.isSpokenLanguageAutoDetectionEnabled,
366370
isWebexAssistantActive: this.isWebexAssistantActive,
367371
canViewCaptionPanel: this.canViewCaptionPanel,
368372
isRealTimeTranslationEnabled: this.isRealTimeTranslationEnabled,

packages/@webex/plugin-meetings/src/meeting/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4226,6 +4226,9 @@ export default class Meeting extends StatelessWebexPlugin {
42264226
isLocalRecordingPaused: MeetingUtil.isLocalRecordingPaused(this.userDisplayHints),
42274227
isManualCaptionActive: MeetingUtil.isManualCaptionActive(this.userDisplayHints),
42284228
isSaveTranscriptsEnabled: MeetingUtil.isSaveTranscriptsEnabled(this.userDisplayHints),
4229+
isSpokenLanguageAutoDetectionEnabled: MeetingUtil.isSpokenLanguageAutoDetectionEnabled(
4230+
this.userDisplayHints
4231+
),
42294232
isWebexAssistantActive: MeetingUtil.isWebexAssistantActive(this.userDisplayHints),
42304233
canViewCaptionPanel: MeetingUtil.canViewCaptionPanel(this.userDisplayHints),
42314234
isRealTimeTranslationEnabled: MeetingUtil.isRealTimeTranslationEnabled(

packages/@webex/plugin-meetings/src/meeting/util.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,9 @@ const MeetingUtil = {
638638
isManualCaptionActive: (displayHints) =>
639639
displayHints.includes(DISPLAY_HINTS.MANUAL_CAPTION_STATUS_ACTIVE),
640640

641+
isSpokenLanguageAutoDetectionEnabled: (displayHints) =>
642+
displayHints.includes(DISPLAY_HINTS.SPOKEN_LANGUAGE_AUTO_DETECTION_ENABLED),
643+
641644
isWebexAssistantActive: (displayHints) =>
642645
displayHints.includes(DISPLAY_HINTS.WEBEX_ASSISTANT_STATUS_ACTIVE),
643646

packages/@webex/plugin-meetings/test/unit/spec/meeting/in-meeting-actions.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ describe('plugin-meetings', () => {
3838
isManualCaptionActive: null,
3939
isPremiseRecordingEnabled: null,
4040
isSaveTranscriptsEnabled: null,
41+
isSpokenLanguageAutoDetectionEnabled: null,
4142
isWebexAssistantActive: null,
4243
canViewCaptionPanel: null,
4344
isRealTimeTranslationEnabled: null,
@@ -151,6 +152,7 @@ describe('plugin-meetings', () => {
151152
'isManualCaptionActive',
152153
'isPremiseRecordingEnabled',
153154
'isSaveTranscriptsEnabled',
155+
'isSpokenLanguageAutoDetectionEnabled',
154156
'isWebexAssistantActive',
155157
'canViewCaptionPanel',
156158
'isRealTimeTranslationEnabled',

0 commit comments

Comments
 (0)