Python speech recognition在PyInstaller打包无控制台窗口exe时失效问题
问题根因
- 标准流缺失报错:使用
--windowed参数打包无控制台程序时,Windows平台会默认将sys.stdout、sys.stderr置为None,你代码中的print(e)语句以及speech_recognition底层逻辑尝试向不存在的标准流写入内容时,会直接抛出未捕获异常,导致识别线程终止。 - 子进程启动失败:speech_recognition的
recognize_google方法会通过subprocess调用flac等工具做音频格式转换,无控制台模式下子进程默认继承父进程的无效控制台句柄,直接启动崩溃,识别流程中断。 - 依赖资源未打包:你用到的UI文件
A_to_T.ui、speech_recognition依赖的flac.exe工具没有被PyInstaller自动打包进exe,运行时找不到对应资源也会触发异常。
解决方案
1. 重定向标准输入输出流
在代码最开头(导入其他模块前)添加如下逻辑,将标准流重定向到空设备,避免写入时报错:
import sys import os # 判断是否为打包后运行状态 if getattr(sys, 'frozen', False): sys.stdout = open(os.devnull, 'w') sys.stderr = open(os.devnull, 'w')
2. 补丁修复subprocess调用
给subprocess.Popen打补丁,无控制台运行时自动添加子进程无窗口参数,指定输入输出流:
import subprocess original_popen = subprocess.Popen def patched_popen(*args, **kwargs): if sys.platform == 'win32' and getattr(sys, 'frozen', False): kwargs['creationflags'] = subprocess.CREATE_NO_WINDOW kwargs['stdin'] = subprocess.PIPE kwargs['stdout'] = subprocess.PIPE kwargs['stderr'] = subprocess.PIPE return original_popen(*args, **kwargs) subprocess.Popen = patched_popen
3. 修复代码现有语法错误
你贴出的代码存在两处语法问题需要先修正:
- ThreadClass的run方法缺少self参数,改为
def run(self): - ThreadClass实例化时传入了lang、path参数,需要在
__init__方法中添加对应参数接收逻辑
4. 调整打包命令
打包时添加缺失的资源文件,命令如下:
pyinstaller --noconfirm --onefile --windowed --add-binary "你的Python路径/Lib/site-packages/speech_recognition/flac.exe;." --add-data "A_to_T.ui;." Python_file.py
将命令中的你的Python路径替换为本地Python安装目录的实际路径即可。
内容的提问来源于stack exchange,提问作者Nms co
相关产品推荐
相关产品推荐

