cogserv-speechtotext-client
Version:
NodeJS service + client package for using Microsoft Translator in front end applications
130 lines (97 loc) • 3.66 kB
JavaScript
const debug = require('debug')('translationClient');
const translationService = require('ms-translator-speech-service');
const EventEmitter = require('events').EventEmitter;
const util = require('util');
TranslationClient = function(options) {
this.options = options;
this.transSocket;
this.clientSocket;
this.translator = new translationService(this.options);
EventEmitter.call(this);
};
util.inherits(TranslationClient, EventEmitter);
TranslationClient.prototype.createService = function createService() {
this.io = require('socket.io')(3100);
this.io.on('connection', this._onConnection(this.options));
};
TranslationClient.prototype._startTranslationService = function _startTranslationService() {
this.translator.start((error, transSocket) => {
this.transSocket = transSocket;
if (error) {
this.clientSocket.emit('service:error', error);
this.emit('error', error);
return;
}
debug('translation endpoint client connected.');
this._initTranslationEvents();
this.clientSocket.emit('service:ready');
});
};
TranslationClient.prototype._initTranslationEvents = function _initTranslationEvents() {
this.transSocket.on('message', (data) => {
debug('translation endpoint message received: ', data);
const prop = `${data.type}Data`;
this.clientSocket.emit('translation', data[prop]);
});
this.transSocket.on('close', (reasonCode, description) => {
debug('translation socket closed: ' + reasonCode);
this.emit('close', reasonCode);
});
this.transSocket.on('error', (error) => {
debug('translation endpoint error', error);
this.emit('error', error);
});
this.clientSocket.on('record:stop', () => {
debug('recording stopped');
// naive way to wait for the last recorded blobs to be sent before closing
setTimeout(() => {
this.transSocket.close();
this._removeTranslationEvents();
}, 2000);
});
this.clientSocket.on('audio', (blob) => {
debug('audio blob received:', blob);
this.transSocket.sendBytes(blob);
});
this.clientSocket.on('disconnect', () => {
debug('client websocket disconnected');
});
};
TranslationClient.prototype._removeTranslationEvents = function _removeTranslationEvents() {
const transEvents = ['error', 'close', 'message'];
if (this.transSocket) transEvents.forEach((e) => this.transSocket.removeAllListeners(e));
};
TranslationClient.prototype._removeClientEvents = function _removeClientEvents() {
const clientEvents = ['audio', 'record:stop'];
if (this.clientSocket) clientEvents.forEach((e) => this.clientSocket.removeAllListeners(e));
if (this.io) this.io.removeAllListeners('connection');
};
TranslationClient.prototype._onConnection = function _onConnection() {
return (clientSocket) => {
debug('client websocket connected');
this.clientSocket = clientSocket;
this.clientSocket.emit('socket:connected');
this.clientSocket.on('record:start', () => {
this._startTranslationService();
});
};
};
TranslationClient.prototype.stopService = function stopService() {
this.stopTranslator();
this.stopClient();
this.emit('service:all:stop');
};
TranslationClient.prototype.stopTranslator = function stopTranslator() {
debug('stopping translation endpoint');
this.translator.stop(() => {
this._removeTranslationEvents();
this.emit('service:translator:stop');
});
};
TranslationClient.prototype.stopClient = function stopClient() {
debug('stopping browser socket connection');
this.io.close();
this._removeClientEvents();
this.emit('service:client:stop');
};
module.exports = TranslationClient;