Skip to content

Commit b584e55

Browse files
authored
feat: Add an option to render speaker ID for transcriptions. (#17390)
* feat: Add an option to render speaker ID for transcriptions. * feat(subtitles): add renderTranscriptDetails config option When transcription.renderTranscriptDetails is enabled, prepend [Speaker N, lang] to rendered subtitles when the backend provides diarization speaker and/or language fields.
1 parent fc58240 commit b584e55

3 files changed

Lines changed: 30 additions & 6 deletions

File tree

config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,10 @@ var config = {
531531
// // subtitles on stage and the "Show subtitles on stage" checkbox in the settings.
532532
// // Note: Starting transcriptions from the recording dialog will still work.
533533
// disableClosedCaptions: false,
534+
//
535+
// // When the backend provides diarization by setting a "speaker" field, append [Speaker N] for transcription
536+
// // events from non-0 speakers.
537+
// renderTranscriptDetails: false
534538

535539
// },
536540

react/features/base/config/configType.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,7 @@ export interface IConfig {
700700
disableClosedCaptions?: boolean;
701701
enabled?: boolean;
702702
preferredLanguage?: string;
703+
renderTranscriptDetails?: boolean;
703704
translationLanguages?: Array<string>;
704705
translationLanguagesHead?: Array<string>;
705706
useAppLanguage?: boolean;

react/features/subtitles/middleware.ts

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,23 @@ function _endpointMessageReceived(store: IStore, next: Function, action: AnyActi
156156
};
157157
const { timestamp } = json;
158158
const participantId = participant.id;
159+
const speaker = json.speaker;
160+
const renderTranscriptDetails = state['features/base/config'].transcription?.renderTranscriptDetails;
161+
let detailsPrefix = '';
162+
163+
if (renderTranscriptDetails) {
164+
const parts = [];
165+
166+
if (speaker != null) {
167+
parts.push(`Speaker ${speaker}`);
168+
}
169+
if (json.language) {
170+
parts.push(json.language);
171+
}
172+
if (parts.length > 0) {
173+
detailsPrefix = `[${parts.join(', ')}] `;
174+
}
175+
}
159176

160177
// Handle transcript messages
161178
const language = state['features/base/conference'].conference
@@ -170,7 +187,8 @@ function _endpointMessageReceived(store: IStore, next: Function, action: AnyActi
170187
return next(action);
171188
}
172189

173-
const translation = json.text?.trim();
190+
const translationText = json.text?.trim();
191+
const translation = translationText ? `${detailsPrefix}${translationText}` : translationText;
174192

175193
if (isCCTabEnabled(state)) {
176194
dispatch(storeSubtitle({
@@ -191,7 +209,7 @@ function _endpointMessageReceived(store: IStore, next: Function, action: AnyActi
191209
// enabled.
192210
newTranscriptMessage = {
193211
clearTimeOut: undefined,
194-
final: json.text?.trim(),
212+
final: translation,
195213
participant
196214
};
197215
}
@@ -202,6 +220,7 @@ function _endpointMessageReceived(store: IStore, next: Function, action: AnyActi
202220
// translations are disabled.
203221

204222
const { text } = json.transcript[0];
223+
const displayText = `${detailsPrefix}${text}`;
205224

206225
// First, notify the external API.
207226
if (!(isInterim && skipInterimTranscriptions)) {
@@ -253,7 +272,7 @@ function _endpointMessageReceived(store: IStore, next: Function, action: AnyActi
253272
id: transcriptMessageID,
254273
participantId,
255274
language: json.language,
256-
text,
275+
text: displayText,
257276
interim: isInterim,
258277
timestamp,
259278
isTranscription: true
@@ -290,17 +309,17 @@ function _endpointMessageReceived(store: IStore, next: Function, action: AnyActi
290309
// If this is final result, update the state as a final result
291310
// and start a count down to remove the subtitle from the state
292311
if (!json.is_interim) {
293-
newTranscriptMessage.final = text;
312+
newTranscriptMessage.final = displayText;
294313
} else if (json.stability > STABLE_TRANSCRIPTION_FACTOR) {
295314
// If the message has a high stability, we can update the
296315
// stable field of the state and remove the previously
297316
// unstable results
298-
newTranscriptMessage.stable = text;
317+
newTranscriptMessage.stable = displayText;
299318
} else {
300319
// Otherwise, this result has an unstable result, which we
301320
// add to the state. The unstable result will be appended
302321
// after the stable part.
303-
newTranscriptMessage.unstable = text;
322+
newTranscriptMessage.unstable = displayText;
304323
}
305324
}
306325

0 commit comments

Comments
 (0)