def stop(self): """ 结束识别并关闭与服务端的连接 :return: 关闭成功,返回0 关闭失败,返回-1 """ ret = 0 if self._status == Status.STATUS_STARTED: self._status = Status.STATUS_STOPPING msg_id = six.u(uuid.uuid1().hex) self._header[ Constant. HEADER_KEY_NAME] = Constant.HEADER_VALUE_TRANS_NAME_STOP self._header[Constant.HEADER_KEY_MESSAGE_ID] = msg_id self._payload.clear() text = self.serialize() _log.info('sending stop cmd: ' + text) self._ws.send(text) for i in range(100): if self._status == Status.STATUS_STOPPED: break else: time.sleep(0.1) _log.debug('waite 100ms') if self._status != Status.STATUS_STOPPED: ret = -1 else: ret = 0 else: _log.error('should not stop in state %d', self._status) ret = -1 return ret
def _on_open(ws): _log.debug('websocket connected') self._status = Status.STATUS_WS_CONNECTED self._is_connected = True msg_id = six.u(uuid.uuid1().hex) self._task_id = six.u(uuid.uuid1().hex) self._header[Constant.HEADER_KEY_NAME] = Constant.HEADER_VALUE_TRANS_NAME_START self._header[Constant.HEADER_KEY_MESSAGE_ID] = msg_id self._header[Constant.HEADER_KEY_TASK_ID] = self._task_id text = self.serialize() _log.info('sending start cmd: ' + text) ws.send(text)
def create_token(access_key_id, access_key_secret): parameters = { 'AccessKeyId': access_key_id, 'Action': 'CreateToken', 'Format': 'JSON', 'RegionId': 'cn-shanghai', 'SignatureMethod': 'HMAC-SHA1', 'SignatureNonce': str(uuid.uuid1()), 'SignatureVersion': '1.0', 'Timestamp': time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), 'Version': '2019-02-28' } # 构造规范化的请求字符串 query_string = AccessToken._encode_dict(parameters) _log.debug('规范化的请求字符串: %s' % query_string) # 构造待签名字符串 string_to_sign = 'GET' + '&' + AccessToken._encode_text( '/') + '&' + AccessToken._encode_text(query_string) _log.debug('待签名的字符串: %s' % string_to_sign) # 计算签名 secreted_string = hmac.new( bytes(access_key_secret + '&', encoding='utf-8'), bytes(string_to_sign, encoding='utf-8'), hashlib.sha1).digest() signature = base64.b64encode(secreted_string) _log.debug('签名: %s' % signature) # 进行URL编码 signature = AccessToken._encode_text(signature) _log.debug('URL编码后的签名: %s' % signature) # 调用服务 full_url = 'http://nls-meta.cn-shanghai.aliyuncs.com/?Signature=%s&%s' % ( signature, query_string) _log.debug('url: %s' % full_url) # 提交HTTP GET请求 response = requests.get(full_url) if response.ok: root_obj = response.json() key = 'Token' if key in root_obj: token = root_obj[key]['Id'] expire_time = root_obj[key]['ExpireTime'] return token, expire_time _log.error(response.text) return None, None
def wait_completed(self): """ 等待合成结束 :return: 合成结束,返回0 合成超时,返回-1 """ ret = 0 if self._status == Status.STATUS_STARTED: for i in range(100): if self._status == Status.STATUS_STOPPED: break else: time.sleep(0.1) _log.debug('waite 100ms') if self._status != Status.STATUS_STOPPED: ret = -1 else: ret = 0 else: _log.error('should not wait completed in state %d', self._status) ret = -1 return ret
def _on_message(ws, raw): _log.debug('websocket message received: ' + raw) msg = json.loads(raw) name = msg[Constant.HEADER][Constant.HEADER_KEY_NAME] if name == Constant.HEADER_VALUE_ASR_NAME_STARTED: self._status = Status.STATUS_STARTED _log.debug('callback on_started') self._callback.on_started(msg) elif name == Constant.HEADER_VALUE_ASR_NAME_RESULT_CHANGED: _log.debug('callback on_result_changed') self._callback.on_result_changed(msg) elif name == Constant.HEADER_VALUE_ASR_NAME_COMPLETED: if self._status == Status.STATUS_STOPPING: # 客户端主动调用stop返回的completed事件 self._status = Status.STATUS_STOPPED else: # 开启VAD,服务端主动返回的completed事件 self._status = Status.STATUS_COMPLETED_WITH_OUT_STOP _log.debug('websocket status changed to stopped') _log.debug('callback on_completed') self._callback.on_completed(msg) elif name == Constant.HEADER_VALUE_NAME_TASK_FAILED: self._status = Status.STATUS_STOPPED _log.error(msg) _log.debug('websocket status changed to stopped') _log.debug('callback on_task_failed') self._callback.on_task_failed(msg)
def start(self, ping_interval=5, ping_timeout=3): """ 开始识别,新建到服务端的连接 :param ping_interval: 自动发送ping命令,指定发送间隔,单位为秒 :param ping_timeout: 等待接收pong消息的超时时间,单位为秒 :return: 与服务端建立连接成功,返回0 与服务端建立连接失败,返回-1 """ if self._status == Status.STATUS_INIT: _log.debug('starting recognizer...') self._status = Status.STATUS_STARTING else: _log.error("Illegal status: %s" % self._status) return -1 def _on_open(ws): _log.debug('websocket connected') self._status = Status.STATUS_WS_CONNECTED self._is_connected = True msg_id = six.u(uuid.uuid1().hex) self._task_id = six.u(uuid.uuid1().hex) self._header[ Constant. HEADER_KEY_NAME] = Constant.HEADER_VALUE_ASR_NAME_START self._header[Constant.HEADER_KEY_MESSAGE_ID] = msg_id self._header[Constant.HEADER_KEY_TASK_ID] = self._task_id text = self.serialize() _log.info('sending start cmd: ' + text) ws.send(text) def _on_message(ws, raw): _log.debug('websocket message received: ' + raw) msg = json.loads(raw) name = msg[Constant.HEADER][Constant.HEADER_KEY_NAME] if name == Constant.HEADER_VALUE_ASR_NAME_STARTED: self._status = Status.STATUS_STARTED _log.debug('callback on_started') self._callback.on_started(msg) elif name == Constant.HEADER_VALUE_ASR_NAME_RESULT_CHANGED: _log.debug('callback on_result_changed') self._callback.on_result_changed(msg) elif name == Constant.HEADER_VALUE_ASR_NAME_COMPLETED: if self._status == Status.STATUS_STOPPING: # 客户端主动调用stop返回的completed事件 self._status = Status.STATUS_STOPPED else: # 开启VAD,服务端主动返回的completed事件 self._status = Status.STATUS_COMPLETED_WITH_OUT_STOP _log.debug('websocket status changed to stopped') _log.debug('callback on_completed') self._callback.on_completed(msg) elif name == Constant.HEADER_VALUE_NAME_TASK_FAILED: self._status = Status.STATUS_STOPPED _log.error(msg) _log.debug('websocket status changed to stopped') _log.debug('callback on_task_failed') self._callback.on_task_failed(msg) def _on_close(ws): _log.debug('callback on_channel_closed') self._callback.on_channel_closed() def _on_error(ws, error): if self._is_connected or self._last_start_retry: _log.error(error) self._status = Status.STATUS_STOPPED message = json.loads( '{"header":{"namespace":"Default","name":"TaskFailed",' '"status":400,"message_id":"0","task_id":"0",' '"status_text":"%s"}}' % error) self._callback.on_task_failed(message) else: _log.warning('retry start: %s' % error) retry_count = 3 for count in range(retry_count): self._status = Status.STATUS_STARTING if count == (retry_count - 1): self._last_start_retry = True # Init WebSocket self._ws = websocket.WebSocketApp( self._gateway_url, on_open=_on_open, on_message=_on_message, on_error=_on_error, on_close=_on_close, header={Constant.HEADER_TOKEN: self._token}) self._thread = threading.Thread(target=self._ws.run_forever, args=(None, None, ping_interval, ping_timeout)) self._thread.daemon = True self._thread.start() # waite for no more than 10 seconds for i in range(1000): if self._status == Status.STATUS_STARTED or self._status == Status.STATUS_STOPPED: break else: time.sleep(0.01) if self._status == Status.STATUS_STARTED: # 与服务端连接建立成功 _log.debug('start succeed!') return 0 else: if self._is_connected or self._last_start_retry: # 已建立了WebSocket链接但是与服务端的连接失败, 或者是最后一次重试,则返回-1 _log.error("start failed, status: %s" % self._status) return -1 else: # 尝试重连 continue
def _on_close(ws): _log.debug('callback on_channel_closed') self._callback.on_channel_closed()
def _on_message(ws, raw): _log.debug('websocket message received: ' + raw) msg = json.loads(raw) name = msg[Constant.HEADER][Constant.HEADER_KEY_NAME] if name == Constant.HEADER_VALUE_TRANS_NAME_STARTED: self._status = Status.STATUS_STARTED _log.debug('callback on_started') self._callback.on_started(msg) elif name == Constant.HEADER_VALUE_TRANS_NAME_RESULT_CHANGE: _log.debug('callback on_result_changed') self._callback.on_result_changed(msg) elif name == Constant.HEADER_VALUE_TRANS_NAME_SENTENCE_BEGIN: _log.debug('callback on_sentence_begin') self._callback.on_sentence_begin(msg) elif name == Constant.HEADER_VALUE_TRANS_NAME_SENTENCE_END: _log.debug('callback on_sentence_end') self._callback.on_sentence_end(msg) elif name == Constant.HEADER_VALUE_TRANS_NAME_COMPLETED: self._status = Status.STATUS_STOPPED _log.debug('websocket status changed to stopped') _log.debug('callback on_completed') self._callback.on_completed(msg) elif name == Constant.HEADER_VALUE_NAME_TASK_FAILED: self._status = Status.STATUS_STOPPED _log.error(msg) _log.debug('websocket status changed to stopped') _log.debug('callback on_task_failed') self._callback.on_task_failed(msg)
def _on_data(ws, raw, opcode, flag): if opcode == websocket.ABNF.OPCODE_BINARY: _log.debug("received binary data, size: %s" % len(raw)) self._callback.on_binary_data_received(raw) elif opcode == websocket.ABNF.OPCODE_TEXT: _log.debug("websocket message received: %s" % raw) msg = json.loads(raw) name = msg[Constant.HEADER][Constant.HEADER_KEY_NAME] if name == Constant.HEADER_VALUE_TTS_NAME_COMPLETED: self._status = Status.STATUS_STOPPED _log.debug('websocket status changed to stopped') _log.debug('callback on_completed') self._callback.on_completed(msg) elif name == Constant.HEADER_VALUE_NAME_TASK_FAILED: self._status = Status.STATUS_STOPPED _log.error(msg) _log.debug('websocket status changed to stopped') _log.debug('callback on_task_failed') self._callback.on_task_failed(msg)