Python 与Twilio一起使用时,谷歌云语音到文本音频超时错误;溪流;动词与Websocket

Python 与Twilio一起使用时,谷歌云语音到文本音频超时错误;溪流;动词与Websocket,python,flask,websocket,twilio,google-speech-to-text-api,Python,Flask,Websocket,Twilio,Google Speech To Text Api,我目前正在尝试制作一个系统,可以实时转录一个电话,然后在我的命令行中显示对话。为了做到这一点,我使用了一个Twilio电话号码,当被呼叫时,它会发送一个http请求。然后使用Flask、Ngrok和Websockets编译我的服务器代码,公开我的本地端口并传输数据,TwiML动词“Stream”用于将音频数据流到Google云语音文本API。到目前为止,我已经在GitHub()上使用了Twilio的python演示 我的服务器代码: from flask import Flask, render

我目前正在尝试制作一个系统,可以实时转录一个电话,然后在我的命令行中显示对话。为了做到这一点,我使用了一个Twilio电话号码,当被呼叫时,它会发送一个http请求。然后使用Flask、Ngrok和Websockets编译我的服务器代码,公开我的本地端口并传输数据,TwiML动词“Stream”用于将音频数据流到Google云语音文本API。到目前为止,我已经在GitHub()上使用了Twilio的python演示

我的服务器代码:

from flask import Flask, render_template
from flask_sockets import Sockets

from SpeechClientBridge import SpeechClientBridge
from google.cloud.speech_v1 import enums
from google.cloud.speech_v1 import types

import json
import base64
import os

os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "./<KEY>.json"
HTTP_SERVER_PORT = 8080

config = types.RecognitionConfig(
    encoding=enums.RecognitionConfig.AudioEncoding.MULAW,
    sample_rate_hertz=8000,
    language_code='en-US')
streaming_config = types.StreamingRecognitionConfig(
    config=config,
    interim_results=True)

app = Flask(__name__)
sockets = Sockets(app)

@app.route('/home')
def home():
    return render_template("index.html")

@app.route('/twiml', methods=['POST'])
def return_twiml():
    print("POST TwiML")
    return render_template('streams.xml')

def on_transcription_response(response):
    if not response.results:
        return

    result = response.results[0]
    if not result.alternatives:
        return

    transcription = result.alternatives[0].transcript
    print("Transcription: " + transcription)

@sockets.route('/')
def transcript(ws):
    print("WS connection opened")
    bridge = SpeechClientBridge(
        streaming_config, 
        on_transcription_response
    )
    while not ws.closed:
        message = ws.receive()
        if message is None:
            bridge.terminate()
            break

        data = json.loads(message)
        if data["event"] in ("connected", "start"):
            print(f"Media WS: Received event '{data['event']}': {message}")
            continue
        if data["event"] == "media":
            media = data["media"]
            chunk = base64.b64decode(media["payload"])
            bridge.add_request(chunk)
        if data["event"] == "stop":
            print(f"Media WS: Received event 'stop': {message}")
            print("Stopping...")
            break

    bridge.terminate()
    print("WS connection closed")

if __name__ == '__main__':
    from gevent import pywsgi
    from geventwebsocket.handler import WebSocketHandler

    server = pywsgi.WSGIServer(('', HTTP_SERVER_PORT), app, handler_class=WebSocketHandler)
    print("Server listening on: http://localhost:" + str(HTTP_SERVER_PORT))
    server.serve_forever()
从烧瓶导入烧瓶,渲染\u模板
从U形插座导入插座
从SpeechClientBridge导入SpeechClientBridge
从google.cloud.speech_v1导入枚举
从google.cloud.speech_v1导入类型
导入json
导入base64
导入操作系统
os.environ[“谷歌应用程序证书”]=“/.json”
HTTP_服务器_端口=8080
config=types.RecognitionConfig(
encoding=enums.RecognitionConfig.AudioEncoding.MULAW,
采样率=8000赫兹,
语言(代码='en-US')
streaming_config=types.StreamingRecognitionConfig(
config=config,
临时结果(正确)
app=烧瓶(名称)
套接字=套接字(应用程序)
@应用程序路径(“/home”)
def home():
返回渲染模板(“index.html”)
@app.route('/twiml',methods=['POST'])
def return_twiml():
打印(“PostTwiml”)
返回render_模板('streams.xml')
def on_转录_响应(响应):
如果没有响应。结果:
返回
结果=响应。结果[0]
如果不是结果,则选择:
返回
转录=结果。备选方案[0]。转录本
打印(“转录:”+转录)
@sockets.route(“/”)
def记录(ws):
打印(“WS连接已打开”)
bridge=SpeechClientBridge(
流媒体配置,
论转录反应
)
虽然未关闭ws.closed:
message=ws.receive()
如果消息为“无”:
bridge.terminate()
打破
data=json.load(消息)
如果(“已连接”、“启动”)中的数据[“事件”]:
打印(f“媒体WS:Received event'{data['event']}':{message}”)
持续
如果数据[“事件”]=“媒体”:
媒体=数据[“媒体”]
chunk=base64.b64解码(媒体[“有效负载”])
bridge.add_请求(块)
如果数据[“事件”]=“停止”:
打印(f“媒体WS:接收到的事件‘停止’:{message}”)
打印(“停止…”)
打破
bridge.terminate()
打印(“WS连接已关闭”)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
从gevent导入pywsgi
从geventwebsocket.handler导入WebSocketHandler
server=pywsgi.WSGIServer((“”,HTTP_服务器_端口),app,handler_class=WebSocketHandler)
打印(“正在侦听的服务器:”http://localhost:“+str(HTTP_服务器_端口))
服务器。永远为您服务()
streams.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Response>
     <Say> Thanks for calling!</Say>
     <Start>
        <Stream url="wss://<ngrok-URL/.ngrok.io/"/>
     </Start>
     <Pause length="40"/>
</Response>

谢谢你的来电!
Twilio WebHook:

http://<ngrok-URL>.ngrok.io/twiml
http://.ngrok.io/twiml
当我运行服务器代码并调用Twilio号码时,我收到以下错误:

C:\Users\Max\Python\Twilio>python server.py
Server listening on: http://localhost:8080
POST TwiML
WS connection opened
Media WS: Received event 'connected': {"event":"connected","protocol":"Call","version":"0.2.0"}
Media WS: Received event 'start': {"event":"start","sequenceNumber":"1","start":{"accountSid":"AC8abc5aa74496a227d3eb489","streamSid":"MZe6245f23e2385aa2ea7b397","callSid":"CA5864313b4992607d3fe46","tracks":["inbound"],"mediaFormat":{"encoding":"audio/x-mulaw","sampleRate":8000,"channels":1}},"streamSid":"MZe6245f2397c1285aa2ea7b397"}
Exception in thread Thread-4:
Traceback (most recent call last):
  File "C:\Users\Max\AppData\Local\Programs\Python\Python37\lib\site-packages\google\api_core\grpc_helpers.py", line 96, in next
    return six.next(self._wrapped)
  File "C:\Users\Max\AppData\Local\Programs\Python\Python37\lib\site-packages\grpc\_channel.py", line 416, in __next__
    return self._next()
  File "C:\Users\Max\AppData\Local\Programs\Python\Python37\lib\site-packages\grpc\_channel.py", line 689, in _next
    raise self
grpc._channel._MultiThreadedRendezvous: <_MultiThreadedRendezvous of RPC that terminated with:
        status = StatusCode.OUT_OF_RANGE
        details = "Audio Timeout Error: Long duration elapsed without audio. Audio should be sent close to real time."
        debug_error_string = "{"created":"@1591738676.565000000","description":"Error received from peer ipv6:[2a00:1450:4009:807::200a]:443","file":"src/core/lib/surface/call.cc","file_line":1056,"grpc_message":"Audio Timeout Error: Long duration elapsed without audio. Audio should be sent close to real time.","grpc_status":11}"
>

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\Max\AppData\Local\Programs\Python\Python37\lib\threading.py", line 917, in _bootstrap_inner
    self.run()
  File "C:\Users\Max\AppData\Local\Programs\Python\Python37\lib\threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\Max\Python\Twilio\SpeechClientBridge.py", line 37, in process_responses_loop
    for response in responses:
  File "C:\Users\Max\AppData\Local\Programs\Python\Python37\lib\site-packages\google\api_core\grpc_helpers.py", line 99, in next
    six.raise_from(exceptions.from_grpc_error(exc), exc)
  File "<string>", line 3, in raise_from
google.api_core.exceptions.OutOfRange: 400 Audio Timeout Error: Long duration elapsed without audio. Audio should be sent close to real time.

Media WS: Received event 'stop': {"event":"stop","sequenceNumber":"752","streamSid":"MZe6245f2397c125aa2ea7b397","stop":{"accountSid":"AC8abc5aa74496a60227d3eb489","callSid":"CA5842bc6431314d502607d3fe46"}}
Stopping...
WS connection closed
C:\Users\Max\Python\Twilio>Python server.py
正在侦听的服务器:http://localhost:8080
后TwiML
WS-connection已打开
媒体WS:接收到事件“已连接”:{“事件”:“已连接”,“协议”:“呼叫”,“版本”:“0.2.0”}
媒体WS:收到的事件'start':{“event”:“start”,“sequenceNumber”:“1”,“start”:{“accountSid”:“AC8abc5aa74496a227d3eb489”,“streamSid”:“MZe6245f23e2385aa2ea7b397”,“callSid”:“CA5864313B492607D3FE46”,“tracks”:[“inbound”],“mediaFormat”:{“encoding”:“audio/x-mulaw”,“sampleRate”:8000,“Channel”:1},“streamSid”:“MZE6245F2397C1285AA7B397”}
线程4中的异常:
回溯(最近一次呼叫最后一次):
文件“C:\Users\Max\AppData\Local\Programs\Python\37\lib\site packages\google\api\u core\grpc\u helpers.py”,下一行第96行
返回六。下一个(自我包装)
文件“C:\Users\Max\AppData\Local\Programs\Python37\lib\site packages\grpc\\ u channel.py”,第416行,下一页__
返回自我。_next()
文件“C:\Users\Max\AppData\Local\Programs\Python37\lib\site packages\grpc\\ u channel.py”,第689行,下一页
自立
grpc.\u通道.\u多线程端接:
上述异常是以下异常的直接原因:
回溯(最近一次呼叫最后一次):
文件“C:\Users\Max\AppData\Local\Programs\Python\37\lib\threading.py”,第917行,在\u bootstrap\u inner中
self.run()
文件“C:\Users\Max\AppData\Local\Programs\Python\Python37\lib\threading.py”,第865行,正在运行
自我目标(*自我参数,**自我参数)
文件“C:\Users\Max\Python\Twilio\SpeechClientBridge.py”,第37行,在进程\u响应\u循环中
关于答复中的答复:
文件“C:\Users\Max\AppData\Local\Programs\Python\37\lib\site packages\google\api\u core\grpc\u helpers.py”,第99行,下一行
六、从(例外情况。从grpc错误(exc),exc)
文件“”,第3行,从
google.api_core.exceptions.OutOfRange:400音频超时错误:长时间没有音频。音频应接近实时发送。
媒体WS:收到的事件“停止”:{“事件”:“停止”,“序列号”:“752”,“流SID”:“MZE6245F2397C125AA2EA7A7B397”,“停止”:{“帐户SID”:“AC8abc5aa74496a60227d3eb489”,“调用SID”:“CA5842bc6431314d502607d3fe46”}
停止。。。
WS连接已关闭
我不明白为什么我收到音频超时错误?这是Twilio和谷歌的防火墙问题吗?编码问题

任何帮助都将不胜感激

系统: 视窗10 Python 3.7.1 ngrok 2.3.35
Flask 1.1.2作为您的streams.xml返回套接字url“wss://作为您的streams.xml返回套接字url”wss://我对此运行了一些测试,试图确定发生了什么。我在墙上放了一个计时器

bridge=SpeechClientBridge( 流媒体配置, 关于(转录)(应答)

并发现初始化需要10.9秒。我相信谷歌API的超时时间是10秒。我试着跑了
<?xml version="1.0" encoding="UTF-8"?>
<Response>
     <Say> Thanks for calling!</Say>
     <Start>
        <Stream url="wss://YOUR_NGROK_ID.ngrok.io/"/>
     </Start>
     <Pause length="40"/>
</Response>