bigbluebutton-Github/bigbluebutton-html5/imports/ui/components/audio/audio-graphql/audio-captions/service.ts
Lucas 9bf3f54183
feat: Initial BBB 3.0 Gladia transcriptions implementation (#20295)
* feat(html5): initial implementation of Gladia transcriptions to BBB 3.0

* fix(transcription): Add missing locales and fix invalid cc menu key

* fix(bbb-transcription-controller): Bump transcription controller to fix some bugs

* fix: adjust yq syntax for setting fs esl password in transctiption-controller

* fix(transcription): Use newer useSettings format from transcription options

* fix(captions): Correctly use captions settings

---------

Co-authored-by: João Victor <joaovictornunes973@gmail.com>
Co-authored-by: Anton Georgiev <anto.georgiev@gmail.com>
Co-authored-by: Ramón Souza <contato@ramonsouza.com>
2024-06-12 12:06:07 -04:00

96 lines
3.0 KiB
TypeScript

import { unique } from 'radash';
import { setAudioCaptionEnable } from '/imports/ui/core/local-states/useAudioCaptionEnable';
import { isLiveTranscriptionEnabled } from '/imports/ui/services/features';
import getFromUserSettings from '/imports/ui/services/users-settings';
import { Caption } from './live/queries';
import Session from '/imports/ui/services/storage/in-memory';
export const splitTranscript = (obj: Caption) => {
const CAPTIONS_CONFIG = window.meetingClientSettings.public.captions;
const CHARACTERS_PER_LINE = CAPTIONS_CONFIG.lineLimit;
const LINES_PER_MESSAGE = CAPTIONS_CONFIG.lines;
const transcripts = [];
const words = obj.captionText.split(' ');
let currentLine = '';
let result = '';
// eslint-disable-next-line no-restricted-syntax
for (const word of words) {
if ((currentLine + word).length <= CHARACTERS_PER_LINE) {
currentLine += `${word} `;
} else {
result += `${currentLine.trim()}\n`;
currentLine = `${word} `;
}
if (result.split('\n').length > LINES_PER_MESSAGE) {
transcripts.push(result);
result = '';
}
}
if (result.length) {
transcripts.push(result);
}
transcripts.push(currentLine.trim());
return transcripts.map((t) => { return { ...obj, captionText: t }; });
};
export const isAudioTranscriptionEnabled = () => isLiveTranscriptionEnabled();
const getSpeechProvider = () => {
const PROVIDER = window.meetingClientSettings.public.app.audioCaptions.provider;
return getFromUserSettings('bbb_transcription_provider', PROVIDER);
};
export const isWebSpeechApi = () => getSpeechProvider() === 'webspeech';
export const isGladia = () => getSpeechProvider() === 'gladia';
export const getSpeechVoices = () => {
const LANGUAGES = window.meetingClientSettings.public.app.audioCaptions.language.available;
if (!isWebSpeechApi()) return LANGUAGES;
return unique(
window
.speechSynthesis
.getVoices()
.map((v) => v.lang)
.filter((v) => LANGUAGES.includes(v)),
);
};
export const setAudioCaptions = (value: boolean) => {
setAudioCaptionEnable(value);
// @ts-ignore - Exist while we have meteor in the project
Session.setItem('audioCaptions', value);
};
export const setSpeechLocale = (value: string, setUserSpeechLocale: (a: string, b: string) => void) => {
setUserSpeechLocale(value, getSpeechProvider());
};
// SpeechLocale or CaptionLocale
export const setUserLocaleProperty = (value: string, setUserLocaleCallback: (a: string, b: string) => void) => {
const PROVIDER = window.meetingClientSettings.public.app.audioCaptions.provider;
setUserLocaleCallback(value, PROVIDER);
};
export const useFixedLocale = () => {
const FORCE_LOCALE = window.meetingClientSettings.public.app.audioCaptions.language.forceLocale;
return isAudioTranscriptionEnabled() && FORCE_LOCALE;
};
export default {
getSpeechVoices,
isAudioTranscriptionEnabled,
setUserLocaleProperty,
setSpeechLocale,
setAudioCaptions,
isWebSpeechApi,
useFixedLocale,
isGladia,
splitTranscript,
};