@hahnpro/ms-speech-sdk
Version:
Microsoft Cognitive Services Speech SDK for JavaScript
1 lines • 24.4 kB
Source Map (JSON)
{"version":3,"sources":["src/sdk/Transcription/ConversationTranslator.ts"],"names":[],"mappings":"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","file":"ConversationTranslator.d.ts","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n// Multi-device Conversation is a Preview feature.\n\n/* eslint-disable max-classes-per-file */\n\nimport {\n ConversationConnectionConfig,\n IAuthentication,\n ServicePropertiesPropertyName,\n} from \"../../common.speech/Exports.js\";\nimport { ConversationTranslatorConnectionFactory } from \"../../common.speech/Transcription/ConversationTranslatorConnectionFactory.js\";\nimport {\n IDisposable,\n IErrorMessages,\n IStringDictionary,\n marshalPromiseToCallbacks\n} from \"../../common/Exports.js\";\nimport { Contracts } from \"../Contracts.js\";\nimport {\n AudioConfig,\n CancellationErrorCode,\n CancellationReason,\n ProfanityOption,\n PropertyCollection,\n PropertyId,\n ServicePropertyChannel,\n SessionEventArgs,\n SpeechTranslationConfig,\n TranslationRecognitionEventArgs,\n TranslationRecognizer\n} from \"../Exports.js\";\nimport { ConversationImpl } from \"./Conversation.js\";\nimport {\n ConversationCommon,\n ConversationExpirationEventArgs,\n ConversationHandler,\n ConversationParticipantsChangedEventArgs,\n ConversationTranslationCanceledEventArgs,\n ConversationTranslationEventArgs,\n IConversationTranslator,\n Participant\n} from \"./Exports.js\";\nimport { Callback, IConversation } from \"./IConversation.js\";\n\nexport enum SpeechState {\n Inactive, Connecting, Connected\n}\n\n// child class of TranslationRecognizer meant only for use with ConversationTranslator\nclass ConversationTranslationRecognizer extends TranslationRecognizer {\n private privTranslator: ConversationTranslator;\n private privSpeechState: SpeechState;\n\n public constructor(speechConfig: SpeechTranslationConfig, audioConfig: AudioConfig, translator: ConversationTranslator, convGetter: () => ConversationImpl) {\n\n super(speechConfig, audioConfig, new ConversationTranslatorConnectionFactory(convGetter));\n\n this.privSpeechState = SpeechState.Inactive;\n if (!!translator) {\n this.privTranslator = translator;\n this.sessionStarted = (): void => {\n this.privSpeechState = SpeechState.Connected;\n };\n\n this.sessionStopped = (): void => {\n this.privSpeechState = SpeechState.Inactive;\n };\n\n this.recognizing = (tr: TranslationRecognizer, e: TranslationRecognitionEventArgs): void => {\n if (!!this.privTranslator.recognizing) {\n this.privTranslator.recognizing(this.privTranslator, e);\n }\n };\n\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.recognized = async (tr: TranslationRecognizer, e: TranslationRecognitionEventArgs): Promise<void> => {\n // if there is an error connecting to the conversation service from the speech service the error will be returned in the ErrorDetails field.\n if (e.result?.errorDetails) {\n await this.cancelSpeech();\n // TODO: format the error message contained in 'errorDetails'\n this.fireCancelEvent(e.result.errorDetails);\n } else {\n if (!!this.privTranslator.recognized) {\n this.privTranslator.recognized(this.privTranslator, e);\n }\n }\n return;\n };\n\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.canceled = async (): Promise<void> => {\n if (this.privSpeechState !== SpeechState.Inactive) {\n try {\n await this.cancelSpeech();\n } catch (error) {\n this.privSpeechState = SpeechState.Inactive;\n }\n }\n };\n }\n }\n\n public get state(): SpeechState {\n return this.privSpeechState;\n }\n\n public set state(newState: SpeechState) {\n this.privSpeechState = newState;\n }\n\n public set authentication(token: IAuthentication) {\n this.privReco.authentication = token;\n }\n\n\n public onConnection(): void {\n this.privSpeechState = SpeechState.Connected;\n }\n\n public async onCancelSpeech(): Promise<void> {\n this.privSpeechState = SpeechState.Inactive;\n await this.cancelSpeech();\n }\n\n /**\n * Fire a cancel event\n * @param error\n */\n private fireCancelEvent(error: string): void {\n try {\n if (!!this.privTranslator.canceled) {\n const cancelEvent: ConversationTranslationCanceledEventArgs = new ConversationTranslationCanceledEventArgs(\n CancellationReason.Error,\n error,\n CancellationErrorCode.RuntimeError\n );\n\n this.privTranslator.canceled(this.privTranslator, cancelEvent);\n }\n } catch (e) {\n //\n }\n }\n\n private async cancelSpeech(): Promise<void> {\n try {\n this.stopContinuousRecognitionAsync();\n await this.privReco?.disconnect();\n this.privSpeechState = SpeechState.Inactive;\n } catch (e) {\n // ignore the error\n }\n }\n}\n\n/**\n * Join, leave or connect to a conversation.\n */\nexport class ConversationTranslator extends ConversationCommon implements IConversationTranslator, IDisposable {\n\n public canceled: (sender: ConversationHandler, event: ConversationTranslationCanceledEventArgs) => void;\n public conversationExpiration: (sender: IConversationTranslator, event: ConversationExpirationEventArgs) => void;\n public participantsChanged: (sender: IConversationTranslator, event: ConversationParticipantsChangedEventArgs) => void;\n public sessionStarted: (sender: ConversationHandler, event: SessionEventArgs) => void;\n public sessionStopped: (sender: ConversationHandler, event: SessionEventArgs) => void;\n public textMessageReceived: (sender: IConversationTranslator, event: ConversationTranslationEventArgs) => void;\n\n // Callbacks for whole conversation results\n public transcribed: (sender: IConversationTranslator, event: ConversationTranslationEventArgs) => void;\n public transcribing: (sender: IConversationTranslator, event: ConversationTranslationEventArgs) => void;\n\n // Callbacks for detecting speech/translation results from self\n public recognized: (sender: IConversationTranslator, event: TranslationRecognitionEventArgs) => void;\n public recognizing: (sender: IConversationTranslator, event: TranslationRecognitionEventArgs) => void;\n\n private privSpeechRecognitionLanguage: string;\n private privProperties: PropertyCollection;\n private privIsDisposed: boolean;\n private privCTRecognizer: ConversationTranslationRecognizer;\n private privIsSpeaking: boolean;\n private privConversation: ConversationImpl;\n private privErrors: IErrorMessages = ConversationConnectionConfig.restErrors;\n private privPlaceholderKey: string;\n private privPlaceholderRegion: string;\n\n public constructor(audioConfig?: AudioConfig) {\n super(audioConfig);\n this.privIsDisposed = false;\n this.privIsSpeaking = false;\n this.privPlaceholderKey = \"abcdefghijklmnopqrstuvwxyz012345\";\n this.privPlaceholderRegion = \"westus\";\n this.privProperties = new PropertyCollection();\n }\n\n public get properties(): PropertyCollection {\n return this.privProperties;\n }\n\n public get speechRecognitionLanguage(): string {\n return this.privSpeechRecognitionLanguage;\n }\n\n public get participants(): Participant[] {\n return this.privConversation?.participants;\n }\n\n private get canSpeak(): boolean {\n\n // is there a Conversation websocket available and has the Recognizer been set up\n if (!this.privConversation.isConnected || !this.privCTRecognizer) {\n return false;\n }\n\n // is the user already speaking\n if (this.privIsSpeaking || this.privCTRecognizer.state === SpeechState.Connected || this.privCTRecognizer.state === SpeechState.Connecting) {\n return false;\n }\n\n // is the user muted\n if (this.privConversation.isMutedByHost) {\n return false;\n }\n\n return true;\n }\n\n public onToken(token: IAuthentication): void {\n this.privCTRecognizer.authentication = token;\n }\n\n public setServiceProperty(name: string, value: string): void {\n const currentProperties: IStringDictionary<string> = JSON.parse(this.privProperties.getProperty(ServicePropertiesPropertyName, \"{}\")) as IStringDictionary<string>;\n\n currentProperties[name] = value;\n\n this.privProperties.setProperty(ServicePropertiesPropertyName, JSON.stringify(currentProperties));\n }\n\n /**\n * Join a conversation. If this is the host, pass in the previously created Conversation object.\n * @param conversation\n * @param nickname\n * @param lang\n * @param cb\n * @param err\n */\n public joinConversationAsync(conversation: IConversation, nickname: string, cb?: Callback, err?: Callback): void;\n public joinConversationAsync(conversationId: string, nickname: string, lang: string, cb?: Callback, err?: Callback): void;\n public joinConversationAsync(conversation: string | IConversation, nickname: string, param1?: string | Callback, param2?: Callback, param3?: Callback): void {\n\n try {\n\n if (typeof conversation === \"string\") {\n\n Contracts.throwIfNullOrUndefined(conversation, this.privErrors.invalidArgs.replace(\"{arg}\", \"conversation id\"));\n Contracts.throwIfNullOrWhitespace(nickname, this.privErrors.invalidArgs.replace(\"{arg}\", \"nickname\"));\n\n if (!!this.privConversation) {\n this.handleError(new Error(this.privErrors.permissionDeniedStart), param3);\n }\n\n let lang: string = param1 as string;\n if (lang === undefined || lang === null || lang === \"\") {\n lang = ConversationConnectionConfig.defaultLanguageCode;\n }\n\n // create a placeholder config\n this.privSpeechTranslationConfig = SpeechTranslationConfig.fromSubscription(\n this.privPlaceholderKey,\n this.privPlaceholderRegion);\n this.privSpeechTranslationConfig.setProfanity(ProfanityOption.Masked);\n this.privSpeechTranslationConfig.addTargetLanguage(lang);\n this.privSpeechTranslationConfig.setProperty(PropertyId[PropertyId.SpeechServiceConnection_RecoLanguage], lang);\n this.privSpeechTranslationConfig.setProperty(PropertyId[PropertyId.ConversationTranslator_Name], nickname);\n\n const propertyIdsToCopy: (string | PropertyId)[] = [\n PropertyId.SpeechServiceConnection_Host,\n PropertyId.ConversationTranslator_Host,\n PropertyId.SpeechServiceConnection_Endpoint,\n PropertyId.SpeechServiceConnection_ProxyHostName,\n PropertyId.SpeechServiceConnection_ProxyPassword,\n PropertyId.SpeechServiceConnection_ProxyPort,\n PropertyId.SpeechServiceConnection_ProxyUserName,\n \"ConversationTranslator_MultiChannelAudio\",\n \"ConversationTranslator_Region\"\n ];\n\n for (const prop of propertyIdsToCopy) {\n const value = this.privProperties.getProperty(prop);\n if (value) {\n const key = typeof prop === \"string\" ? prop : PropertyId[prop];\n this.privSpeechTranslationConfig.setProperty(key, value);\n }\n }\n\n const currentProperties = JSON.parse(this.privProperties.getProperty(ServicePropertiesPropertyName, \"{}\")) as IStringDictionary<string>;\n for (const prop of Object.keys(currentProperties)) {\n this.privSpeechTranslationConfig.setServiceProperty(prop, currentProperties[prop], ServicePropertyChannel.UriQueryParameter);\n }\n\n // join the conversation\n this.privConversation = new ConversationImpl(this.privSpeechTranslationConfig);\n this.privConversation.conversationTranslator = this;\n\n this.privConversation.joinConversationAsync(\n conversation,\n nickname,\n lang,\n ((result: string): void => {\n\n if (!result) {\n this.handleError(new Error(this.privErrors.permissionDeniedConnect), param3);\n }\n\n this.privSpeechTranslationConfig.authorizationToken = result;\n this.privConversation.room.isHost = false;\n\n // connect to the ws\n this.privConversation.startConversationAsync(\n ((): void => {\n this.handleCallback(param2, param3);\n }),\n ((error: any): void => {\n this.handleError(error, param3);\n }));\n\n }),\n ((error: any): void => {\n this.handleError(error, param3);\n }));\n\n } else if (typeof conversation === \"object\") {\n\n Contracts.throwIfNullOrUndefined(conversation, this.privErrors.invalidArgs.replace(\"{arg}\", \"conversation id\"));\n Contracts.throwIfNullOrWhitespace(nickname, this.privErrors.invalidArgs.replace(\"{arg}\", \"nickname\"));\n\n // save the nickname\n this.privProperties.setProperty(PropertyId.ConversationTranslator_Name, nickname);\n // ref the conversation object\n this.privConversation = conversation as ConversationImpl;\n // ref the conversation translator object\n this.privConversation.conversationTranslator = this;\n this.privConversation.room.isHost = true;\n\n Contracts.throwIfNullOrUndefined(this.privConversation, this.privErrors.permissionDeniedConnect);\n Contracts.throwIfNullOrUndefined(this.privConversation.room.token, this.privErrors.permissionDeniedConnect);\n\n this.privSpeechTranslationConfig = conversation.config;\n\n this.handleCallback(param1 as Callback, param2);\n } else {\n this.handleError(\n new Error(this.privErrors.invalidArgs.replace(\"{arg}\", \"invalid conversation type\")),\n param2);\n }\n\n } catch (error) {\n this.handleError(error, typeof param1 === \"string\" ? param3 : param2);\n }\n }\n\n /**\n * Leave the conversation\n * @param cb\n * @param err\n */\n public leaveConversationAsync(cb?: Callback, err?: Callback): void {\n\n marshalPromiseToCallbacks((async (): Promise<void> => {\n\n // stop the speech websocket\n await this.cancelSpeech();\n // stop the websocket\n await this.privConversation.endConversationImplAsync();\n // https delete request\n await this.privConversation.deleteConversationImplAsync();\n this.dispose();\n\n })(), cb, err);\n }\n\n /**\n * Send a text message\n * @param message\n * @param cb\n * @param err\n */\n public sendTextMessageAsync(message: string, cb?: Callback, err?: Callback): void {\n\n try {\n Contracts.throwIfNullOrUndefined(this.privConversation, this.privErrors.permissionDeniedSend);\n Contracts.throwIfNullOrWhitespace(message, this.privErrors.invalidArgs.replace(\"{arg}\", message));\n\n this.privConversation.sendTextMessageAsync(message, cb, err);\n } catch (error) {\n\n this.handleError(error, err);\n }\n }\n\n /**\n * Start speaking\n * @param cb\n * @param err\n */\n public startTranscribingAsync(cb?: Callback, err?: Callback): void {\n marshalPromiseToCallbacks((async (): Promise<void> => {\n try {\n Contracts.throwIfNullOrUndefined(this.privConversation, this.privErrors.permissionDeniedSend);\n Contracts.throwIfNullOrUndefined(this.privConversation.room.token, this.privErrors.permissionDeniedConnect);\n\n if (this.privCTRecognizer === undefined) {\n await this.connectTranslatorRecognizer();\n }\n Contracts.throwIfNullOrUndefined(this.privCTRecognizer, this.privErrors.permissionDeniedSend);\n\n if (!this.canSpeak) {\n this.handleError(new Error(this.privErrors.permissionDeniedSend), err);\n }\n\n await this.startContinuousRecognition();\n\n this.privIsSpeaking = true;\n } catch (error) {\n this.privIsSpeaking = false;\n await this.cancelSpeech();\n throw error;\n }\n })(), cb, err);\n }\n\n /**\n * Stop speaking\n * @param cb\n * @param err\n */\n public stopTranscribingAsync(cb?: Callback, err?: Callback): void {\n marshalPromiseToCallbacks((async (): Promise<void> => {\n try {\n if (!this.privIsSpeaking) {\n // stop speech\n await this.cancelSpeech();\n return;\n }\n\n // stop the recognition but leave the websocket open\n this.privIsSpeaking = false;\n await new Promise<void>((resolve: (value: void) => void, reject: (reason?: any) => void): void => {\n this.privCTRecognizer.stopContinuousRecognitionAsync(resolve, reject);\n });\n\n } catch (error) {\n await this.cancelSpeech();\n }\n })(), cb, err);\n }\n\n public isDisposed(): boolean {\n return this.privIsDisposed;\n }\n\n public dispose(reason?: string, success?: () => void, err?: (error: string) => void): void {\n marshalPromiseToCallbacks((async (): Promise<void> => {\n if (this.isDisposed && !this.privIsSpeaking) {\n return;\n }\n await this.cancelSpeech();\n this.privIsDisposed = true;\n this.privSpeechTranslationConfig.close();\n this.privSpeechRecognitionLanguage = undefined;\n this.privProperties = undefined;\n this.privAudioConfig = undefined;\n this.privSpeechTranslationConfig = undefined;\n this.privConversation.dispose();\n this.privConversation = undefined;\n })(), success, err);\n }\n\n /**\n * Cancel the speech websocket\n */\n private async cancelSpeech(): Promise<void> {\n try {\n this.privIsSpeaking = false;\n await this.privCTRecognizer?.onCancelSpeech();\n this.privCTRecognizer = undefined;\n } catch (e) {\n // ignore the error\n }\n }\n\n /**\n * Connect to the speech translation recognizer.\n * Currently there is no language validation performed before sending the SpeechLanguage code to the service.\n * If it's an invalid language the raw error will be: 'Error during WebSocket handshake: Unexpected response code: 400'\n * e.g. pass in 'fr' instead of 'fr-FR', or a text-only language 'cy'\n */\n private async connectTranslatorRecognizer(): Promise<void> {\n try {\n\n if (this.privAudioConfig === undefined) {\n this.privAudioConfig = AudioConfig.fromDefaultMicrophoneInput();\n }\n\n // clear the temp subscription key if it's a participant joining\n if (this.privSpeechTranslationConfig.getProperty(PropertyId[PropertyId.SpeechServiceConnection_Key])\n === this.privPlaceholderKey) {\n this.privSpeechTranslationConfig.setProperty(PropertyId[PropertyId.SpeechServiceConnection_Key], \"\");\n }\n\n const convGetter = (): ConversationImpl => this.privConversation;\n this.privCTRecognizer = new ConversationTranslationRecognizer(this.privSpeechTranslationConfig, this.privAudioConfig, this, convGetter);\n } catch (error) {\n await this.cancelSpeech();\n throw error;\n }\n }\n\n /**\n * Handle the start speaking request\n */\n private startContinuousRecognition(): Promise<void> {\n return new Promise((resolve: () => void, reject: (error: string) => void): void => {\n this.privCTRecognizer.startContinuousRecognitionAsync(resolve, reject);\n });\n }\n}\n"]}