From f4b7eefc385e286d849dcc794610209330ba5135 Mon Sep 17 00:00:00 2001 From: hrz <1710360675@qq.com> Date: Sun, 27 Apr 2025 22:07:36 +0800 Subject: [PATCH] =?UTF-8?q?update:=E5=8E=BB=E9=99=A4print?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/providers/asr/doubao.py | 83 +++++++++++-------- .../plugins_func/functions/get_weather.py | 6 -- 2 files changed, 50 insertions(+), 39 deletions(-) diff --git a/main/xiaozhi-server/core/providers/asr/doubao.py b/main/xiaozhi-server/core/providers/asr/doubao.py index 51b0b8b1..b19ceb97 100644 --- a/main/xiaozhi-server/core/providers/asr/doubao.py +++ b/main/xiaozhi-server/core/providers/asr/doubao.py @@ -45,14 +45,14 @@ def parse_response(res): payload 类似与http 请求体 """ protocol_version = res[0] >> 4 - header_size = res[0] & 0x0f + header_size = res[0] & 0x0F message_type = res[1] >> 4 - message_type_specific_flags = res[1] & 0x0f + message_type_specific_flags = res[1] & 0x0F serialization_method = res[2] >> 4 - message_compression = res[2] & 0x0f + message_compression = res[2] & 0x0F reserved = res[3] - header_extensions = res[4:header_size * 4] - payload = res[header_size * 4:] + header_extensions = res[4 : header_size * 4] + payload = res[header_size * 4 :] result = {} payload_msg = None payload_size = 0 @@ -61,13 +61,13 @@ def parse_response(res): payload_msg = payload[4:] elif message_type == SERVER_ACK: seq = int.from_bytes(payload[:4], "big", signed=True) - result['seq'] = seq + result["seq"] = seq if len(payload) >= 8: payload_size = int.from_bytes(payload[4:8], "big", signed=False) payload_msg = payload[8:] elif message_type == SERVER_ERROR_RESPONSE: code = int.from_bytes(payload[:4], "big", signed=False) - result['code'] = code + result["code"] = code payload_size = int.from_bytes(payload[4:8], "big", signed=False) payload_msg = payload[8:] if payload_msg is None: @@ -78,8 +78,8 @@ def parse_response(res): payload_msg = json.loads(str(payload_msg, "utf-8")) elif serialization_method != NO_SERIALIZATION: payload_msg = str(payload_msg, "utf-8") - result['payload_msg'] = payload_msg - result['payload_size'] = payload_size + result["payload_msg"] = payload_msg + result["payload_size"] = payload_size return result @@ -122,7 +122,9 @@ class ASRProvider(ASRProviderBase): return file_path @staticmethod - def _generate_header(message_type=CLIENT_FULL_REQUEST, message_type_specific_flags=NO_SEQUENCE) -> bytearray: + def _generate_header( + message_type=CLIENT_FULL_REQUEST, message_type_specific_flags=NO_SEQUENCE + ) -> bytearray: """Generate protocol header.""" header = bytearray() header_size = 1 @@ -143,11 +145,7 @@ class ASRProvider(ASRProviderBase): "user": { "uid": str(uuid.uuid4()), }, - "request": { - "reqid": reqid, - "show_utterances": False, - "sequence": 1 - }, + "request": {"reqid": reqid, "show_utterances": False, "sequence": 1}, "audio": { "format": "raw", "rate": 16000, @@ -158,18 +156,23 @@ class ASRProvider(ASRProviderBase): }, } - async def _send_request(self, audio_data: List[bytes], segment_size: int) -> Optional[str]: + async def _send_request( + self, audio_data: List[bytes], segment_size: int + ) -> Optional[str]: """Send request to Volcano ASR service.""" try: - auth_header = {'Authorization': 'Bearer; {}'.format(self.access_token)} - async with websockets.connect(self.ws_url, additional_headers=auth_header) as websocket: + auth_header = {"Authorization": "Bearer; {}".format(self.access_token)} + async with websockets.connect( + self.ws_url, additional_headers=auth_header + ) as websocket: # Prepare request data request_params = self._construct_request(str(uuid.uuid4())) - print(request_params) payload_bytes = str.encode(json.dumps(request_params)) payload_bytes = gzip.compress(payload_bytes) full_client_request = self._generate_header() - full_client_request.extend((len(payload_bytes)).to_bytes(4, 'big')) # payload size(4 bytes) + full_client_request.extend( + (len(payload_bytes)).to_bytes(4, "big") + ) # payload size(4 bytes) full_client_request.extend(payload_bytes) # payload # Send header and metadata @@ -177,22 +180,29 @@ class ASRProvider(ASRProviderBase): await websocket.send(full_client_request) res = await websocket.recv() result = parse_response(res) - if 'payload_msg' in result and result['payload_msg']['code'] != self.success_code: + if ( + "payload_msg" in result + and result["payload_msg"]["code"] != self.success_code + ): logger.bind(tag=TAG).error(f"ASR error: {result}") return None - for seq, (chunk, last) in enumerate(self.slice_data(audio_data, segment_size), 1): + for seq, (chunk, last) in enumerate( + self.slice_data(audio_data, segment_size), 1 + ): if last: audio_only_request = self._generate_header( message_type=CLIENT_AUDIO_ONLY_REQUEST, - message_type_specific_flags=NEG_SEQUENCE + message_type_specific_flags=NEG_SEQUENCE, ) else: audio_only_request = self._generate_header( message_type=CLIENT_AUDIO_ONLY_REQUEST ) payload_bytes = gzip.compress(chunk) - audio_only_request.extend((len(payload_bytes)).to_bytes(4, 'big')) # payload size(4 bytes) + audio_only_request.extend( + (len(payload_bytes)).to_bytes(4, "big") + ) # payload size(4 bytes) audio_only_request.extend(payload_bytes) # payload # Send audio data await websocket.send(audio_only_request) @@ -201,9 +211,12 @@ class ASRProvider(ASRProviderBase): response = await websocket.recv() result = parse_response(response) - if 'payload_msg' in result and result['payload_msg']['code'] == self.success_code: - if len(result['payload_msg']['result']) > 0: - return result['payload_msg']['result'][0]["text"] + if ( + "payload_msg" in result + and result["payload_msg"]["code"] == self.success_code + ): + if len(result["payload_msg"]["result"]) > 0: + return result["payload_msg"]["result"][0]["text"] return None else: logger.bind(tag=TAG).error(f"ASR error: {result}") @@ -231,7 +244,7 @@ class ASRProvider(ASRProviderBase): @staticmethod def read_wav_info(data: io.BytesIO = None) -> (int, int, int, int, int): with io.BytesIO(data) as _f: - wave_fp = wave.open(_f, 'rb') + wave_fp = wave.open(_f, "rb") nchannels, sampwidth, framerate, nframes = wave_fp.getparams()[:4] wave_bytes = wave_fp.readframes(nframes) return nchannels, sampwidth, framerate, nframes, len(wave_bytes) @@ -247,17 +260,19 @@ class ASRProvider(ASRProviderBase): data_len = len(data) offset = 0 while offset + chunk_size < data_len: - yield data[offset: offset + chunk_size], False + yield data[offset : offset + chunk_size], False offset += chunk_size else: - yield data[offset: data_len], True + yield data[offset:data_len], True - async def speech_to_text(self, opus_data: List[bytes], session_id: str) -> Tuple[Optional[str], Optional[str]]: + async def speech_to_text( + self, opus_data: List[bytes], session_id: str + ) -> Tuple[Optional[str], Optional[str]]: """将语音数据转换为文本""" try: # 合并所有opus数据包 pcm_data = self.decode_opus(opus_data, session_id) - combined_pcm_data = b''.join(pcm_data) + combined_pcm_data = b"".join(pcm_data) # 直接使用PCM数据 # 计算分段大小 (单声道, 16bit, 16kHz采样率) @@ -268,7 +283,9 @@ class ASRProvider(ASRProviderBase): start_time = time.time() text = await self._send_request(combined_pcm_data, segment_size) if text: - logger.bind(tag=TAG).debug(f"语音识别耗时: {time.time() - start_time:.3f}s | 结果: {text}") + logger.bind(tag=TAG).debug( + f"语音识别耗时: {time.time() - start_time:.3f}s | 结果: {text}" + ) return text, None return "", None diff --git a/main/xiaozhi-server/plugins_func/functions/get_weather.py b/main/xiaozhi-server/plugins_func/functions/get_weather.py index b17755a2..dc7976dd 100644 --- a/main/xiaozhi-server/plugins_func/functions/get_weather.py +++ b/main/xiaozhi-server/plugins_func/functions/get_weather.py @@ -153,21 +153,17 @@ def parse_weather_info(soup): def get_weather(conn, location: str = None, lang: str = "zh_CN"): api_key = conn.config["plugins"]["get_weather"]["api_key"] default_location = conn.config["plugins"]["get_weather"]["default_location"] - print("用户设置的default_location为:", default_location) client_ip = conn.client_ip - print("用户提供的location为:", location) # 优先使用用户提供的location参数 if not location: # 通过客户端IP解析城市 if client_ip: # 动态解析IP对应的城市信息 ip_info = get_ip_info(client_ip, logger) - print("解析用户IP后的城市为:", ip_info) location = ip_info.get("city") if ip_info and "city" in ip_info else None else: # 若IP解析失败或无IP,使用默认位置 location = default_location - print("解析失败,将使用默认地址", location) city_info = fetch_city_info(location, api_key) if not city_info: @@ -179,8 +175,6 @@ def get_weather(conn, location: str = None, lang: str = "zh_CN"): return ActionResponse(Action.REQLLM, None, "请求失败") city_name, current_abstract, current_basic, temps_list = parse_weather_info(soup) - print(f"当前查询的城市名称是: {city_name}") - weather_report = f"您查询的位置是:{city_name}\n\n当前天气: {current_abstract}\n" # 添加有效的当前天气参数