IBM Watson 语音到文本 API 中的 1006 错误代码
Posted
技术标签:
【中文标题】IBM Watson 语音到文本 API 中的 1006 错误代码【英文标题】:1006 Error code in IBM Watson speech-to-text API 【发布时间】:2019-03-18 14:47:51 【问题描述】:我正在使用 Ratchet 连接到 IBM Watson websockets,它似乎总是适用于较小的文件(我已经测试了长达 66 分钟的 23 MB mp3 文件),但它总是失败较大的文件(例如 2 小时 56 MB 的 mp3)。
这是我的日志:
[2019-03-17 21:43:23] local.DEBUG: \Ratchet\Client\connect bf4e38983775f6e53b392666138b5a3a50e9c9c8
[2019-03-17 21:43:24] local.DEBUG: startWatsonStream options = "content-type":"audio\/mpeg","timestamps":true,"speaker_labels":true,"smart_formatting":true,"inactivity_timeout":-1,"interim_results":false,"max_alternatives":1,"word_confidence":false,"action":"start"
[2019-03-17 21:43:24] local.DEBUG: Split audio into this many frames: 570222
[2019-03-17 21:43:42] local.DEBUG: send action stop
[2019-03-17 21:43:42] local.DEBUG: Received:
"state": "listening"
[2019-03-17 21:43:42] local.DEBUG: Received first 'listening' message.
[2019-03-17 22:56:31] local.DEBUG: Connection closed (1006 - Underlying connection closed)
请注意接收到第一个“正在侦听”消息之间的 1 小时 13 分钟,然后连接因错误而关闭。
Watson说:“1006表示连接异常关闭。”
https://www.rfc-editor.org/rfc/rfc6455 说:
1006 是一个保留值,绝不能被端点设置为关闭控制帧中的状态码。它被指定用于期望状态代码指示连接已异常关闭的应用程序,例如,没有发送或接收关闭控制帧。
我可以调整我的代码的哪一部分,以便它可以处理更长的 mp3 文件而不会引发 1006 错误?
\Ratchet\Client\connect($url, [], $headers)->then(function(\Ratchet\Client\WebSocket $conn) use($contentType, $audioFileContents, $callback)
$conn->on('message', function($msg) use ($conn, $callback)
$this->handleIncomingWebSocketMessage($msg, $conn, $callback);
);
$conn->on('close', function($code = null, $reason = null)
Log::debug("Connection closed ($code - $reason)");
);
$this->startWatsonStream($conn, $contentType);
$this->sendBinaryMessage($conn, $audioFileContents);
Log::debug('send action stop');
$conn->send(json_encode(['action' => 'stop']));
, function (\Exception $e)
Log::error("Could not connect: $e->getMessage() " . $e->getTraceAsString());
);
...
public function handleIncomingWebSocketMessage($msg, $conn, $callback)
Log::debug("Received: " . str_limit($msg, 100));
$msgArray = json_decode($msg, true);
$state = $msgArray['state'] ?? null;
if ($state == 'listening')
if ($this->listening) //then this is the 2nd time listening, which means audio processing has finished and has already been sent by server and received by this client.
Log::debug("FINAL RESPONSE: " . str_limit($this->responseJson, 500));
$conn->close(\Ratchet\RFC6455\Messaging\Frame::CLOSE_NORMAL, 'Finished.');
$callback($this->responseJson);
else
$this->listening = true;
Log::debug("Received first 'listening' message.");
else
$this->responseJson = $msg;
public function sendBinaryMessage($conn, $fileContents)
$chunkSizeInBytes = 100; //probably just needs to be <= 4 MB according to Watson's rules
$chunks = str_split($fileContents, $chunkSizeInBytes);
Log::debug('Split audio into this many frames: ' . count($chunks));
$final = true;
foreach ($chunks as $key => $chunk)
$frame = new \Ratchet\RFC6455\Messaging\Frame($chunk, $final, \Ratchet\RFC6455\Messaging\Frame::OP_BINARY);
$conn->send($frame);
【问题讨论】:
我猜想在$conn->on('close',
上你会想要重新建立连接。
@chughts 我很好奇为什么较小的文件可以工作。我的理解是,会话有可能(甚至可能需要?)一直保持打开状态,直到所有处理完成并且我的客户收到整个响应。例如。 “在发送最后一个块以指示流结束后,您无需担心会话超时。服务会继续处理音频,直到返回最终的转录结果。当您转录较长的音频流时,.. .
@chughts "...服务可能需要超过 30 秒的时间来处理音频并生成响应。服务在完成处理它拥有的所有音频之前不会开始计算会话超时已收到。服务的处理时间不会导致会话超过 30 秒的会话超时。 - cloud.ibm.com/docs/services/…
我猜这不是关闭 Web 套接字的服务,而是自动关闭它的底层 Web 套接字基础设施。
@chughts 啊,所以你的意思是我的 php 服务器(它作为 websockets 的 client 使用)使用 Ratchet 库。 ***.com/a/19305172/470749 同样表示 1006 是由客户端而不是 websockets 服务器引起的错误。我还不确定要调查什么,但听说这可能是 我的 端(并且在我的控制范围内)而不是 IBM 端的事情是令人鼓舞的。我想至少我可以试试你重新连接的想法。谢谢。
【参考方案1】:
作为一般建议,基于文件的识别,尤其是文件大于几 MB 时,应使用异步的 Watson /recognitions
API(更多详细信息:https://cloud.ibm.com/apidocs/speech-to-text)来完成。您不需要保持连接打开几个小时,这不是一个好习惯,因为您可能会遇到读取超时,您可能会失去网络连接等。通过异步执行此操作,您 POST 文件然后连接结束,然后您可以每 X 分钟获取一次状态,或者通过回调获得通知,无论哪种方式更适合您。
curl -X POST -u "apikey:apikey" --header "Content-Type: audio/flac" --data-binary @audio-file.flac "https://stream.watsonplatform.net/speech-to-text/api/v1/recognitions?callback_url=http://user_callback_path/job_results&user_token=job25×tamps=true"
顺便说一句。您的 websockets 客户端是否使用 ping-pong 帧来保持连接处于活动状态?我注意到您不要求临时结果 ("content-type":"audio\/mpeg","timestamps":true,"speaker_labels":true,"smart_formatting":true,"inactivity_timeout":-1,"interim_results":false,"max_alternatives":1,"word_confidence":false,"action":"start"
),这是保持连接打开的另一种方法,但可靠性较低。请检查乒乓框架。
【讨论】:
感谢您的有趣建议。 +1。我不知道我是否做得正确,但是是的,我每 120 秒发送一次 ping:***.com/questions/35009726/…以上是关于IBM Watson 语音到文本 API 中的 1006 错误代码的主要内容,如果未能解决你的问题,请参考以下文章
Curl 文本到语音中的 SSML 代码 IBM Watson
如何检测是不是在语音到文本(Unity IBM Watson sdk)中完成了句子检测?
Watson语音到文本 - 无法构造'WebSocket':URL包含片段标识符