网页调用含PyAudio的语音转文字Python脚本加载无响应问题求助
看起来你遇到的问题是终端能正常运行的Python语音转文字脚本,通过PHP的shell_exec调用时页面无限加载,而简单的Python脚本可以正常执行。这大概率是几个常见原因导致的,下面分点给出解决方案:
1. 核心问题:Python脚本的无限循环导致PHP阻塞
你的Python脚本里,send_audio函数是一个无限while True循环,只有收到停止信号或异常才会退出。而PHP的shell_exec是同步等待脚本执行完成才会返回结果,这就导致PHP一直卡在等待脚本结束的状态,页面自然一直加载。
修复方法:让脚本在完成转录后自动退出
修改speech_to_text函数里的逻辑,当拿到Watson返回的最终转录结果时,主动发送停止信号并终止脚本:
if parsed["results"][0]["final"]: print(transcript, flush=True) # 加上flush确保输出及时 lst.append(transcript) lst.append("\n") # 发送停止信号并关闭连接 await conn.send(json.dumps({'action': 'stop'})) conn.close() break # 退出while循环,让脚本自然结束
同时,send_audio里的循环也会因为收到stop信号或连接关闭而退出,最终脚本会正常结束,PHP就能拿到输出。
2. Web服务器用户没有麦克风访问权限
终端运行脚本时用的是你当前的用户(有麦克风权限),但Web服务器(比如Apache/Nginx)是用系统服务用户(比如Windows的Network Service、Linux的www-data)运行的,这个用户可能没有访问麦克风的权限,导致脚本卡在获取音频的步骤。
修复方法:
- Windows系统:打开「设置」→「隐私和安全性」→「麦克风」,确保「允许桌面应用访问麦克风」已开启,并且找到Apache的
httpd.exe进程,允许它访问麦克风。 - Linux系统:将Web服务器用户添加到
audio组,获取音频设备权限:
之后重启Web服务器生效。sudo usermod -a -G audio www-data
3. Python环境与依赖不一致
Web服务器使用的Python环境可能和你终端的不一样,比如缺少pyaudio、websockets等依赖包,或者用了错误的Python版本(比如终端用Python3,服务器用Python2)。
修复方法:
指定完整的Python路径:在终端运行
which python3(Linux)或where python(Windows)找到你平时用的Python路径,替换PHP里的python命令:# Windows示例 print_r(shell_exec("C:\Python39\python.exe C:/xampp/htdocs/heyy/postibm.py 2>&1")); # Linux示例 print_r(shell_exec("/usr/bin/python3 /var/www/html/heyy/postibm.py 2>&1"));这里的
2>&1是把错误输出重定向到标准输出,方便你看到脚本的报错信息。检查依赖包:确保Web服务器的Python环境安装了所有需要的包。比如在Linux下,切换到Web服务器用户执行:
sudo -u www-data pip list如果缺少包,直接用该用户安装:
sudo -u www-data pip install pyaudio websockets python-dotenv
4. Python输出缓冲导致PHP无响应
Python在非终端环境下(比如Web服务器调用)会启用输出缓冲,脚本的输出不会即时返回给PHP,导致PHP一直等待输出。
修复方法:
- 在脚本开头添加强制关闭缓冲的代码:
import sys sys.stdout.flush() - 或者在所有
print语句后添加flush=True:print("* READY *", flush=True) print(transcript, flush=True)
5. 额外排查:添加日志记录
如果以上方法都没解决,可以给Python脚本添加日志,排查具体哪里卡住了:
import logging logging.basicConfig(filename='speech_to_text.log', level=logging.DEBUG, format='%(asctime)s %(message)s') # 在异常处理里记录日志 except Exception as e: logging.error(f"Error occurred: {str(e)}") print(e, flush=True) return False
运行PHP调用后,查看speech_to_text.log文件,就能看到脚本运行时的错误或卡住的位置。
内容的提问来源于stack exchange,提问作者ashu holmes

