巴里摩尔,Voximplant的热门话题是什么? 已实现的网络套接字,先生


WebSocket是用于客户端与第三方服务之间实时全双工(双向)通信的渐进标准。 Web套接字用于组织连续的数据交换,而无需其他HTTP请求。

并且我们很高兴地通知您,由于新的VoxEngine模块(称为-Surprise - WebSocket) ,所有这些在Voximplant中已经成为可能。 从现在开始,您将能够充分利用Web套接字传输文本和音频。 简而言之,您还有另一个工具可以升级您的应用程序。

在本文中,您将学习如何创建出站WebSocket连接,如何通过它传输音频流,以及如何使用Google Cloud Speech-to-Text API将其转换为文本。
请注意,Voximplant具有内置功能,可在ASR模块的控制下将语音实时转换为文本。 该模块使用Google,Yandex和Tinkoff的功能,请参见此处的详细信息。

当前文章介绍了您要使用第三方服务将语音转换为文本和/或从其帐户而不是从Voximplant帐户花费的情况。

我们的模块提供两种工作格式:
  • 建立外向连接;
  • 接收传入的连接并为其创建Web套接字。

外向


创建出站连接时,您要做的第一件事是运行VoxEngine脚本。 然后调用VoxEngine.createWebSocket方法,该方法将创建WebSocket对象。 此方法有两个参数:格式为“ wss:// + +域+路径”的URL和协议(可选)。 这是它在代码中的外观:

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

如果一切正常,则call.sendMediaTo方法会将音频流发送到套接字,而WebSocket.send将通过它以JSON格式发送解码后的音频流。 结果,您将从处理请求的服务接收消息。

需要WebSocket.close方法来关闭连接。 请注意,可以在客户端和服务器端都关闭连接。

收件箱


为了允许传入连接,必须通过VoxEngine.allowWebSocketConnections报告此事件 ,并订阅AppEvents.WebSocket事件。 然后,可以接受传入的连接并获取WebSocket:event.WebSocket对象。 请参见下面的代码:

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

要创建传入的Web套接字,您需要accessSecureURL控件。 它可以从AppEvents.Started事件或启动会话的HTTP请求的响应中获取。 请注意,URL中的“ https”必须更改为“ wss”。

其余步骤与传出连接方案中介绍的步骤相同。

您将需要


要在您的应用程序中实现WebSocket技术和语音识别,您将需要:
  • Voximplant帐户。 如果您还没有,请随时在这里注册;
  • Voximplant应用程序以及脚本,规则和单个用户。 所有这些都将在本教程中创建。
  • 简单的后端(我们将在node.js上启动服务器),并已连接了用于语音转文本API的Cloud客户端库;
  • 用于拨打电话的网络客户端(我们将使用phone.voximplant.com上的网络电话)。

1. VOXIMPLANT设置


首先,请登录至manage.voximplant.com/auth的帐户。 在左侧菜单中,单击“应用程序”,创建一个新应用程序并将其命名为websocket。 进入您的应用程序,切换到“脚本”选项卡,创建一个脚本并将以下代码粘贴到其中:

 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); }); }); 

此VoxEngine脚本将音频流发送到WebSocket,并跟踪其事件(错误,关闭,打开,消息)。 我们稍后可以深入研究脚本的细节。

现在,让我们转到“路由”选项卡,单击“新规则”并将其命名为socketRule。 现在,仅需选择脚本,并默认保留掩码(。*)。


在此阶段您需要做的最后一件事是创建一个用户。 切换到“用户”选项卡,单击“创建用户”,指定名称(例如socketUser)和密码,然后单击“创建”。 在最后一步中,我们将需要此用户名/密码对在Web客户端中进行身份验证。


配置已完成,但是在开始创建服务器之前,让我们看一下WebSocket模块在我们的方案中如何工作。

2.脚本细节


WebSocket模块允许开发人员打开稳定的连接并通过它发送数据。 要使用此模块,我们必须在脚本的开始处将其连接:

 require(Modules.WebSocket); 

通过createWebSocket方法,我们确定URL和协议(可选)。 您可以从下一部分中学习如何获取WebSocket的URL。

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

创建WebSocket对象后,我们将继续在处理程序中管理调用。 即,我们使用call.sendMediaTo方法将媒体发送到WebSocket对象。

在这里,您可以设置首选的编码格式,标签和一些自定义参数。 如果未设置编码,则默认使用PCM8。

收到成功的连接消息后将调用此方法。 在我们的场景中,调用代码如下所示:

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

您在代码中看到的所有其他WebSocket事件都用于调试;它们将信息发送到Voximplant会话的日志。 您可以根据需要删除它们。

最后,我们添加正确的数据传输完成处理程序。 在我们的情况下,Voximplant会话在已建立的呼叫结束( 断开连接 )后1秒结束其工作:

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

现在脚本的逻辑已经很清楚了,是时候继续进行示例中下一个非常重要的部分了。

3.后端


首先,确保您的计算机上安装了Node.js。 您可以从Node.js站点下载它。 然后,在终端窗口中依次运行以下命令以设置工作环境:

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

完成此操作后,创建一个空的JS文件并将以下代码放在此处(代码的细微差别将在下面突出显示):

 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'); }); 

现在已经配置了服务器,它将帮助我们执行语音识别。 通过使用ngrok在localhost 3000上创建隧道在本地测试您的解决方案。

为此,请按照下列步骤操作:
  1. 按照其网站上的说明安装ngrok。
  2. 为ngrok指定您的身份验证,以将客户端绑定到该帐户。
  3. 运行node your_file_name.js以在本地主机上启动服务器:3000。
  4. 转到计算机上的ngrok文件夹,然后运行./ngrok http 3000命令以在正在运行的本地服务器和公共URL之间建立隧道。

注意生成的公共URL,我们将其用作脚本中带有前缀“ wss”的WebSocket URL:



4.语音识别


您可能已经注意到,我们的后端代码包含与Google Cloud相关的行。

库本身的导入如下:

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

现在,您需要指定如何处理语音识别请求。 为此,请在生成的配置中选择编码,sampleRateHertz和languageCode:

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

接下来,创建一个写入流,使您可以将传输的数据保存到文件中:

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

一切设置完成后,您需要解析消息,并将音频数据以base64格式放入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); } 

此后,将立即启动识别请求并开始处理此请求:

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

最后,提供您的服务帐户的凭据以将Google库连接到其后端。 为此,请转到Google身份验证页面,然后按照此处列出的所有步骤进行操作。 然后在与node your_file_name.js:相同的工作空间中(在同一“ Terminal”选项卡中)运行export node your_file_name.js:

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

发射插座


打开phone.voximplant.com ,填写表格,然后单击“登录”。 用户名和密码是指在步骤1中创建的用户:


成功授权后,单击呼叫并开始通话。 语音转文字云将您的语音实时转换为文本,您可以在终端窗口中看到该文本。

恭喜,您做到了! 我们希望您喜欢这篇文章,并希望您有更多的集成和新的挑战。

Source: https://habr.com/ru/post/zh-CN476902/


All Articles