1006 IBM Watson语音到文本API中的错误代码

问题描述 投票:0回答:1

我正在使用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://tools.ietf.org/html/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);
    }

}
websocket ibm-watson ratchet
1个回答
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&timestamps=true"

顺便说一句。是你的websockets客户端使用乒乓帧来保持连接活着?我注意到你没有请求中期结果({"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"}),这是保持连接打开的另一种方法,但不太可靠。请检查乒乓球架。

© www.soinside.com 2019 - 2024. All rights reserved.