diff --git a/src/manage/img/11.jpg b/src/manage/img/11.jpg new file mode 100644 index 0000000..9c9247b Binary files /dev/null and b/src/manage/img/11.jpg differ diff --git a/src/manage/img/22.jpg b/src/manage/img/22.jpg new file mode 100644 index 0000000..6b63407 Binary files /dev/null and b/src/manage/img/22.jpg differ diff --git a/src/manage/itt/ReadMe b/src/manage/itt/ReadMe new file mode 100644 index 0000000..8f57aec --- /dev/null +++ b/src/manage/itt/ReadMe @@ -0,0 +1,2 @@ +主要实现每1s读取一次img目录中的图片,并且识别的图片中的文字会存储到txt目录中, +另外,txt目录中设置了当存储的备份文件即历史识别后结构仅仅保留最后1m以来做记录器。 diff --git a/src/manage/itt/wenzhi.py b/src/manage/itt/wenzhi.py new file mode 100644 index 0000000..fc7078f --- /dev/null +++ b/src/manage/itt/wenzhi.py @@ -0,0 +1,99 @@ +import pytesseract +from PIL import Image +import sys +import os +import time +import datetime + + +def ensure_directories(): + # 确保存储输出文本的目录存在 + output_dir = 'txt' + if not os.path.exists(output_dir): + os.makedirs(output_dir) + +def ensure_pytesseract_installed(): + try: + # 尝试导入pytesseract以确认它已安装 + import pytesseract + except ImportError: + print("pytesseract库未安装。请运行'pip install pytesseract'来安装它。") + sys.exit(1) + +def ensure_tesseract_executable_configured(): + try: + # 尝试获取Tesseract的路径以确认它已配置 + pytesseract.pytesseract.tesseract_cmd + except AttributeError: + print("未配置Tesseract可执行文件的路径。请在pytesseract中设置tesseract_cmd。") + sys.exit(1) + +def image_to_text(image_path): + try: + # 打开图像文件 + img = Image.open(image_path) + except IOError: + print(f"无法打开图像文件:{image_path}") + return None + + try: + # 使用pytesseract进行文字识别 + text = pytesseract.image_to_string(img, lang='eng') + except Exception as e: + print(f"文字识别过程中发生错误:{e}") + return None + + return text + +def main(): + # 确保pytesseract库已安装 + ensure_pytesseract_installed() + + # 确保配置了Tesseract可执行文件的路径 + ensure_tesseract_executable_configured() + + # 确保输出目录存在 + ensure_directories() + + # 设置输出目录路径 + output_dir_path = 'txt' + + + # 主循环,每3秒处理一张图片 + while True: + # 获取当前时间,并格式化为文件名 + current_time = datetime.datetime.now().strftime("%Y%m%d%H%M%S") + image_filename = f"{current_time}.jpg" + #image_path = os.path.join('img', image_filename) + image_path = 'img/22.jpg' + output_file_path = os.path.join(output_dir_path, f"{current_time}.txt") + + # 检查图片是否存在 + if not os.path.exists(image_path): + print(f"图片 {image_path} 不存在,等待下一张...") + time.sleep(1) + continue + + # 调用image_to_text函数并将结果写入文件 + text = image_to_text(image_path) + if text: + with open(output_file_path, 'w', encoding='utf-8') as file: + file.write(text) + print(f"图片 {image_filename} 的识别结果已保存到 {output_file_path}") + else: + print(f"无法识别图片 {image_filename} 中的文字。") + + # 检查txt文件夹中的文件数量,如果超过60个,删除最早的文件 + files = os.listdir(output_dir_path) + if len(files) > 60: + # 对文件进行排序,以便找到最早的文件 + files.sort() + oldest_file_path = os.path.join(output_dir_path, files[0]) + os.remove(oldest_file_path) + print(f"已删除最早的文件:{oldest_file_path}") + + # 等待1秒 + time.sleep(1) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/src/manage/log.txt b/src/manage/log.txt new file mode 100644 index 0000000..3342b69 --- /dev/null +++ b/src/manage/log.txt @@ -0,0 +1,242 @@ +2024年 07月 01日 星期一 21:13:13 CST: wenzhi.py 被停止, PID: 29387 +2024年 07月 01日 星期一 21:13:13 CST: tts.py 运行失败,退出状态码 1, PID: 29405 +2024年 07月 01日 星期一 21:13:18 CST: wenzhi.py 被停止, PID: 29408 +2024年 07月 01日 星期一 21:13:18 CST: tts.py 运行失败,退出状态码 1, PID: 29435 +2024年 07月 01日 星期一 21:13:23 CST: wenzhi.py 被停止, PID: 29456 +2024年 07月 01日 星期一 21:13:23 CST: tts.py 运行失败,退出状态码 1, PID: 29474 +2024年 07月 01日 星期一 21:14:26 CST: wenzhi.py 被停止, PID: 29817 +2024年 07月 01日 星期一 21:14:26 CST: tts.py 运行失败,退出状态码 1, PID: 29835 +2024年 07月 01日 星期一 21:14:31 CST: wenzhi.py 被停止, PID: 29838 +2024年 07月 01日 星期一 21:14:31 CST: tts.py 运行失败,退出状态码 1, PID: 29865 +2024年 07月 01日 星期一 21:16:08 CST: wenzhi.py 被停止, PID: 30373 +2024年 07月 01日 星期一 21:16:08 CST: tts.py 运行失败,退出状态码 1, PID: 30391 +2024年 07月 01日 星期一 21:16:13 CST: wenzhi.py 被停止, PID: 30412 +2024年 07月 01日 星期一 21:16:13 CST: tts.py 运行失败,退出状态码 1, PID: 30466 +2024年 07月 01日 星期一 21:16:18 CST: wenzhi.py 被停止, PID: 30469 +2024年 07月 01日 星期一 21:16:18 CST: tts.py 运行失败,退出状态码 1, PID: 30550 +2024年 07月 01日 星期一 21:16:42 CST: wenzhi.py 被停止, PID: 30664 +2024年 07月 01日 星期一 21:16:42 CST: tts.py 运行失败,退出状态码 1, PID: 30691 +2024年 07月 01日 星期一 21:16:47 CST: wenzhi.py 被停止, PID: 30694 +2024年 07月 01日 星期一 21:16:47 CST: tts.py 运行失败,退出状态码 1, PID: 30721 +2024年 07月 01日 星期一 21:16:52 CST: wenzhi.py 被停止, PID: 30733 +2024年 07月 01日 星期一 21:16:52 CST: tts.py 运行失败,退出状态码 1, PID: 30769 +2024年 07月 01日 星期一 21:16:57 CST: wenzhi.py 被停止, PID: 30781 +2024年 07月 01日 星期一 21:16:57 CST: tts.py 运行失败,退出状态码 1, PID: 30835 +2024年 07月 01日 星期一 21:17:02 CST: wenzhi.py 被停止, PID: 30838 +2024年 07月 01日 星期一 21:17:02 CST: tts.py 运行失败,退出状态码 1, PID: 30895 +2024年 07月 01日 星期一 21:19:05 CST: wenzhi.py 被停止, PID: 31525 +2024年 07月 01日 星期一 21:19:05 CST: tts.py 运行失败,退出状态码 1, PID: 31543 +2024年 07月 01日 星期一 21:19:10 CST: wenzhi.py 被停止, PID: 31546 +2024年 07月 01日 星期一 21:19:10 CST: tts.py 运行失败,退出状态码 1, PID: 31573 +2024年 07月 01日 星期一 21:20:16 CST: wenzhi.py 被停止, PID: 31924 +2024年 07月 01日 星期一 21:20:17 CST: tts.py 运行失败,退出状态码 1, PID: 31960 +2024年 07月 01日 星期一 21:20:22 CST: wenzhi.py 被停止, PID: 31981 +2024年 07月 01日 星期一 21:20:22 CST: tts.py 运行失败,退出状态码 1, PID: 32008 +2024年 07月 01日 星期一 21:20:27 CST: wenzhi.py 被停止, PID: 32029 +2024年 07月 01日 星期一 21:20:27 CST: tts.py 运行失败,退出状态码 1, PID: 32056 +2024年 07月 01日 星期一 21:20:32 CST: wenzhi.py 被停止, PID: 32059 +2024年 07月 01日 星期一 21:20:32 CST: tts.py 运行失败,退出状态码 1, PID: 32086 +2024年 07月 01日 星期一 21:20:37 CST: wenzhi.py 被停止, PID: 32125 +2024年 07月 01日 星期一 21:20:37 CST: tts.py 运行失败,退出状态码 1, PID: 32161 +2024年 07月 01日 星期一 21:20:42 CST: wenzhi.py 被停止, PID: 32191 +2024年 07月 01日 星期一 21:20:42 CST: tts.py 运行失败,退出状态码 1, PID: 32264 +2024年 07月 01日 星期一 21:20:47 CST: wenzhi.py 被停止, PID: 32267 +2024年 07月 01日 星期一 21:20:47 CST: tts.py 运行失败,退出状态码 1, PID: 32303 +2024年 07月 01日 星期一 21:20:52 CST: wenzhi.py 被停止, PID: 32306 +2024年 07月 01日 星期一 21:20:52 CST: tts.py 运行失败,退出状态码 1, PID: 32351 +2024年 07月 01日 星期一 21:20:57 CST: wenzhi.py 被停止, PID: 32354 +2024年 07月 01日 星期一 21:20:57 CST: tts.py 运行失败,退出状态码 1, PID: 32426 +2024年 07月 01日 星期一 23:05:26 CST: wenzhi.py 被停止, PID: 8301 +2024年 07月 01日 星期一 23:05:26 CST: tts.py 运行失败,退出状态码 1, PID: 8318 +2024年 07月 01日 星期一 23:05:28 CST: wenzhi.py 被停止, PID: 8322 +2024年 07月 01日 星期一 23:05:28 CST: tts.py 运行失败,退出状态码 1, PID: 8339 +2024年 07月 01日 星期一 23:05:30 CST: wenzhi.py 被停止, PID: 8352 +2024年 07月 01日 星期一 23:05:30 CST: tts.py 运行失败,退出状态码 1, PID: 8369 +2024年 07月 01日 星期一 23:05:32 CST: wenzhi.py 被停止, PID: 8373 +2024年 07月 01日 星期一 23:05:32 CST: tts.py 运行失败,退出状态码 1, PID: 8400 +2024年 07月 01日 星期一 23:05:34 CST: wenzhi.py 被停止, PID: 8422 +2024年 07月 01日 星期一 23:05:34 CST: tts.py 运行失败,退出状态码 1, PID: 8448 +2024年 07月 01日 星期一 23:09:24 CST: wenzhi.py 被停止, PID: 10042 +2024年 07月 01日 星期一 23:09:24 CST: tts.py 运行失败,退出状态码 1, PID: 10069 +2024年 07月 01日 星期一 23:09:26 CST: wenzhi.py 被停止, PID: 10073 +2024年 07月 01日 星期一 23:09:27 CST: tts.py 运行失败,退出状态码 1, PID: 10090 +2024年 07月 01日 星期一 23:09:29 CST: wenzhi.py 被停止, PID: 10121 +2024年 07月 01日 星期一 23:09:29 CST: tts.py 运行失败,退出状态码 1, PID: 10129 +2024年 07月 01日 星期一 23:09:31 CST: wenzhi.py 被停止, PID: 10178 +2024年 07月 01日 星期一 23:09:31 CST: tts.py 运行失败,退出状态码 1, PID: 10195 +2024年 07月 01日 星期一 23:09:33 CST: wenzhi.py 被停止, PID: 10208 +2024年 07月 01日 星期一 23:09:33 CST: tts.py 运行失败,退出状态码 1, PID: 10225 +2024年 07月 01日 星期一 23:09:35 CST: wenzhi.py 被停止, PID: 10229 +2024年 07月 01日 星期一 23:09:35 CST: tts.py 运行失败,退出状态码 1, PID: 10237 +2024年 07月 01日 星期一 23:09:37 CST: wenzhi.py 被停止, PID: 10241 +2024年 07月 01日 星期一 23:09:37 CST: tts.py 运行失败,退出状态码 1, PID: 10249 +2024年 07月 01日 星期一 23:09:39 CST: wenzhi.py 被停止, PID: 10289 +2024年 07月 01日 星期一 23:09:39 CST: tts.py 运行失败,退出状态码 1, PID: 10306 +2024年 07月 01日 星期一 23:09:41 CST: wenzhi.py 被停止, PID: 10310 +2024年 07月 01日 星期一 23:09:41 CST: tts.py 运行失败,退出状态码 1, PID: 10327 +2024年 07月 01日 星期一 23:09:43 CST: wenzhi.py 被停止, PID: 10340 +2024年 07月 01日 星期一 23:09:43 CST: tts.py 运行失败,退出状态码 1, PID: 10357 +2024年 07月 01日 星期一 23:09:45 CST: wenzhi.py 被停止, PID: 10379 +2024年 07月 01日 星期一 23:09:45 CST: tts.py 运行失败,退出状态码 1, PID: 10396 +2024年 07月 01日 星期一 23:13:21 CST: wenzhi.py 被停止, PID: 11686 +2024年 07月 01日 星期一 23:13:21 CST: tts.py 运行成功, PID: 11694 +2024年 07月 01日 星期一 23:13:23 CST: wenzhi.py 被停止, PID: 11698 +2024年 07月 01日 星期一 23:13:23 CST: tts.py 运行成功, PID: 11733 +2024年 07月 01日 星期一 23:14:23 CST: wenzhi.py 被停止, PID: 12133 +2024年 07月 01日 星期一 23:14:23 CST: tts.py 运行成功, PID: 12141 +2024年 07月 01日 星期一 23:14:25 CST: wenzhi.py 被停止, PID: 12154 +2024年 07月 01日 星期一 23:14:25 CST: tts.py 运行成功, PID: 12180 +2024年 07月 01日 星期一 23:16:13 CST: wenzhi.py 被停止, PID: 12910 +2024年 07月 01日 星期一 23:16:13 CST: tts.py 运行成功, PID: 12918 +2024年 07月 01日 星期一 23:16:15 CST: wenzhi.py 被停止, PID: 12940 +2024年 07月 01日 星期一 23:16:15 CST: tts.py 运行成功, PID: 12957 +2024年 07月 01日 星期一 23:16:17 CST: wenzhi.py 被停止, PID: 12961 +2024年 07月 01日 星期一 23:16:17 CST: tts.py 运行成功, PID: 12978 +2024年 07月 01日 星期一 23:16:19 CST: wenzhi.py 被停止, PID: 12982 +2024年 07月 01日 星期一 23:16:19 CST: tts.py 运行成功, PID: 12990 +2024年 07月 01日 星期一 23:16:21 CST: wenzhi.py 被停止, PID: 12994 +2024年 07月 01日 星期一 23:16:21 CST: tts.py 运行成功, PID: 13002 +2024年 07月 01日 星期一 23:16:23 CST: wenzhi.py 被停止, PID: 13024 +2024年 07月 01日 星期一 23:16:23 CST: tts.py 运行成功, PID: 13041 +2024年 07月 01日 星期一 23:16:25 CST: wenzhi.py 被停止, PID: 13054 +2024年 07月 01日 星期一 23:16:25 CST: tts.py 运行成功, PID: 13062 +2024年 07月 01日 星期一 23:16:27 CST: wenzhi.py 被停止, PID: 13075 +2024年 07月 01日 星期一 23:16:27 CST: tts.py 运行成功, PID: 13083 +2024年 07月 01日 星期一 23:17:10 CST: wenzhi.py 被停止, PID: 13388 +2024年 07月 01日 星期一 23:17:10 CST: tts.py 运行成功, PID: 13396 +2024年 07月 01日 星期一 23:17:12 CST: wenzhi.py 被停止, PID: 13400 +2024年 07月 01日 星期一 23:17:12 CST: tts.py 运行成功, PID: 13408 +2024年 07月 01日 星期一 23:17:23 CST: wenzhi.py 被停止, PID: 13502 +2024年 07月 01日 星期一 23:17:23 CST: tts.py 运行成功, PID: 13510 +2024年 07月 01日 星期一 23:17:25 CST: wenzhi.py 被停止, PID: 13514 +2024年 07月 01日 星期一 23:17:25 CST: tts.py 运行成功, PID: 13522 +2024年 07月 01日 星期一 23:17:27 CST: wenzhi.py 被停止, PID: 13526 +2024年 07月 01日 星期一 23:17:27 CST: tts.py 运行成功, PID: 13534 +2024年 07月 01日 星期一 23:17:59 CST: wenzhi.py 被停止, PID: 13762 +2024年 07月 01日 星期一 23:17:59 CST: tts.py 运行失败,退出状态码 1, PID: 13779 +2024年 07月 01日 星期一 23:18:01 CST: wenzhi.py 被停止, PID: 13783 +2024年 07月 01日 星期一 23:18:01 CST: tts.py 运行失败,退出状态码 1, PID: 13791 +2024年 07月 01日 星期一 23:18:03 CST: wenzhi.py 被停止, PID: 13795 +2024年 07月 01日 星期一 23:18:03 CST: tts.py 运行失败,退出状态码 1, PID: 13821 +2024年 07月 01日 星期一 23:18:05 CST: wenzhi.py 被停止, PID: 13825 +2024年 07月 01日 星期一 23:18:05 CST: tts.py 运行失败,退出状态码 1, PID: 13833 +2024年 07月 01日 星期一 23:18:07 CST: wenzhi.py 被停止, PID: 13837 +2024年 07月 01日 星期一 23:18:07 CST: tts.py 运行失败,退出状态码 1, PID: 13854 +2024年 07月 01日 星期一 23:18:09 CST: wenzhi.py 被停止, PID: 13867 +2024年 07月 01日 星期一 23:18:09 CST: tts.py 运行失败,退出状态码 1, PID: 13875 +2024年 07月 01日 星期一 23:18:11 CST: wenzhi.py 被停止, PID: 13879 +2024年 07月 01日 星期一 23:18:11 CST: tts.py 运行失败,退出状态码 1, PID: 13887 +2024年 07月 01日 星期一 23:18:13 CST: wenzhi.py 被停止, PID: 13891 +2024年 07月 01日 星期一 23:18:13 CST: tts.py 运行失败,退出状态码 1, PID: 13899 +2024年 07月 01日 星期一 23:18:15 CST: wenzhi.py 被停止, PID: 13903 +2024年 07月 01日 星期一 23:18:15 CST: tts.py 运行失败,退出状态码 1, PID: 13911 +2024年 07月 01日 星期一 23:18:17 CST: wenzhi.py 被停止, PID: 13915 +2024年 07月 01日 星期一 23:18:18 CST: tts.py 运行失败,退出状态码 1, PID: 13923 +2024年 07月 01日 星期一 23:18:20 CST: wenzhi.py 被停止, PID: 13927 +2024年 07月 01日 星期一 23:18:20 CST: tts.py 运行失败,退出状态码 1, PID: 13935 +2024年 07月 01日 星期一 23:18:22 CST: wenzhi.py 被停止, PID: 13939 +2024年 07月 01日 星期一 23:18:22 CST: tts.py 运行失败,退出状态码 1, PID: 13947 +2024年 07月 01日 星期一 23:18:24 CST: wenzhi.py 被停止, PID: 13960 +2024年 07月 01日 星期一 23:18:24 CST: tts.py 运行失败,退出状态码 1, PID: 13968 +2024年 07月 01日 星期一 23:18:26 CST: wenzhi.py 被停止, PID: 13972 +2024年 07月 01日 星期一 23:18:26 CST: tts.py 运行失败,退出状态码 1, PID: 13980 +2024年 07月 01日 星期一 23:18:28 CST: wenzhi.py 被停止, PID: 13984 +2024年 07月 01日 星期一 23:18:28 CST: tts.py 运行失败,退出状态码 1, PID: 13992 +2024年 07月 01日 星期一 23:18:30 CST: wenzhi.py 被停止, PID: 13996 +2024年 07月 01日 星期一 23:18:30 CST: tts.py 运行失败,退出状态码 1, PID: 14004 +2024年 07月 01日 星期一 23:18:32 CST: wenzhi.py 被停止, PID: 14017 +2024年 07月 01日 星期一 23:18:32 CST: tts.py 运行失败,退出状态码 1, PID: 14025 +2024年 07月 01日 星期一 23:18:34 CST: wenzhi.py 被停止, PID: 14029 +2024年 07月 01日 星期一 23:18:34 CST: tts.py 运行失败,退出状态码 1, PID: 14046 +2024年 07月 01日 星期一 23:18:36 CST: wenzhi.py 被停止, PID: 14050 +2024年 07月 01日 星期一 23:18:36 CST: tts.py 运行失败,退出状态码 1, PID: 14076 +2024年 07月 01日 星期一 23:18:38 CST: wenzhi.py 被停止, PID: 14080 +2024年 07月 01日 星期一 23:18:38 CST: tts.py 运行失败,退出状态码 1, PID: 14088 +2024年 07月 01日 星期一 23:18:40 CST: wenzhi.py 被停止, PID: 14092 +2024年 07月 01日 星期一 23:18:40 CST: tts.py 运行失败,退出状态码 1, PID: 14109 +2024年 07月 01日 星期一 23:18:42 CST: wenzhi.py 被停止, PID: 14113 +2024年 07月 01日 星期一 23:18:42 CST: tts.py 运行失败,退出状态码 1, PID: 14130 +2024年 07月 01日 星期一 23:18:44 CST: wenzhi.py 被停止, PID: 14134 +2024年 07月 01日 星期一 23:18:44 CST: tts.py 运行失败,退出状态码 1, PID: 14142 +2024年 07月 01日 星期一 23:18:46 CST: wenzhi.py 被停止, PID: 14146 +2024年 07月 01日 星期一 23:18:46 CST: tts.py 运行失败,退出状态码 1, PID: 14154 +2024年 07月 01日 星期一 23:18:48 CST: wenzhi.py 被停止, PID: 14167 +2024年 07月 01日 星期一 23:18:48 CST: tts.py 运行失败,退出状态码 1, PID: 14184 +2024年 07月 01日 星期一 23:18:50 CST: wenzhi.py 被停止, PID: 14197 +2024年 07月 01日 星期一 23:18:50 CST: tts.py 运行失败,退出状态码 1, PID: 14223 +2024年 07月 01日 星期一 23:18:52 CST: wenzhi.py 被停止, PID: 14227 +2024年 07月 01日 星期一 23:18:52 CST: tts.py 运行失败,退出状态码 1, PID: 14235 +2024年 07月 01日 星期一 23:18:54 CST: wenzhi.py 被停止, PID: 14248 +2024年 07月 01日 星期一 23:18:54 CST: tts.py 运行失败,退出状态码 1, PID: 14282 +2024年 07月 01日 星期一 23:18:56 CST: wenzhi.py 被停止, PID: 14296 +2024年 07月 01日 星期一 23:18:56 CST: tts.py 运行失败,退出状态码 1, PID: 14313 +2024年 07月 01日 星期一 23:18:58 CST: wenzhi.py 被停止, PID: 14334 +2024年 07月 01日 星期一 23:18:58 CST: tts.py 运行失败,退出状态码 1, PID: 14361 +2024年 07月 01日 星期一 23:19:00 CST: wenzhi.py 被停止, PID: 14374 +2024年 07月 01日 星期一 23:19:00 CST: tts.py 运行失败,退出状态码 1, PID: 14391 +2024年 07月 01日 星期一 23:19:02 CST: wenzhi.py 被停止, PID: 14395 +2024年 07月 01日 星期一 23:19:02 CST: tts.py 运行失败,退出状态码 1, PID: 14403 +2024年 07月 01日 星期一 23:19:04 CST: wenzhi.py 被停止, PID: 14425 +2024年 07月 01日 星期一 23:19:04 CST: tts.py 运行失败,退出状态码 1, PID: 14433 +2024年 07月 01日 星期一 23:19:06 CST: wenzhi.py 被停止, PID: 14446 +2024年 07月 01日 星期一 23:19:07 CST: tts.py 运行失败,退出状态码 1, PID: 14463 +2024年 07月 01日 星期一 23:19:09 CST: wenzhi.py 被停止, PID: 14485 +2024年 07月 01日 星期一 23:19:09 CST: tts.py 运行失败,退出状态码 1, PID: 14502 +2024年 07月 01日 星期一 23:19:11 CST: wenzhi.py 被停止, PID: 14515 +2024年 07月 01日 星期一 23:19:11 CST: tts.py 运行失败,退出状态码 1, PID: 14532 +2024年 07月 01日 星期一 23:19:13 CST: wenzhi.py 被停止, PID: 14536 +2024年 07月 01日 星期一 23:19:13 CST: tts.py 运行失败,退出状态码 1, PID: 14544 +2024年 07月 01日 星期一 23:19:15 CST: wenzhi.py 被停止, PID: 14548 +2024年 07月 01日 星期一 23:19:15 CST: tts.py 运行失败,退出状态码 1, PID: 14574 +2024年 07月 01日 星期一 23:19:17 CST: wenzhi.py 被停止, PID: 14578 +2024年 07月 01日 星期一 23:19:17 CST: tts.py 运行失败,退出状态码 1, PID: 14586 +2024年 07月 01日 星期一 23:19:19 CST: wenzhi.py 被停止, PID: 14599 +2024年 07月 01日 星期一 23:19:19 CST: tts.py 运行失败,退出状态码 1, PID: 14616 +2024年 07月 01日 星期一 23:19:21 CST: wenzhi.py 被停止, PID: 14620 +2024年 07月 01日 星期一 23:19:21 CST: tts.py 运行失败,退出状态码 1, PID: 14646 +2024年 07月 01日 星期一 23:19:23 CST: wenzhi.py 被停止, PID: 14650 +2024年 07月 01日 星期一 23:19:23 CST: tts.py 运行失败,退出状态码 1, PID: 14658 +2024年 07月 01日 星期一 23:19:25 CST: wenzhi.py 被停止, PID: 14671 +2024年 07月 01日 星期一 23:19:25 CST: tts.py 运行失败,退出状态码 1, PID: 14679 +2024年 07月 01日 星期一 23:19:27 CST: wenzhi.py 被停止, PID: 14692 +2024年 07月 01日 星期一 23:19:27 CST: tts.py 运行失败,退出状态码 1, PID: 14709 +2024年 07月 01日 星期一 23:19:29 CST: wenzhi.py 被停止, PID: 14713 +2024年 07月 01日 星期一 23:19:29 CST: tts.py 运行失败,退出状态码 1, PID: 14721 +2024年 07月 01日 星期一 23:19:31 CST: wenzhi.py 被停止, PID: 14735 +2024年 07月 01日 星期一 23:19:31 CST: tts.py 运行失败,退出状态码 1, PID: 14743 +2024年 07月 01日 星期一 23:19:33 CST: wenzhi.py 被停止, PID: 14756 +2024年 07月 01日 星期一 23:19:33 CST: tts.py 运行失败,退出状态码 1, PID: 14773 +2024年 07月 01日 星期一 23:19:35 CST: wenzhi.py 被停止, PID: 14777 +2024年 07月 01日 星期一 23:19:35 CST: tts.py 运行失败,退出状态码 1, PID: 14785 +2024年 07月 01日 星期一 23:19:37 CST: wenzhi.py 被停止, PID: 14798 +2024年 07月 01日 星期一 23:19:37 CST: tts.py 运行失败,退出状态码 1, PID: 14815 +2024年 07月 01日 星期一 23:19:39 CST: wenzhi.py 被停止, PID: 14819 +2024年 07月 01日 星期一 23:19:39 CST: tts.py 运行失败,退出状态码 1, PID: 14836 +2024年 07月 01日 星期一 23:19:41 CST: wenzhi.py 被停止, PID: 14840 +2024年 07月 01日 星期一 23:19:41 CST: tts.py 运行失败,退出状态码 1, PID: 14848 +2024年 07月 01日 星期一 23:19:43 CST: wenzhi.py 被停止, PID: 14852 +2024年 07月 01日 星期一 23:19:43 CST: tts.py 运行失败,退出状态码 1, PID: 14860 +2024年 07月 01日 星期一 23:19:45 CST: wenzhi.py 被停止, PID: 14864 +2024年 07月 01日 星期一 23:19:45 CST: tts.py 运行失败,退出状态码 1, PID: 14872 +2024年 07月 01日 星期一 23:19:47 CST: wenzhi.py 被停止, PID: 14885 +2024年 07月 01日 星期一 23:19:47 CST: tts.py 运行失败,退出状态码 1, PID: 14893 +2024年 07月 01日 星期一 23:19:49 CST: wenzhi.py 被停止, PID: 14897 +2024年 07月 01日 星期一 23:19:49 CST: tts.py 运行失败,退出状态码 1, PID: 14905 +2024年 07月 01日 星期一 23:19:51 CST: wenzhi.py 被停止, PID: 14909 +2024年 07月 01日 星期一 23:19:51 CST: tts.py 运行失败,退出状态码 1, PID: 14926 +2024年 07月 01日 星期一 23:19:53 CST: wenzhi.py 被停止, PID: 14948 +2024年 07月 01日 星期一 23:19:53 CST: tts.py 运行失败,退出状态码 1, PID: 14956 +2024年 07月 01日 星期一 23:19:55 CST: wenzhi.py 被停止, PID: 14969 +2024年 07月 01日 星期一 23:19:55 CST: tts.py 运行失败,退出状态码 1, PID: 14977 +2024年 07月 01日 星期一 23:19:58 CST: wenzhi.py 被停止, PID: 14981 +2024年 07月 01日 星期一 23:19:58 CST: tts.py 运行失败,退出状态码 1, PID: 15007 +2024年 07月 01日 星期一 23:20:00 CST: wenzhi.py 被停止, PID: 15020 +2024年 07月 01日 星期一 23:20:00 CST: tts.py 运行失败,退出状态码 1, PID: 15037 +2024年 07月 01日 星期一 23:20:02 CST: wenzhi.py 被停止, PID: 15041 +2024年 07月 01日 星期一 23:20:02 CST: tts.py 运行失败,退出状态码 1, PID: 15049 +2024年 07月 01日 星期一 23:20:04 CST: wenzhi.py 被停止, PID: 15053 +2024年 07月 01日 星期一 23:20:04 CST: tts.py 运行失败,退出状态码 1, PID: 15061 +2024年 07月 01日 星期一 23:20:06 CST: wenzhi.py 被停止, PID: 15067 +2024年 07月 01日 星期一 23:20:06 CST: tts.py 运行失败,退出状态码 1, PID: 15075 +2024年 07月 01日 星期一 23:20:08 CST: wenzhi.py 被停止, PID: 15079 +2024年 07月 01日 星期一 23:20:08 CST: tts.py 运行失败,退出状态码 1, PID: 15105 diff --git a/src/manage/repted.sh b/src/manage/repted.sh new file mode 100644 index 0000000..724dae8 --- /dev/null +++ b/src/manage/repted.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +# repted.sh +while true; do + # 在后台运行itt目录中的wenzhi.py脚本并获取其PID + python3 itt/wenzhi.py & + wenzhi_pid=$! + + # 等待一段时间,让wenzhi.py开始执行 + sleep 1 + + # 检查wenzhi.py是否还在运行 + if kill -0 $wenzhi_pid 2>/dev/null; then + # wenzhi.py仍在运行,尝试停止它 + kill $wenzhi_pid + wait $wenzhi_pid + echo "$(date): wenzhi.py 被停止, PID: $wenzhi_pid" >> log.txt + else + # wenzhi.py已经停止,记录日志 + echo "$(date): wenzhi.py 已经停止, PID: $wenzhi_pid" >> log.txt + fi + + # 在后台运行tts目录中的tts.py脚本并获取其PID + python3 tts/tts.py & + tts_pid=$! + + # 等待tts.py脚本结束以获取其退出状态 + wait $tts_pid + tts_exit_status=$? + + # 检查tts.py脚本是否成功运行 + if [ $tts_exit_status -eq 0 ]; then + echo "$(date): tts.py 运行成功, PID: $tts_pid" >> log.txt + else + echo "$(date): tts.py 运行失败,退出状态码 $tts_exit_status, PID: $tts_pid" >> log.txt + fi + + # 等待一段时间后再重复这个过程 + sleep 1 +done diff --git a/src/manage/tts/trans.py b/src/manage/tts/trans.py new file mode 100644 index 0000000..b926776 --- /dev/null +++ b/src/manage/tts/trans.py @@ -0,0 +1,69 @@ +import numpy as np +from sklearn.model_selection import train_test_split +from sklearn.preprocessing import OneHotEncoder +from keras.models import Sequential +from keras.layers import Dense, Embedding, Flatten +from keras.preprocessing.sequence import pad_sequences +from keras.utils import to_categorical +import re + +# 文本清洗函数 +def clean_text(text): + # 使用正则表达式去除非标准字符 + cleaned_text = re.sub(r'[^a-zA-Z0-9\s]', '', text.lower()) + return cleaned_text + +# 读取文本文件 +def read_text_file(file_path): + with open(file_path, 'r', encoding='utf-8') as f: + return f.read() + +# 数据准备 +def prepare_data(text, max_sequence_length=10): + words = set(clean_text(text).split()) + word2index = {word: i for i, word in enumerate(words, 1)} + index2word = {i: word for word, i in word2index.items()} + + sentences = text.split('. ') + X, y = [], [] + for sentence in sentences: + cleaned_sentence = clean_text(sentence) + tokens = [word2index[word] for word in cleaned_sentence.split() if word in word2index] + for i in range(1, len(tokens)): + X.append(tokens[:-i]) + y.append(tokens[i]) + + # 使用pad_sequences处理变长序列 + X = pad_sequences(X, maxlen=max_sequence_length, padding='pre', truncating='post') + y = to_categorical(np.array(y), num_classes=len(word2index)) + return X, y, word2index, index2word + +# 读取文本文件并准备数据 +text = read_text_file('input.txt') # 假设输入文件名为input.txt +X, y, word2index, index2word = prepare_data(text) + +# 划分训练集和测试集 +X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) + +# 构建NNLM模型(这里使用Embedding层来捕获词汇之间的相似性) +model = Sequential() +model.add(Embedding(input_dim=len(word2index) + 1, output_dim=32, input_length=max_sequence_length)) +model.add(Flatten()) +model.add(Dense(128, activation='relu')) +model.add(Dense(len(word2index), activation='softmax')) + +model.compile(optimizer='adam', loss='categorical_crossentropy') + +# 训练模型 +model.fit(np.array([x for x in X_train]), y_train, epochs=10, batch_size=32) + +# 预测 +predictions = model.predict([x for x in X_test]) +predicted_words = [np.argmax(pred) for pred in predictions] +predicted_sentences = [' '.join(index2word[word] for word in [sentence[0]] + [predicted_words[i] for i, _ in enumerate(sentence[1:]) if i < len(predicted_words)]) + for sentence in X_test] + +# 将预测结果写入文本文件 +with open('output.txt', 'w', encoding='utf-8') as f: + for sentence in predicted_sentences: + f.write(sentence + '\n') \ No newline at end of file diff --git a/src/manage/tts/tts.py b/src/manage/tts/tts.py new file mode 100644 index 0000000..8ae8441 --- /dev/null +++ b/src/manage/tts/tts.py @@ -0,0 +1,76 @@ +import subprocess +import os +import datetime +from datetime import timedelta +import re + +def speak_text_from_file(file_path, voice='zh', speed=150, pitch=50, output_file=None): + """ + 从文件中读取文本并使用espeak将其转换为语音。 + + :param file_path: 文本文件的路径 + :param voice: 使用的声音(例如 'zh' 用于中文) + :param speed: 语速(默认为 150) + :param pitch: 音调(默认为 50) + :param output_file: 如果指定,将语音输出保存为WAV文件 + """ + with open(file_path, 'r', encoding='utf-8') as file: + text = file.read() + + # 构建espeak命令 + cmd = ['espeak', '-v', voice, '-s', str(speed), '-p', str(pitch)] + if output_file: + cmd.extend(['-w', output_file]) + else: + # 如果没有指定输出文件,则直接播放语音 + pass # 这里可以添加其他选项,如音量调整等 + + # 使用stdin将文本传递给espeak + try: + proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8') + proc.communicate(input=text) + + if proc.returncode != 0: + # 获取并打印错误信息 + error_message = proc.stderr.read() + print(f"Error executing espeak: {error_message}") + except Exception as e: + print(f"An error occurred: {e}") + +# 获取当前文件夹路径 +current_dir = os.getcwd() + +# 获取父文件夹路径 +parent_dir = os.path.dirname(current_dir) + +specific_folder_name = "txt" + +specific_folder_path = os.path.join(current_dir, specific_folder_name) + +# 列出当前文件夹中的所有txt文件 +txt_files = [f for f in os.listdir(specific_folder_path) if f.endswith('.txt')] + +# 提取文件名中的数字,并找出最大的数字 +max_number = -1 +max_file = None +for txt_file in txt_files: + # 使用正则表达式提取文件名中的数字 + match = re.search(r'^(\d+)\.txt$', txt_file) + if match: + file_number = int(match.group(1)) + if file_number > max_number: + max_number = file_number + max_file = txt_file + +# 检查是否找到了数字命名最大的txt文件 +if max_file: + file_path = os.path.join(current_dir, max_file) + # 调用函数来朗读文本文件 + speak_text_from_file(file_path, voice='zh', speed=140, pitch=55) + + # 如果你想要将语音保存为WAV文件,可以这样做: + output_wav_file = 'output/output.wav' # WAV文件的输出路径 + speak_text_from_file(file_path, voice='zh', speed=140, pitch=55, output_file=output_wav_file) +else: + print("没有找到数字命名最大的txt文件。") + print(specific_folder_path) \ No newline at end of file diff --git a/src/manage/txt/20240701231806.txt b/src/manage/txt/20240701231806.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231806.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231808.txt b/src/manage/txt/20240701231808.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231808.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231810.txt b/src/manage/txt/20240701231810.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231810.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231813.txt b/src/manage/txt/20240701231813.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231813.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231815.txt b/src/manage/txt/20240701231815.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231815.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231817.txt b/src/manage/txt/20240701231817.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231817.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231819.txt b/src/manage/txt/20240701231819.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231819.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231821.txt b/src/manage/txt/20240701231821.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231821.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231823.txt b/src/manage/txt/20240701231823.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231823.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231825.txt b/src/manage/txt/20240701231825.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231825.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231827.txt b/src/manage/txt/20240701231827.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231827.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231829.txt b/src/manage/txt/20240701231829.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231829.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231831.txt b/src/manage/txt/20240701231831.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231831.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231833.txt b/src/manage/txt/20240701231833.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231833.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231835.txt b/src/manage/txt/20240701231835.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231835.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231837.txt b/src/manage/txt/20240701231837.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231837.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231839.txt b/src/manage/txt/20240701231839.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231839.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231841.txt b/src/manage/txt/20240701231841.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231841.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231843.txt b/src/manage/txt/20240701231843.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231843.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231845.txt b/src/manage/txt/20240701231845.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231845.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231847.txt b/src/manage/txt/20240701231847.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231847.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231849.txt b/src/manage/txt/20240701231849.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231849.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231851.txt b/src/manage/txt/20240701231851.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231851.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231853.txt b/src/manage/txt/20240701231853.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231853.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231855.txt b/src/manage/txt/20240701231855.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231855.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231857.txt b/src/manage/txt/20240701231857.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231857.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231859.txt b/src/manage/txt/20240701231859.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231859.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231901.txt b/src/manage/txt/20240701231901.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231901.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231904.txt b/src/manage/txt/20240701231904.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231904.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231906.txt b/src/manage/txt/20240701231906.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231906.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231908.txt b/src/manage/txt/20240701231908.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231908.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231910.txt b/src/manage/txt/20240701231910.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231910.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231912.txt b/src/manage/txt/20240701231912.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231912.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231914.txt b/src/manage/txt/20240701231914.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231914.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231916.txt b/src/manage/txt/20240701231916.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231916.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231918.txt b/src/manage/txt/20240701231918.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231918.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231920.txt b/src/manage/txt/20240701231920.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231920.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231922.txt b/src/manage/txt/20240701231922.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231922.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231924.txt b/src/manage/txt/20240701231924.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231924.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231926.txt b/src/manage/txt/20240701231926.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231926.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231928.txt b/src/manage/txt/20240701231928.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231928.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231930.txt b/src/manage/txt/20240701231930.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231930.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231932.txt b/src/manage/txt/20240701231932.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231932.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231934.txt b/src/manage/txt/20240701231934.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231934.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231936.txt b/src/manage/txt/20240701231936.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231936.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231938.txt b/src/manage/txt/20240701231938.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231938.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231940.txt b/src/manage/txt/20240701231940.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231940.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231942.txt b/src/manage/txt/20240701231942.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231942.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231944.txt b/src/manage/txt/20240701231944.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231944.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231946.txt b/src/manage/txt/20240701231946.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231946.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231948.txt b/src/manage/txt/20240701231948.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231948.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231951.txt b/src/manage/txt/20240701231951.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231951.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231953.txt b/src/manage/txt/20240701231953.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231953.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231955.txt b/src/manage/txt/20240701231955.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231955.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231957.txt b/src/manage/txt/20240701231957.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231957.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701231959.txt b/src/manage/txt/20240701231959.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701231959.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701232001.txt b/src/manage/txt/20240701232001.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701232001.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701232003.txt b/src/manage/txt/20240701232003.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701232003.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701232005.txt b/src/manage/txt/20240701232005.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701232005.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/manage/txt/20240701232007.txt b/src/manage/txt/20240701232007.txt new file mode 100644 index 0000000..b7bd227 --- /dev/null +++ b/src/manage/txt/20240701232007.txt @@ -0,0 +1,4 @@ +English + +X is + \ No newline at end of file diff --git a/src/voice_assistant/README.md b/src/voice_assistant/README.md new file mode 100644 index 0000000..06c5c26 --- /dev/null +++ b/src/voice_assistant/README.md @@ -0,0 +1,7 @@ +# 树莓派实现语音助手 + +### 基于: +1. [Snowboy](https://snowboy.kitt.ai/dashboard),用于实现唤醒系统 +2. [百度语音](https://cloud.baidu.com/),用于语音识别 + +#### 使用python编写,具体介绍前往 [树莓派实现语音助手](https://www.passerma.com/article/54) \ No newline at end of file diff --git a/src/voice_assistant/__pycache__/snowboydecoder.cpython-39.pyc b/src/voice_assistant/__pycache__/snowboydecoder.cpython-39.pyc new file mode 100644 index 0000000..3bca655 Binary files /dev/null and b/src/voice_assistant/__pycache__/snowboydecoder.cpython-39.pyc differ diff --git a/src/voice_assistant/__pycache__/snowboydetect.cpython-39.pyc b/src/voice_assistant/__pycache__/snowboydetect.cpython-39.pyc new file mode 100644 index 0000000..e5b5617 Binary files /dev/null and b/src/voice_assistant/__pycache__/snowboydetect.cpython-39.pyc differ diff --git a/src/voice_assistant/_snowboydetect.so b/src/voice_assistant/_snowboydetect.so new file mode 100644 index 0000000..f3c78d3 Binary files /dev/null and b/src/voice_assistant/_snowboydetect.so differ diff --git a/src/voice_assistant/audio/audio.wav b/src/voice_assistant/audio/audio.wav new file mode 100644 index 0000000..a44c5fd Binary files /dev/null and b/src/voice_assistant/audio/audio.wav differ diff --git a/src/voice_assistant/audio/exit.wav b/src/voice_assistant/audio/exit.wav new file mode 100644 index 0000000..8a6a638 Binary files /dev/null and b/src/voice_assistant/audio/exit.wav differ diff --git a/src/voice_assistant/audio/none.wav b/src/voice_assistant/audio/none.wav new file mode 100644 index 0000000..fda5a70 Binary files /dev/null and b/src/voice_assistant/audio/none.wav differ diff --git a/src/voice_assistant/audio/open.wav b/src/voice_assistant/audio/open.wav new file mode 100644 index 0000000..1192790 Binary files /dev/null and b/src/voice_assistant/audio/open.wav differ diff --git a/src/voice_assistant/fetchToken.py b/src/voice_assistant/fetchToken.py new file mode 100644 index 0000000..ba23d52 --- /dev/null +++ b/src/voice_assistant/fetchToken.py @@ -0,0 +1,69 @@ +#从百度AI开放平台获取语音合成(TTS)服务所需的access_token +# -*- coding: utf-8 -*- + +import sys +import json + +# 保证兼容python2以及python3 +IS_PY3 = sys.version_info.major == 3 +if IS_PY3: + from urllib.request import urlopen + from urllib.request import Request + from urllib.error import URLError + from urllib.parse import urlencode + from urllib.parse import quote_plus +else: + import urllib.request + import urllib + from urllib import quote_plus + from urllib import urlopen + from urllib import Request + from urllib import URLError + from urllib import urlencode + +# 替换你的 API_KEY +API_KEY = 'P2o5IjKMXqGz80VzRuv2v9Uj' + +# 替换你的 SECRET_KEY +SECRET_KEY = 'TbvincgBwx4TfOvVXC5WgrP3WED9J2SQ' + +TOKEN_URL = 'http://openapi.baidu.com/oauth/2.0/token' + + +def fetch_token(): + # 定义请求参数 + params = {'grant_type': 'client_credentials', + 'client_id': API_KEY, + 'client_secret': SECRET_KEY} + # 将参数编码为utf-8 + post_data = urlencode(params) + if (IS_PY3): + post_data = post_data.encode('utf-8') + # 创建请求对象 + req = Request(TOKEN_URL, post_data) + try: + # 发送请求 + f = urlopen(req, timeout=5) + result_str = f.read() + except URLError as err: + # 处理异常 + print('token http response http code : ' + str(err.code)) + result_str = err.read() + if (IS_PY3): + result_str = result_str.decode() + + # 将结果转换为字典 + result = json.loads(result_str) + + # 检查结果中是否包含access_token和scope + if ('access_token' in result.keys() and 'scope' in result.keys()): + # 检查scope中是否包含audio_tts_post + if not 'audio_tts_post' in result['scope'].split(' '): + print('please ensure has check the tts ability') + return '' + # 返回access_token + return result['access_token'] + else: + # 否则,检查API_KEY和SECRET_KEY是否正确 + print('please overwrite the correct API_KEY and SECRET_KEY') + return '' diff --git a/src/voice_assistant/resources/._alexa.umdl b/src/voice_assistant/resources/._alexa.umdl new file mode 100644 index 0000000..e8c147b Binary files /dev/null and b/src/voice_assistant/resources/._alexa.umdl differ diff --git a/src/voice_assistant/resources/._alexa_02092017.umdl b/src/voice_assistant/resources/._alexa_02092017.umdl new file mode 100644 index 0000000..e8c147b Binary files /dev/null and b/src/voice_assistant/resources/._alexa_02092017.umdl differ diff --git a/src/voice_assistant/resources/._common.res b/src/voice_assistant/resources/._common.res new file mode 100644 index 0000000..e8c147b Binary files /dev/null and b/src/voice_assistant/resources/._common.res differ diff --git a/src/voice_assistant/resources/._ding.wav b/src/voice_assistant/resources/._ding.wav new file mode 100644 index 0000000..e8c147b Binary files /dev/null and b/src/voice_assistant/resources/._ding.wav differ diff --git a/src/voice_assistant/resources/._dong.wav b/src/voice_assistant/resources/._dong.wav new file mode 100644 index 0000000..e8c147b Binary files /dev/null and b/src/voice_assistant/resources/._dong.wav differ diff --git a/src/voice_assistant/resources/._snowboy.umdl b/src/voice_assistant/resources/._snowboy.umdl new file mode 100644 index 0000000..e8c147b Binary files /dev/null and b/src/voice_assistant/resources/._snowboy.umdl differ diff --git a/src/voice_assistant/resources/alexa.umdl b/src/voice_assistant/resources/alexa.umdl new file mode 100644 index 0000000..0d9db6f Binary files /dev/null and b/src/voice_assistant/resources/alexa.umdl differ diff --git a/src/voice_assistant/resources/alexa_02092017.umdl b/src/voice_assistant/resources/alexa_02092017.umdl new file mode 100644 index 0000000..c4a6094 Binary files /dev/null and b/src/voice_assistant/resources/alexa_02092017.umdl differ diff --git a/src/voice_assistant/resources/common.res b/src/voice_assistant/resources/common.res new file mode 100644 index 0000000..0e267f5 Binary files /dev/null and b/src/voice_assistant/resources/common.res differ diff --git a/src/voice_assistant/resources/ding.wav b/src/voice_assistant/resources/ding.wav new file mode 100644 index 0000000..79346e0 Binary files /dev/null and b/src/voice_assistant/resources/ding.wav differ diff --git a/src/voice_assistant/resources/dong.wav b/src/voice_assistant/resources/dong.wav new file mode 100644 index 0000000..426596b Binary files /dev/null and b/src/voice_assistant/resources/dong.wav differ diff --git a/src/voice_assistant/resources/snowboy.umdl b/src/voice_assistant/resources/snowboy.umdl new file mode 100644 index 0000000..bb68185 Binary files /dev/null and b/src/voice_assistant/resources/snowboy.umdl differ diff --git a/src/voice_assistant/snow.py b/src/voice_assistant/snow.py new file mode 100644 index 0000000..eb3f4bb --- /dev/null +++ b/src/voice_assistant/snow.py @@ -0,0 +1,195 @@ +import snowboydecoder +import signal +import wave +import sys +import json +import requests +import time +import os +import base64 +from pyaudio import PyAudio, paInt16 +import webbrowser +from fetchToken import fetch_token +import time + +IS_PY3 = sys.version_info.major == 3 +if IS_PY3: + from urllib.request import urlopen + from urllib.request import Request + from urllib.error import URLError + from urllib.parse import urlencode + from urllib.parse import quote_plus +else: + import urllib.request + from urllib import quote_plus + from urllib.request import urlopen + from urllib.request import Request + from urllib.request import URLError + from urllib import urlencode + +interrupted = False # snowboy监听唤醒结束标志 +endSnow = False # 程序结束标志 + +framerate = 16000 # 采样率 +num_samples = 2000 # 采样点 +channels = 1 # 声道 +sampwidth = 2 # 采样宽度2bytes + +FILEPATH = './audio/audio.wav' # 录制完成存放音频路径 +music_exit = './audio/exit.wav' # 唤醒系统退出语音 +music_open = './audio/open.wav' # 唤醒系统打开语音 +os.close(sys.stderr.fileno()) # 去掉错误警告 + +def signal_handler(signal, frame): + """ + 监听键盘结束 + """ + global interrupted + interrupted = True + +def interrupt_callback(): + """ + 监听唤醒 + """ + global interrupted + return interrupted + +def detected(): + """ + 唤醒成功 + """ + print('唤醒成功') + play(music_open) + global interrupted + interrupted = True + detector.terminate() + +def play(filename): + """ + 播放音频 + """ + wf = wave.open(filename, 'rb') # 打开audio.wav + p = PyAudio() # 实例化 pyaudio + # 打开流 + stream = p.open(format=p.get_format_from_width(wf.getsampwidth()), + channels=wf.getnchannels(), + rate=wf.getframerate(), + output=True) + data = wf.readframes(1024) + while data != b'': + data = wf.readframes(1024) + stream.write(data) + # 释放IO + stream.stop_stream() + stream.close() + p.terminate() + +def save_wave_file(filepath, data): + """ + 存储文件 + """ + # 打开文件 + wf = wave.open(filepath, 'wb') + # 设置通道数 + wf.setnchannels(channels) + # 设置采样宽度 + wf.setsampwidth(sampwidth) + # 设置帧率 + wf.setframerate(framerate) + # 将数据写入文件 + wf.writeframes(b''.join(data)) + # 关闭文件 + wf.close() + +def my_record(): + """ + 录音 + """ + pa = PyAudio() # 初始化pyaudio + stream = pa.open(format=paInt16, channels=channels, + rate=framerate, input=True, frames_per_buffer=num_samples) # 打开流 + my_buf = [] # 初始化缓冲区 + # count = 0 + t = time.time() + print('开始录音...') # 打印开始录音信息 + while time.time() < t + 4: + string_audio_data = stream.read(num_samples) # 读取数据 + my_buf.append(string_audio_data) # 添加到缓冲区 + print('录音结束!') # 打印录音结束信息 + save_wave_file(FILEPATH, my_buf) # 保存录音文件 + stream.close() # 关闭流 + + +def speech2text(speech_data, token, dev_pid=1537): + """ + 音频转文字 + """ + FORMAT = 'wav' + RATE = '16000' + CHANNEL = 1 + CUID = 'baidu_workshop' + SPEECH = base64.b64encode(speech_data).decode('utf-8') + data = { + 'format': FORMAT, + 'rate': RATE, + 'channel': CHANNEL, + 'cuid': CUID, + 'len': len(speech_data), + 'speech': SPEECH, + 'token': token, + 'dev_pid': dev_pid + } + # 语音转文字接口 该接口可能每个人不一样,取决于你需要哪种语音识别功能,本文使用的是 语音识别极速版 + + url = 'https://vop.baidu.com/pro_api' + headers = {'Content-Type': 'application/json'} # 请求头 + print('正在识别...') + r = requests.post(url, json=data, headers=headers) + Result = r.json() + if 'result' in Result: + return Result['result'][0] + else: + return Result + +def get_audio(file): + """ + 获取音频文件 + """ + with open(file, 'rb') as f: + data = f.read() + return data + +def identifyComplete(text): + """ + 识别成功 + """ + print(text) + maps = { + '打开百度': ['打开百度。', '打开百度', '打开百度,', 'baidu'] + } + if (text == '再见。' or text == '拜拜。'): + play(music_exit) # 关闭系统播放反馈语音 + exit() + if text in maps['打开百度']: + webbrowser.open_new_tab('https://www.baidu.com') + play('./audio/openbaidu.wav') # 识别到播放反馈语音 + else: + play('./audio/none.wav') # 未匹配口令播放反馈语音 + print('操作完成') + +if __name__ == "__main__": + while endSnow == False: + interrupted = False + # 实例化snowboy,第一个参数就是唤醒识别模型位置 + detector = snowboydecoder.HotwordDetector('ma.pmdl', sensitivity=0.5) + print('等待唤醒') + # snowboy监听循环 + detector.start(detected_callback=detected, + interrupt_check=interrupt_callback, + sleep_time=0.03) + my_record() # 唤醒成功开始录音 + TOKEN = fetch_token() # 获取token + speech = get_audio(FILEPATH) + result = speech2text(speech, TOKEN, int(80001)) + if type(result) == str: + identifyComplete(result.strip(',')) \ No newline at end of file diff --git a/src/voice_assistant/snowboydecoder.py b/src/voice_assistant/snowboydecoder.py new file mode 100644 index 0000000..86e001c --- /dev/null +++ b/src/voice_assistant/snowboydecoder.py @@ -0,0 +1,194 @@ +#!/usr/bin/env python + +import collections +import pyaudio +import snowboydetect +import time +import wave +import os +import logging + +logging.basicConfig() +logger = logging.getLogger("snowboy") +logger.setLevel(logging.INFO) +TOP_DIR = os.path.dirname(os.path.abspath(__file__)) + +RESOURCE_FILE = os.path.join(TOP_DIR, "resources/common.res") +DETECT_DING = os.path.join(TOP_DIR, "resources/ding.wav") +DETECT_DONG = os.path.join(TOP_DIR, "resources/dong.wav") + + +class RingBuffer(object): + """Ring buffer to hold audio from PortAudio""" + + def __init__(self, size=4096): + self._buf = collections.deque(maxlen=size) + + def extend(self, data): + """Adds data to the end of buffer""" + self._buf.extend(data) + + def get(self): + """Retrieves data from the beginning of buffer and clears it""" + tmp = bytes(bytearray(self._buf)) + self._buf.clear() + return tmp + + +def play_audio_file(fname=DETECT_DING): + """Simple callback function to play a wave file. By default it plays + a Ding sound. + + :param str fname: wave file name + :return: None + """ + # 打开wave文件 + ding_wav = wave.open(fname, 'rb') + # 读取文件内容 + ding_data = ding_wav.readframes(ding_wav.getnframes()) + # 初始化pyaudio + audio = pyaudio.PyAudio() + # 打开音频流 + stream_out = audio.open( + format=audio.get_format_from_width(ding_wav.getsampwidth()), + channels=ding_wav.getnchannels(), + rate=ding_wav.getframerate(), input=False, output=True) + # 开始音频流 + stream_out.start_stream() + # 写入音频数据 + stream_out.write(ding_data) + # 等待0.2秒 + time.sleep(0.2) + # 停止音频流 + stream_out.stop_stream() + stream_out.close() + # 关闭pyaudio + audio.terminate() + + +class HotwordDetector(object): + """ + Snowboy decoder to detect whether a keyword specified by `decoder_model` + exists in a microphone input stream. + + :param decoder_model: decoder model file path, a string or a list of strings + :param resource: resource file path. + :param sensitivity: decoder sensitivity, a float of a list of floats. + The bigger the value, the more senstive the + decoder. If an empty list is provided, then the + default sensitivity in the model will be used. + :param audio_gain: multiply input volume by this factor. + """ + + def __init__(self, decoder_model, + resource=RESOURCE_FILE, + sensitivity=[], + audio_gain=1): + + def audio_callback(in_data, frame_count, time_info, status): + self.ring_buffer.extend(in_data) + play_data = chr(0) * len(in_data) + return play_data, pyaudio.paContinue + + tm = type(decoder_model) + ts = type(sensitivity) + if tm is not list: + decoder_model = [decoder_model] + if ts is not list: + sensitivity = [sensitivity] + model_str = ",".join(decoder_model) + + self.detector = snowboydetect.SnowboyDetect( + resource_filename=resource.encode(), model_str=model_str.encode()) + self.detector.SetAudioGain(audio_gain) + self.num_hotwords = self.detector.NumHotwords() + + if len(decoder_model) > 1 and len(sensitivity) == 1: + sensitivity = sensitivity*self.num_hotwords + if len(sensitivity) != 0: + assert self.num_hotwords == len(sensitivity), \ + "number of hotwords in decoder_model (%d) and sensitivity " \ + "(%d) does not match" % (self.num_hotwords, len(sensitivity)) + sensitivity_str = ",".join([str(t) for t in sensitivity]) + if len(sensitivity) != 0: + self.detector.SetSensitivity(sensitivity_str.encode()) + + self.ring_buffer = RingBuffer( + self.detector.NumChannels() * self.detector.SampleRate() * 5) + self.audio = pyaudio.PyAudio() + self.stream_in = self.audio.open( + input=True, output=False, + format=self.audio.get_format_from_width( + self.detector.BitsPerSample() / 8), + channels=self.detector.NumChannels(), + rate=self.detector.SampleRate(), + frames_per_buffer=2048, + stream_callback=audio_callback) + + def start(self, detected_callback=play_audio_file, + interrupt_check=lambda: False, + sleep_time=0.03): + """ + Start the voice detector. For every `sleep_time` second it checks the + audio buffer for triggering keywords. If detected, then call + corresponding function in `detected_callback`, which can be a single + function (single model) or a list of callback functions (multiple + models). Every loop it also calls `interrupt_check` -- if it returns + True, then breaks from the loop and return. + + :param detected_callback: a function or list of functions. The number of + items must match the number of models in + `decoder_model`. + :param interrupt_check: a function that returns True if the main loop + needs to stop. + :param float sleep_time: how much time in second every loop waits. + :return: None + """ + if interrupt_check(): + logger.debug("detect voice return") + return + + tc = type(detected_callback) + if tc is not list: + detected_callback = [detected_callback] + if len(detected_callback) == 1 and self.num_hotwords > 1: + detected_callback *= self.num_hotwords + + assert self.num_hotwords == len(detected_callback), \ + "Error: hotwords in your models (%d) do not match the number of " \ + "callbacks (%d)" % (self.num_hotwords, len(detected_callback)) + + logger.debug("detecting...") + + while True: + if interrupt_check(): + logger.debug("detect voice break") + break + data = self.ring_buffer.get() + if len(data) == 0: + time.sleep(sleep_time) + continue + + ans = self.detector.RunDetection(data) + if ans == -1: + logger.warning( + "Error initializing streams or reading audio data") + elif ans > 0: + message = "Keyword " + str(ans) + " detected at time: " + message += time.strftime("%Y-%m-%d %H:%M:%S", + time.localtime(time.time())) + logger.info(message) + callback = detected_callback[ans-1] + if callback is not None: + callback() + + logger.debug("finished.") + + def terminate(self): + """ + Terminate audio stream. Users cannot call start() again to detect. + :return: None + """ + self.stream_in.stop_stream() + self.stream_in.close() + self.audio.terminate() diff --git a/src/voice_assistant/snowboydetect.py b/src/voice_assistant/snowboydetect.py new file mode 100644 index 0000000..bfa5f6a --- /dev/null +++ b/src/voice_assistant/snowboydetect.py @@ -0,0 +1,180 @@ +# 导入sys模块,并判断版本信息是否大于等于(2, 6, 0) +from sys import version_info +# 如果版本信息大于等于(2, 6, 0),则定义swig_import_helper函数 +if version_info >= (2, 6, 0): + def swig_import_helper(): + # 从os.path模块导入dirname函数 + from os.path import dirname + # 从importlib模块导入load_module函数 + import importlib + # 定义fp变量 + fp = None + # 尝试导入_snowboydetect模块 + try: + fp, pathname, description = importlib.find_module( + '_snowboydetect', [dirname(__file__)]) + # 如果导入失败,则导入_snowboydetect模块 + except ImportError: + import _snowboydetect + return _snowboydetect + # 如果fp不为空,则执行以下操作 + if fp is not None: + try: + # 从fp, pathname, description中导入_mod模块 + _mod = importlib.load_module( + '_snowboydetect', fp, pathname, description) + # finally语句块,关闭fp + finally: + fp.close() + # 返回_mod + return _mod + # 定义_snowboydetect变量,调用swig_import_helper函数 + _snowboydetect = swig_import_helper() + # 删除swig_import_helper变量 + del swig_import_helper +# 如果版本信息小于(2, 6, 0),则导入_snowboydetect模块 +else: + import _snowboydetect +# 删除版本信息变量 +del version_info +# 尝试导入_swig_property变量 +try: + # 如果导入失败,则定义_swig_property变量 + _swig_property = property +except NameError: + pass # Python < 2.2 doesn't have 'property'. + + +def _swig_setattr_nondynamic(self, class_type, name, value, static=1): + # 如果name等于"thisown",则将self.this.own(value)赋值给name + if (name == "thisown"): + return self.this.own(value) + # 如果name等于"this",则将value的类型判断是否为SwigPyObject,如果是,则将self.__dict__[name]赋值给value,否则调用class_type.__swig_setmethods__.get(name, None)函数 + if (name == "this"): + if type(value).__name__ == 'SwigPyObject': + self.__dict__[name] = value + return + # 调用class_type.__swig_setmethods__.get(name, None)函数 + method = class_type.__swig_setmethods__.get(name, None) + # 如果method不为空,则调用method(self, value)函数 + if method: + return method(self, value) + # 如果static为0,则调用object.__setattr__(self, name, value)函数 + if (not static): + if _newclass: + object.__setattr__(self, name, value) + else: + self.__dict__[name] = value + # 否则,抛出AttributeError异常 + else: + raise AttributeError("You cannot add attributes to %s" % self) + + +# 定义_swig_setattr函数,将类、名称和值作为参数 +def _swig_setattr(self, class_type, name, value): + # 返回_swig_setattr_nondynamic函数,将类、名称和值作为参数 + return _swig_setattr_nondynamic(self, class_type, name, value, 0) + + +# 定义_swig_getattr_nondynamic函数,将类、名称和静态作为参数 +def _swig_getattr_nondynamic(self, class_type, name, static=1): + # 如果名称是"thisown",则返回self.this.own() + if (name == "thisown"): + return self.this.own() + # 获取类中是否有该名称的方法 + method = class_type.__swig_getmethods__.get(name, None) + # 如果存在该方法,则返回该方法(self) + if method: + return method(self) + # 如果不是静态的 + if (not static): + # 则返回object.__getattr__(self, name) + return object.__getattr__(self, name) + # 否则抛出AttributeError异常 + else: + raise AttributeError(name) + + +# 定义_swig_getattr函数,将类和名称作为参数 +def _swig_getattr(self, class_type, name): + # 返回_swig_getattr_nondynamic函数,将类、名称和静态作为参数 + return _swig_getattr_nondynamic(self, class_type, name, 0) + + +# 定义_swig_repr函数,将self作为参数 +def _swig_repr(self): + # 尝试将self.__repr__()赋值给strthis + try: + strthis = "proxy of " + self.this.__repr__() + # 如果不存在,则strthis为空 + except: + strthis = "" + # 返回<%s.%s; %s > % % (self.__class__.__module__, self.__class__.__name__, strthis,) + return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,) + + +# 尝试获取object类 +try: + _object = object + # 如果存在,则_newclass为1 + _newclass = 1 +# 如果不存在,则_object为空,_newclass为0 +except AttributeError: + class _object: + pass + _newclass = 0 + + +class SnowboyDetect(_object): + __swig_setmethods__ = {} + def __setattr__(self, name, value): return _swig_setattr( + self, SnowboyDetect, name, value) + __swig_getmethods__ = {} + def __getattr__(self, name): return _swig_getattr( + self, SnowboyDetect, name) + __repr__ = _swig_repr + + def __init__(self, resource_filename, model_str): + this = _snowboydetect.new_SnowboyDetect(resource_filename, model_str) + try: + self.this.append(this) + except: + self.this = this + + def Reset(self): + return _snowboydetect.SnowboyDetect_Reset(self) + + def RunDetection(self, *args): + return _snowboydetect.SnowboyDetect_RunDetection(self, *args) + + def SetSensitivity(self, sensitivity_str): + return _snowboydetect.SnowboyDetect_SetSensitivity(self, sensitivity_str) + + def GetSensitivity(self): + return _snowboydetect.SnowboyDetect_GetSensitivity(self) + + def SetAudioGain(self, audio_gain): + return _snowboydetect.SnowboyDetect_SetAudioGain(self, audio_gain) + + def UpdateModel(self): + return _snowboydetect.SnowboyDetect_UpdateModel(self) + + def NumHotwords(self): + return _snowboydetect.SnowboyDetect_NumHotwords(self) + + def SampleRate(self): + return _snowboydetect.SnowboyDetect_SampleRate(self) + + def NumChannels(self): + return _snowboydetect.SnowboyDetect_NumChannels(self) + + def BitsPerSample(self): + return _snowboydetect.SnowboyDetect_BitsPerSample(self) + __swig_destroy__ = _snowboydetect.delete_SnowboyDetect + def __del__(self): return None + + +SnowboyDetect_swigregister = _snowboydetect.SnowboyDetect_swigregister +SnowboyDetect_swigregister(SnowboyDetect) + +# This file is compatible with both classic and new-style classes. diff --git a/src/voice_assistant/text/test_unit.py b/src/voice_assistant/text/test_unit.py new file mode 100644 index 0000000..70becc2 --- /dev/null +++ b/src/voice_assistant/text/test_unit.py @@ -0,0 +1,52 @@ +import unittest +from unittest.mock import MagicMock +from unittest.mock import patch + +class TestMyCode(unittest.TestCase): + + def setUp(self): + self.detector = MagicMock(spec=snowboydecoder.HotwordDetector) + self.pa = MagicMock(spec=PyAudio) + self.wf = MagicMock(spec=wave.open) + self.p = MagicMock() + self.stream = MagicMock() + self.data = MagicMock() + + @patch('snowboydecoder.HotwordDetector') + @patch('PyAudio.PyAudio') + @patch('wave.open') + def test_detected(self, mock_wave_open, mock_pyaudio, mock_hotword_detector): + mock_hotword_detector.return_value = self.detector + self.detector.start = MagicMock() + self.detector.terminate = MagicMock() + + with patch('builtins.print') as mock_print: + detected() + mock_print.assert_called_with('唤醒成功') + self.detector.start.assert_called_with(detected_callback=detected, interrupt_check=interrupt_callback, sleep_time=0.03) + self.detector.terminate.assert_called() + + @patch('PyAudio.PyAudio') + @patch('wave.open') + def test_my_record(self, mock_wave_open, mock_pyaudio): + self.pa.return_value = self.pa + self.pa.open = MagicMock(return_value=self.stream) + self.stream.read = MagicMock(return_value=self.data) + + my_record() + + self.pa.open.assert_called_with(format=paInt16, channels=channels, rate=framerate, input=True, frames_per_buffer=num_samples) + self.stream.read.assert_called_with(num_samples) + + @patch('requests.post') + def test_speech2text(self, mock_requests_post): + mock_response = MagicMock() + mock_response.json = MagicMock(return_value={'result': ['你好']}) + mock_requests_post.return_value = mock_response + + speech = MagicMock() + result = speech2text(speech, 'token') + self.assertEqual(result, '你好') + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/src/voice_assistant/xm.pmdl b/src/voice_assistant/xm.pmdl new file mode 100644 index 0000000..e753476 Binary files /dev/null and b/src/voice_assistant/xm.pmdl differ