Barrymore, ¿cuál es el rumor alrededor de Voximplant? Implementado sockets web, señor


WebSocket es un estándar progresivo para la comunicación full-duplex (bidireccional) entre un cliente y un servicio de terceros en tiempo real. Los sockets web se utilizan para organizar el intercambio continuo de datos sin solicitudes HTTP adicionales.

Y nos complace informarle que todo esto ha sido posible en Voximplant gracias al nuevo módulo VoxEngine , que se llama - sorpresa - WebSocket . A partir de ahora, podrá transferir texto y audio, aprovechando al máximo los sockets web. En pocas palabras, tiene otra herramienta para actualizar su aplicación.

En este artículo, aprenderá cómo crear una conexión WebSocket saliente, transferir una transmisión de audio a través de ella y convertirla a texto usando la API de Google Cloud Speech-to-Text .
Tenga en cuenta que Voximplant tiene una funcionalidad incorporada para convertir voz a texto en tiempo real bajo el control del módulo ASR . Este módulo utiliza funciones de Google, Yandex y Tinkoff, consulte los detalles aquí .

El artículo actual describe el caso en el que desea utilizar un servicio de terceros para convertir voz a texto y / o gastar dinero de su cuenta, y no de la cuenta de Voximplant.

Nuestro módulo proporciona dos formatos de trabajo:
  • creando una conexión saliente;
  • recibir una conexión entrante y crear un socket web para ello.

Saliente


Lo primero que debe hacer al crear una conexión saliente es ejecutar el script VoxEngine. Luego llame al método VoxEngine.createWebSocket , que creará el objeto WebSocket . Este método toma 2 parámetros: URL en el formato 'wss: // + dominio + ruta' y protocolos (opcional). Así es como se vería en el código:

VoxEngine.addEventListener(AppEvents.CallAlerting, function(e) { const webSocket = VoxEngine.createWebSocket( /*url*/ "wss://your_link/"); //       }); 

Si todo funciona, el método call.sendMediaTo enviará la secuencia de audio al socket y WebSocket.send , a su vez, enviará la secuencia de audio decodificada en formato JSON a través de él. Como resultado, recibirá mensajes del servicio que procesa las solicitudes.

Se necesita el método WebSocket.close para cerrar la conexión. Tenga en cuenta que la conexión se puede cerrar tanto en el lado del cliente como en el lado del servidor.

Bandeja de entrada


Para permitir las conexiones entrantes, debe notificarlo a través de VoxEngine.allowWebSocketConnections y también suscribirse al evento AppEvents.WebSocket . Entonces será posible aceptar la conexión entrante y obtener el objeto WebSocket: event.WebSocket. Vea el código a continuación:

 VoxEngine.allowWebSocketConnections(); VoxEngine.addEventListener(AppEvents.WebSocket, function(e) { //       }); 

Para crear un socket web entrante, necesita el control accessSecureURL. Se puede tomar del evento AppEvents.Started o la respuesta a la solicitud HTTP que inició la sesión. Tenga en cuenta que "https" debe cambiarse a 'wss' en la URL.

Los pasos restantes son idénticos a los presentados en el esquema de conexión saliente.

Necesitarás


Para implementar la tecnología WebSocket y el reconocimiento de voz en su aplicación, necesitará:
  • Cuenta Voximplant. Si no lo tiene, siéntase libre de registrarse aquí ;
  • Aplicación Voximplant, así como un script, una regla y un solo usuario. Todo esto se creará en este tutorial;
  • backend simple (iniciaremos el servidor en node.js) con la biblioteca del cliente de Cloud conectada para la API de voz a texto;
  • cliente web para realizar una llamada (utilizaremos el teléfono web en phone.voximplant.com ).

1. Configuración de VOXIMPLANT


Para comenzar, inicie sesión en su cuenta en manage.voximplant.com/auth . En el menú de la izquierda, haga clic en "Aplicaciones", cree uno nuevo y asígnele el nombre websocket. Vaya a su aplicación, cambie a la pestaña Scripts, cree un script y pegue el siguiente código en él:

 require(Modules.WebSocket); VoxEngine.addEventListener(AppEvents.CallAlerting, function(e) { call = e.call; call.answer(); const webSocket = VoxEngine.createWebSocket( /*url*/ "wss://your_ngrok_link/"); webSocket.addEventListener(WebSocketEvents.ERROR, function(e) { Logger.write("LOG OUTGOING: WebSocketEvents.ERROR"); call.sendMessage("LOG OUTGOING: WebSocketEvents.ERROR"); }); webSocket.addEventListener(WebSocketEvents.CLOSE, function(e) { Logger.write("LOG OUTGOING: WebSocketEvents.CLOSE: " + e.reason); call.sendMessage("LOG OUTGOING: WebSocketEvents.CLOSE: " + e.reason); }); webSocket.addEventListener(WebSocketEvents.OPEN, function(e) { Logger.write("LOG OUTGOING: WebSocketEvents.OPEN"); Logger.write(JSON.stringify(e)) call.sendMessage("LOG OUTGOING: WebSocketEvents.OPEN"); }); webSocket.addEventListener(WebSocketEvents.MESSAGE, function(e) { Logger.write("LOG OUTGOING: WebSocketEvents.MESSAGE: " + e.text); call.sendMessage("LOG OUTGOING: WebSocketEvents.MESSAGE: " + e.text); if (e.text == "Hi there, I am a WebSocket server") { call.sendMediaTo(webSocket, { encoding: WebSocketAudioEncoding.ULAW, "tag": "MyAudioStream", "customParameters": { "param1": "12345" } }); } }); call.addEventListener(CallEvents.Disconnected, function(e) { Logger.write("LOG OUTGOING: terminating in 1 sec"); webSocket.close(); setTimeout(VoxEngine.terminate, 1000); }); }); 

Este script de VoxEngine envía una transmisión de audio a WebSocket y también rastrea sus eventos (ERROR, CERRAR, ABRIR, MENSAJE). Podemos profundizar en los detalles del guión un poco más tarde.

Ahora, vamos a la pestaña "Enrutamiento", haga clic en "Nueva regla" y llámela socketRule. Ahora solo queda seleccionar su script y dejar la máscara por defecto (. *).


Lo último que debe hacer en esta etapa es crear un usuario. Cambie a la pestaña “Usuarios”, haga clic en “Crear usuario”, especifique un nombre (por ejemplo, socketUser) y contraseña, luego haga clic en “Crear”. Necesitaremos este par de nombre de usuario / contraseña para la autenticación en el cliente web en el último paso.


La configuración está completa, pero antes de comenzar a crear el servidor, veamos cómo funciona el módulo WebSocket en nuestro escenario.

2. Detalles del guión


El módulo WebSocket permite a los desarrolladores abrir una conexión estable y enviar datos a través de ella. Para usar este módulo, debemos conectarlo al comienzo del script:

 require(Modules.WebSocket); 

A través del método createWebSocket, determinamos la URL y los protocolos (opcional). Puede aprender cómo obtener la URL de WebSocket en la siguiente sección.

 const webSocket = VoxEngine.createWebSocket( /*url*/ "wss://your_ngrok_link/"); 

Después de crear el objeto WebSocket, continuamos administrando la llamada dentro del controlador. A saber, enviamos los medios al objeto WebSocket usando el método call.sendMediaTo.

Aquí puede establecer el formato de codificación preferido, la etiqueta y algunos parámetros personalizados. Si no configura la codificación, se utilizará PCM8 de forma predeterminada.

Se llama a este método cuando se recibe un mensaje de conexión exitoso. En nuestro escenario, el código de llamada se ve así:

 call.sendMediaTo(webSocket, { encoding: WebSocketAudioEncoding.ULAW, "tag": "MyAudioStream", "customParameters": { "param1": "12345" } }); 

Todos los demás eventos de WebSocket que ve en el código son para depuración; envían información al registro de la sesión de Voximplant. Puedes eliminarlos si quieres.

Finalmente, agregamos el controlador de finalización de transferencia de datos correcto. En nuestro caso, la sesión de Voximplant finalizará su trabajo 1 segundo después del final de la llamada establecida ( Desconectado ):

 call.addEventListener(CallEvents.Disconnected, function(e) { Logger.write("LOG OUTGOING: terminating in 1 sec"); webSocket.close(); setTimeout(VoxEngine.terminate, 1000); }); 

Ahora que la lógica del guión es clara, es hora de pasar a la siguiente parte muy importante de nuestro ejemplo.

3. Backend


Primero, asegúrese de que Node.js. esté instalado en su computadora. Puede descargarlo del sitio principal de Node.js. Luego, ejecute los siguientes comandos en la ventana de terminal, uno tras otro, para configurar el entorno de trabajo:

 npm install express npm install ws npm install @google-cloud/speech 

Y cuando haya terminado, cree un archivo JS vacío y coloque el siguiente código allí (los matices del código se resaltarán a continuación):

 const app = require('express')(); const http = require('http').createServer(app); const WebSocket = require('ws'); const fs = require('fs'); const wss = new WebSocket.Server({ server: http }); //     Google Cloud const speech = require('@google-cloud/speech'); //    const client = new speech.SpeechClient(); const config = { encoding: 'MULAW', sampleRateHertz: 8000, languageCode: 'ru-RU', }; const request = { config, interimResults: true, }; let audioInput = []; let recognizeStream = null; process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0; app.get('/', function(req, res) { res.send('<h1>Hello world</h1>'); }); wss.on('connection', (ws) => { //  ,       var wstream = fs.createWriteStream('myBinaryFile'); //   audioInput audioInput = []; //    recognizeStream = client .streamingRecognize(request) .on('error', err => { ws.close(); }) .on('data', data => { ws.send(data.results[0].alternatives[0].transcript) process.stdout.write( data.results[0] && data.results[0].alternatives[0] ? `Transcription: ${data.results[0].alternatives[0].transcript}\n` : `\n\nError occurred, press Ctrl+C\n` ) }); ws.on('close', (message) => { console.log('The time limit for speech recognition has been reached. Please disconnect and call again.'); wstream.end(); }) //  ,     message ws.on('message', (message) => { //     base64  recognizeStream try { let data = JSON.parse(message) if (data.event == "media") { let b64data = data.media.payload; let buff = new Buffer.from(b64data, 'base64'); recognizeStream.write(buff); wstream.write(buff); } } catch (err) { console.log(message) } }); //      ws.send('Hi there, I am a WebSocket server'); }); http.listen(3000, function() { console.log('listening on *:3000'); }); 

Ahora que el servidor está configurado, nos ayudará a realizar el reconocimiento de voz. Pruebe su solución localmente creando un túnel en localhost 3000 usando ngrok.

Para hacer esto, siga estos pasos:
  1. Instale ngrok siguiendo las instrucciones en su sitio web .
  2. Especifique su authtoken para ngrok para vincular al cliente a esta cuenta.
  3. Ejecute el node your_file_name.js para iniciar su servidor en localhost: 3000.
  4. Vaya a la carpeta ngrok en su computadora y ejecute el ./ngrok http 3000 para hacer un túnel entre el servidor local en ejecución y la URL pública.

Preste atención a la URL pública generada, la usamos como una URL de WebSocket con el prefijo 'wss' en el script:



4. Reconocimiento de voz


Probablemente haya notado que nuestro código de back-end contiene líneas relacionadas con Google Cloud.

La biblioteca en sí se importa de la siguiente manera:

 const speech = require('@google-cloud/speech'); 

Ahora debe especificar cómo procesar la solicitud de reconocimiento de voz. Para hacer esto, seleccione codificación, sampleRateHertz y languageCode en la configuración generada:

 const config = { encoding: 'MULAW', sampleRateHertz: 8000, languageCode: 'en-US', }; 

A continuación, cree una secuencia de escritura que le permita guardar los datos transferidos en un archivo:

 var wstream = fs.createWriteStream('myBinaryFile'); 

Cuando todo está configurado, debe analizar el mensaje y poner los datos de audio en formato base64 en RecognizeStream:

 let data = JSON.parse(message) if (data.event == "media") { b64data = data.media.payload; let buff = new Buffer.from(b64data, 'base64'); recognizeStream.write(buff); wstream.write(buff); } 

Inmediatamente después de esto, se iniciará una solicitud de reconocimiento y comenzará el procesamiento de esta solicitud:

 recognizeStream = client .streamingRecognize(request) .on('data', data => { ws.send(data.results[0].alternatives[0].transcript) }); 

Finalmente, proporcione las credenciales de su cuenta de servicio para conectar la biblioteca de Google a su backend. Para hacer esto, vaya a la página de autenticación de Google y siga todos los pasos enumerados allí. Luego ejecute el comando de exportación en el mismo espacio de trabajo (en la misma pestaña "Terminal") que el node your_file_name.js:

 export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/[FILE_NAME].json" 

Tomas de lanzamiento


Abra phone.voximplant.com , complete el formulario y haga clic en Iniciar sesión. El nombre de usuario y la contraseña se refieren al usuario creado en el paso 1:


Después de una autorización exitosa, haga clic en Llamar y comience a hablar. La nube de voz a texto convertirá su voz en texto en tiempo real, y puede ver este texto en la ventana del terminal.

Lo hiciste, felicidades! Esperamos que te haya gustado el artículo y te deseamos más integración y nuevos desafíos.

Source: https://habr.com/ru/post/476902/


All Articles