UNPKG

@voice-ping/cognitive-services-speech

Version:

VoicePing Cognitive Services Speech SDK for JavaScript forked from Microsoft

424 lines (422 loc) 19.8 kB
"use strict"; // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. // Multi-device Conversation is a Preview feature. Object.defineProperty(exports, "__esModule", { value: true }); var Exports_1 = require("../../common.speech/Exports"); var Contracts_1 = require("../Contracts"); var Exports_2 = require("../Exports"); var Conversation_1 = require("./Conversation"); var Exports_3 = require("./Exports"); var SpeechState; (function (SpeechState) { SpeechState[SpeechState["Inactive"] = 0] = "Inactive"; SpeechState[SpeechState["Connecting"] = 1] = "Connecting"; SpeechState[SpeechState["Connected"] = 2] = "Connected"; })(SpeechState = exports.SpeechState || (exports.SpeechState = {})); /*** * Join, leave or connect to a conversation. */ var ConversationTranslator = /** @class */ (function () { function ConversationTranslator(audioConfig) { var _this = this; this.privIsDisposed = false; this.privIsSpeaking = false; this.privSpeechState = SpeechState.Inactive; this.privErrors = Exports_1.ConversationConnectionConfig.restErrors; this.privPlaceholderKey = "abcdefghijklmnopqrstuvwxyz012345"; this.privPlaceholderRegion = "westus"; /** Recognizer callbacks */ this.onSpeechConnected = function (e) { _this.privSpeechState = SpeechState.Connected; }; this.onSpeechDisconnected = function (e) { _this.privSpeechState = SpeechState.Inactive; _this.cancelSpeech(); }; this.onSpeechRecognized = function (r, e) { // TODO: add support for getting recognitions from here if own speech var _a; // if there is an error connecting to the conversation service from the speech service the error will be returned in the ErrorDetails field. if ((_a = e.result) === null || _a === void 0 ? void 0 : _a.errorDetails) { _this.cancelSpeech(); // TODO: format the error message contained in 'errorDetails' _this.fireCancelEvent(e.result.errorDetails); } }; this.onSpeechRecognizing = function (r, e) { // TODO: add support for getting recognitions from here if own speech }; this.onSpeechCanceled = function (r, e) { if (_this.privSpeechState !== SpeechState.Inactive) { try { _this.cancelSpeech(); } catch (error) { _this.privSpeechState = SpeechState.Inactive; } } }; this.onSpeechSessionStarted = function (r, e) { _this.privSpeechState = SpeechState.Connected; }; this.onSpeechSessionStopped = function (r, e) { _this.privSpeechState = SpeechState.Inactive; }; this.privProperties = new Exports_2.PropertyCollection(); this.privAudioConfig = audioConfig; } Object.defineProperty(ConversationTranslator.prototype, "properties", { get: function () { return this.privProperties; }, enumerable: true, configurable: true }); Object.defineProperty(ConversationTranslator.prototype, "speechRecognitionLanguage", { get: function () { return this.privSpeechRecognitionLanguage; }, enumerable: true, configurable: true }); Object.defineProperty(ConversationTranslator.prototype, "participants", { get: function () { var _a; return (_a = this.privConversation) === null || _a === void 0 ? void 0 : _a.participants; }, enumerable: true, configurable: true }); ConversationTranslator.prototype.joinConversationAsync = function (conversation, nickname, param1, param2, param3) { var _this = this; try { if (typeof conversation === "string") { Contracts_1.Contracts.throwIfNullOrUndefined(conversation, this.privErrors.invalidArgs.replace("{arg}", "conversation id")); Contracts_1.Contracts.throwIfNullOrWhitespace(nickname, this.privErrors.invalidArgs.replace("{arg}", "nickname")); if (!!this.privConversation) { this.handleError(new Error(this.privErrors.permissionDeniedStart), param3); } var lang = param1; if (lang === undefined || lang === null || lang === "") { lang = Exports_1.ConversationConnectionConfig.defaultLanguageCode; } // create a placecholder config this.privSpeechTranslationConfig = Exports_2.SpeechTranslationConfig.fromSubscription(this.privPlaceholderKey, this.privPlaceholderRegion); this.privSpeechTranslationConfig.setProfanity(Exports_2.ProfanityOption.Masked); this.privSpeechTranslationConfig.addTargetLanguage(lang); this.privSpeechTranslationConfig.setProperty(Exports_2.PropertyId[Exports_2.PropertyId.SpeechServiceConnection_RecoLanguage], lang); this.privSpeechTranslationConfig.setProperty(Exports_2.PropertyId[Exports_2.PropertyId.ConversationTranslator_Name], nickname); var endpoint = this.privProperties.getProperty(Exports_2.PropertyId.ConversationTranslator_Host); if (endpoint) { this.privSpeechTranslationConfig.setProperty(Exports_2.PropertyId[Exports_2.PropertyId.ConversationTranslator_Host], endpoint); } var speechEndpointHost = this.privProperties.getProperty(Exports_2.PropertyId.SpeechServiceConnection_Host); if (speechEndpointHost) { this.privSpeechTranslationConfig.setProperty(Exports_2.PropertyId[Exports_2.PropertyId.SpeechServiceConnection_Host], speechEndpointHost); } // join the conversation this.privConversation = new Conversation_1.ConversationImpl(this.privSpeechTranslationConfig); this.privConversation.conversationTranslator = this; this.privConversation.joinConversationAsync(conversation, nickname, lang, (function (result) { if (!result) { _this.handleError(new Error(_this.privErrors.permissionDeniedConnect), param3); } _this.privSpeechTranslationConfig.authorizationToken = result; // connect to the ws _this.privConversation.startConversationAsync((function () { _this.handleCallback(param2, param3); }), (function (error) { _this.handleError(error, param3); })); }), (function (error) { _this.handleError(error, param3); })); } else if (typeof conversation === "object") { Contracts_1.Contracts.throwIfNullOrUndefined(conversation, this.privErrors.invalidArgs.replace("{arg}", "conversation id")); Contracts_1.Contracts.throwIfNullOrWhitespace(nickname, this.privErrors.invalidArgs.replace("{arg}", "nickname")); // save the nickname this.privProperties.setProperty(Exports_2.PropertyId.ConversationTranslator_Name, nickname); // ref the conversation object this.privConversation = conversation; // ref the conversation translator object this.privConversation.conversationTranslator = this; Contracts_1.Contracts.throwIfNullOrUndefined(this.privConversation, this.privErrors.permissionDeniedConnect); Contracts_1.Contracts.throwIfNullOrUndefined(this.privConversation.room.token, this.privErrors.permissionDeniedConnect); this.privSpeechTranslationConfig = conversation.config; this.handleCallback(param1, param2); } else { this.handleError(new Error(this.privErrors.invalidArgs.replace("{arg}", "invalid conversation type")), param2); } } catch (error) { this.handleError(error, typeof param1 === "string" ? param3 : param2); } }; /** * Leave the conversation * @param cb * @param err */ ConversationTranslator.prototype.leaveConversationAsync = function (cb, err) { var _this = this; try { // stop the speech websocket this.cancelSpeech(); // stop the websocket this.privConversation.endConversationAsync((function () { // https delete request _this.privConversation.deleteConversationAsync((function () { _this.handleCallback(cb, err); _this.dispose(); }), (function (error) { _this.handleError(error, err); })); }), (function (error) { _this.handleError(error, err); })); } catch (error) { this.handleError(error, err); } }; /** * Send a text message * @param message * @param cb * @param err */ ConversationTranslator.prototype.sendTextMessageAsync = function (message, cb, err) { var _a; try { Contracts_1.Contracts.throwIfNullOrUndefined(this.privConversation, this.privErrors.permissionDeniedSend); Contracts_1.Contracts.throwIfNullOrWhitespace(message, this.privErrors.invalidArgs.replace("{arg}", message)); (_a = this.privConversation) === null || _a === void 0 ? void 0 : _a.sendTextMessageAsync(message, cb, err); } catch (error) { this.handleError(error, err); } }; /** * Start speaking * @param cb * @param err */ ConversationTranslator.prototype.startTranscribingAsync = function (cb, err) { var _this = this; try { Contracts_1.Contracts.throwIfNullOrUndefined(this.privConversation, this.privErrors.permissionDeniedSend); Contracts_1.Contracts.throwIfNullOrUndefined(this.privConversation.room.token, this.privErrors.permissionDeniedConnect); if (!this.canSpeak) { this.handleError(new Error(this.privErrors.permissionDeniedSend), err); } if (this.privTranslationRecognizer === undefined) { this.connectTranslatorRecognizer((function () { _this.startContinuousRecognition((function () { _this.privIsSpeaking = true; _this.handleCallback(cb, err); }), (function (error) { _this.privIsSpeaking = false; // this.fireCancelEvent(error); _this.cancelSpeech(); _this.handleError(error, err); })); }), (function (error) { _this.handleError(error, err); })); } else { this.startContinuousRecognition((function () { _this.privIsSpeaking = true; _this.handleCallback(cb, err); }), (function (error) { _this.privIsSpeaking = false; // this.fireCancelEvent(error); _this.cancelSpeech(); _this.handleError(error, err); })); } } catch (error) { this.handleError(error, err); this.cancelSpeech(); } }; /** * Stop speaking * @param cb * @param err */ ConversationTranslator.prototype.stopTranscribingAsync = function (cb, err) { var _this = this; var _a; try { if (!this.privIsSpeaking) { // stop speech this.cancelSpeech(); this.handleCallback(cb, err); return; } // stop the recognition but leave the websocket open this.privIsSpeaking = false; (_a = this.privTranslationRecognizer) === null || _a === void 0 ? void 0 : _a.stopContinuousRecognitionAsync(function () { _this.handleCallback(cb, err); }, function (error) { _this.handleError(error, err); _this.cancelSpeech(); }); } catch (error) { this.handleError(error, err); this.cancelSpeech(); } }; ConversationTranslator.prototype.isDisposed = function () { return this.privIsDisposed; }; ConversationTranslator.prototype.dispose = function (reason) { var _a, _b; if (this.isDisposed && !this.privIsSpeaking) { return; } this.cancelSpeech(); this.privIsDisposed = true; (_a = this.privSpeechTranslationConfig) === null || _a === void 0 ? void 0 : _a.close(); this.privSpeechRecognitionLanguage = undefined; this.privProperties = undefined; this.privAudioConfig = undefined; this.privSpeechTranslationConfig = undefined; (_b = this.privConversation) === null || _b === void 0 ? void 0 : _b.dispose(); this.privConversation = undefined; }; /** * Connect to the speech translation recognizer. * Currently there is no language validation performed before sending the SpeechLanguage code to the service. * If it's an invalid language the raw error will be: 'Error during WebSocket handshake: Unexpected response code: 400' * e.g. pass in 'fr' instead of 'fr-FR', or a text-only language 'cy' * @param cb * @param err */ ConversationTranslator.prototype.connectTranslatorRecognizer = function (cb, err) { try { if (this.privAudioConfig === undefined) { this.privAudioConfig = Exports_2.AudioConfig.fromDefaultMicrophoneInput(); } // clear the temp subscription key if it's a participant joining if (this.privSpeechTranslationConfig.getProperty(Exports_2.PropertyId[Exports_2.PropertyId.SpeechServiceConnection_Key]) === this.privPlaceholderKey) { this.privSpeechTranslationConfig.setProperty(Exports_2.PropertyId[Exports_2.PropertyId.SpeechServiceConnection_Key], ""); } // TODO var token = encodeURIComponent(this.privConversation.room.token); var endpointHost = this.privSpeechTranslationConfig.getProperty(Exports_2.PropertyId[Exports_2.PropertyId.SpeechServiceConnection_Host], Exports_1.ConversationConnectionConfig.speechHost); endpointHost = endpointHost.replace("{region}", this.privConversation.room.cognitiveSpeechRegion); var url = "wss://" + endpointHost + Exports_1.ConversationConnectionConfig.speechPath + "?" + Exports_1.ConversationConnectionConfig.configParams.token + "=" + token; this.privSpeechTranslationConfig.setProperty(Exports_2.PropertyId[Exports_2.PropertyId.SpeechServiceConnection_Endpoint], url); this.privTranslationRecognizer = new Exports_2.TranslationRecognizer(this.privSpeechTranslationConfig, this.privAudioConfig); this.privTranslationRecognizerConnection = Exports_2.Connection.fromRecognizer(this.privTranslationRecognizer); this.privTranslationRecognizerConnection.connected = this.onSpeechConnected; this.privTranslationRecognizerConnection.disconnected = this.onSpeechDisconnected; this.privTranslationRecognizer.recognized = this.onSpeechRecognized; this.privTranslationRecognizer.recognizing = this.onSpeechRecognizing; this.privTranslationRecognizer.canceled = this.onSpeechCanceled; this.privTranslationRecognizer.sessionStarted = this.onSpeechSessionStarted; this.privTranslationRecognizer.sessionStopped = this.onSpeechSessionStopped; this.handleCallback(cb, err); } catch (error) { this.handleError(error, err); this.cancelSpeech(); // this.fireCancelEvent(error); ? } }; /** * Handle the start speaking request * @param cb * @param err */ ConversationTranslator.prototype.startContinuousRecognition = function (cb, err) { this.privTranslationRecognizer.startContinuousRecognitionAsync(cb, err); }; /** * Fire a cancel event * @param error */ ConversationTranslator.prototype.fireCancelEvent = function (error) { var _a, _b, _c, _d, _e, _f, _g; try { if (!!this.canceled) { var cancelEvent = new Exports_3.ConversationTranslationCanceledEventArgs((_b = (_a = error) === null || _a === void 0 ? void 0 : _a.reason, (_b !== null && _b !== void 0 ? _b : Exports_2.CancellationReason.Error)), (_d = (_c = error) === null || _c === void 0 ? void 0 : _c.errorDetails, (_d !== null && _d !== void 0 ? _d : error)), (_f = (_e = error) === null || _e === void 0 ? void 0 : _e.errorCode, (_f !== null && _f !== void 0 ? _f : Exports_2.CancellationErrorCode.RuntimeError)), undefined, (_g = error) === null || _g === void 0 ? void 0 : _g.sessionId); this.canceled(this, cancelEvent); } } catch (e) { // } }; /** * Cancel the speech websocket */ ConversationTranslator.prototype.cancelSpeech = function () { var _a, _b; try { this.privIsSpeaking = false; (_a = this.privTranslationRecognizer) === null || _a === void 0 ? void 0 : _a.stopContinuousRecognitionAsync(); (_b = this.privTranslationRecognizerConnection) === null || _b === void 0 ? void 0 : _b.closeConnection(); this.privTranslationRecognizerConnection = undefined; this.privTranslationRecognizer = undefined; this.privSpeechState = SpeechState.Inactive; } catch (e) { // ignore the error } }; Object.defineProperty(ConversationTranslator.prototype, "canSpeak", { get: function () { // is there a Conversation websocket available if (!this.privConversation.isConnected) { return false; } // is the user already speaking if (this.privIsSpeaking || this.privSpeechState === SpeechState.Connected || this.privSpeechState === SpeechState.Connecting) { return false; } // is the user muted if (this.privConversation.isMutedByHost) { return false; } return true; }, enumerable: true, configurable: true }); ConversationTranslator.prototype.handleCallback = function (cb, err) { if (!!cb) { try { cb(); } catch (e) { if (!!err) { err(e); } } cb = undefined; } }; ConversationTranslator.prototype.handleError = function (error, err) { if (!!err) { if (error instanceof Error) { var typedError = error; err(typedError.name + ": " + typedError.message); } else { err(error); } } }; return ConversationTranslator; }()); exports.ConversationTranslator = ConversationTranslator; //# sourceMappingURL=ConversationTranslator.js.map