Pyinstaller打包后Python subprocess调用ffmpeg失效问题求助
问题解决步骤
1. 核心问题分析
打包后调用ffmpeg失败的主要原因有三个:
- macOS下
--windowed模式打包的应用不继承终端的环境变量,系统PATH里的ffmpeg无法被找到 - 直接用
subprocess.Popen后未等待进程完成就弹出成功提示,实际转换可能还没启动就被中断 - 原命令写法未处理路径含空格的情况,且未捕获错误输出,无法排查问题
2. 代码修改方案
2.1 修复ffmpeg路径问题
将ffmpeg二进制文件和应用一起打包,代码中自动识别打包后的路径:
def convert(path_input, path_output): # 获取ffmpeg路径:打包后用sys._MEIPASS访问资源,本地开发用系统ffmpeg if getattr(sys, 'frozen', False): # 打包后的资源目录 ffmpeg_path = os.path.join(sys._MEIPASS, 'ffmpeg') else: # 本地开发时的ffmpeg路径(可替换为绝对路径) ffmpeg_path = 'ffmpeg' # 用列表传参,避免路径空格和shell注入问题 cmd = [ffmpeg_path, '-i', path_input, path_output] # 启动进程并等待完成,捕获输出 process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) stdout, stderr = process.communicate() # 返回执行结果和输出信息 return process.returncode, stdout, stderr
2.2 修复转换结果判断逻辑
在start函数中,根据ffmpeg的返回码判断是否转换成功,不再提前弹出成功提示:
def start(self): if hasattr(self, "file_path") and hasattr(self, "folder_path"): if not os.path.isfile(self.output_path): # 执行转换并获取结果 returncode, stdout, stderr = convert(self.file_path, self.output_path) if returncode == 0: # 转换成功提示 dlg = QDialog(self) dlg.setWindowTitle("DONE") dlg.setFixedSize(QSize(400, 100)) message = QLabel(dlg) message.setText("Conversion is successfully finished!") dlg.setStyleSheet( "QLabel{font-size: 20pt; margin-left: 50px; margin-top: 25px}") dlg.exec() else: # 转换失败,显示错误信息 dlg = QDialog(self) dlg.setWindowTitle("ERROR") dlg.setFixedSize(QSize(600, 200)) message = QLabel(dlg) # 截取部分错误信息显示,避免过长 error_msg = stderr[:300] if len(stderr) > 300 else stderr message.setText(f"Conversion failed!\nError: {error_msg}") message.setWordWrap(True) dlg.setStyleSheet( "QLabel{font-size: 14pt; margin: 20px}") dlg.exec() else: dlg = QDialog(self) dlg.setWindowTitle("ERROR") dlg.setFixedSize(QSize(400, 100)) message = QLabel(dlg) message.setText("Already a file exists!") dlg.setStyleSheet( "QLabel{font-size: 20pt; margin-left: 90px; margin-top: 25px}") dlg.exec() else: dlg = QDialog(self) dlg.setWindowTitle("ERROR") dlg.setFixedSize(QSize(400, 100)) message = QLabel(dlg) message.setText("No File or Folder Selected!") dlg.setStyleSheet( "QLabel{font-size: 20pt; margin-left: 90px; margin-top: 25px}") dlg.exec()
3. 打包命令修改
使用--add-binary参数将ffmpeg打包进应用,先通过which ffmpeg查看系统中ffmpeg的路径,然后执行:
pyinstaller --windowed --add-binary "/usr/local/bin/ffmpeg:." ffmpeg_gui.py
替换/usr/local/bin/ffmpeg为你实际的ffmpeg路径。
4. 额外注意事项
- 如果你的输入输出路径包含空格,列表传参的方式会自动处理,无需手动加引号
- 打包后如果还是找不到ffmpeg,可以检查打包后的应用包内容,确认ffmpeg是否在根目录下
- 开发时可以打印
ffmpeg_path确认路径是否正确
内容的提问来源于stack exchange,提问作者RRF
相关产品推荐
相关产品推荐

