pyinstaller打包PySide2写的GUI程序,调用ffmpeg隐藏CMD控制台解决方案
1 问题描述
使用PySide2写了一个GUI程序,调用ffmpeg命令行工具,做简单的批量视频处理(调整帧宽度、帧高度、视频变速、降低视频码率达到限制视频大小),使用了ffmpeg、 ffmpeg-python库;
挺简单的事儿,但遇到一个问题:
pyinstaller打包程序时:
- 不加 -w 或 --noconsole,有CMD丑黑框,程序可以正常运行,但是程序界面背后一个大大的CMD黑框真心难看。。。
- 加上 -w 或 --noconsole,没有CMD黑框,程序会直接无限等待,无法正常运行,猜测是调用 ffmpeg 时需要一个shell环境供PIPE的输入输出
2 解决方案
心急的直接看 2.2 隐藏CMD黑框。。。
2.1 CMD黑框依旧在,不显示verbose信息(治标不治本)
使用subprocess.call():
调用CMD命令时,在 ffmpeg 后面的参数加上 -loglevel quiet,就只有黑框,不显示实时进度信息
使用ffmpeg、ffmpeg-python库
ffmpeg.run(quiet=True),将quiet设置为 True,就只有黑框,不显示实时进度信息
2.2 隐藏CMD黑框(啊哈哈哈舒服了)
(我使用到了ffmpeg库的 probe(调用ffprobe.exe获取视频流信息)和run(调用ffmpeg.exe执行操作)方法)
找到ffmpeg库的 _probe.py 和 _run.py 文件
备份这两个文件,修改完、打包完程序后再恢复原样
把这两文件复制到桌面修改好再放回去(这步坑了我一点时间,win10没用管理员权限打开文件,由于ffmpeg库安装在C盘的Program...路径下,在PyCharm中做出的修改一直没保存。。。)
修改 _probe.py
源码: p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Popen 参数添加 shell=True, stdin=subprocess.PIPEdef probe(filename, cmd='ffprobe', **kwargs):
"""Run ffprobe on the specified file and return a JSON representation of the output. Raises:
:class:`ffmpeg.Error`: if ffprobe returns a non-zero exit code,
an :class:`Error` is returned with a generic error message.
The stderr output can be retrieved by accessing the
``stderr`` property of the exception.
"""
args = [cmd, '-show_format', '-show_streams', '-of', 'json']
args += convert_kwargs_to_cmd_line_args(kwargs)
args += [filename] # 源码: p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# Popen 参数添加 shell=True, stdin=subprocess.PIPE, p = subprocess.Popen(args, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
if p.returncode != 0:
raise Error('ffprobe', out, err)
p.wait()
return json.loads(out.decode('utf-8'))
修改 _run.py
源码: return subprocess.Popen(args, stdin=pipe_stdin, stdout=stdout_stream, stderr=stderr_stream)
添加 shell=True, 修改 stdin=subprocess.PIPE 或者修改 pipe_stdin=Truedef run_async(
stream_spec,
cmd='ffmpeg',
pipe_stdin=False,
pipe_stdout=False,
pipe_stderr=False,
quiet=False,
overwrite_output=False,
):
args = compile(stream_spec, cmd, overwrite_output=overwrite_output)
stdin_stream = subprocess.PIPE if pipe_stdin else None
stdout_stream = subprocess.PIPE if pipe_stdout or quiet else None
stderr_stream = subprocess.PIPE if pipe_stderr or quiet else None # 源码: return subprocess.Popen(
# args, stdin=pipe_stdin, stdout=stdout_stream, stderr=stderr_stream)
# 添加 shell=True, 修改 stdin=subprocess.PIPE或者修改 pipe_stdin=True return subprocess.Popen(
args, shell=True, stdin=subprocess.PIPE, stdout=stdout_stream, stderr=stderr_stream
)
将修改完的 _probe.py 和 _run.py 放回 ffmpeg库
pyinstaller 打包程序时,添加 -w 或 --noconsole参数,这时CMD黑框就不显示了
黑框没有了,一切都舒服了
附1:不用ffmpeg库,而是直接使用 subprocess调用ffmpeg.exe的,只需要在调用subprocess.Popen()时指定参数 shell=True, stdin=subprocess.PIPE 即可
附2:打包完程序,把备份的 _probe.py 和 _run.py 恢复到ffmpeg库里,不知道这么写有啥不好的影响,还是恢复原样吧
参考1:https://blog.csdn.net/polyhedronx/article/details/82432148 ------ subprocess.Popen设置shell=True,stdin=subprocess.PIPE
参考2:https://my.oschina.net/u/2396236/blog/1610765 ------ subprocess.Popen设置shell=True,stdin=subprocess.PIPE
参考3:https://blog.csdn.net/iserfj/article/details/94487538 ------ creationflags=0x08000000 或者 creationflags=subprocess.CREAT_NO_WINDOW(这个方法我尝试无效)
pyinstaller打包PySide2写的GUI程序,调用ffmpeg隐藏CMD控制台解决方案的更多相关文章
- sbt打包Scala写的Spark程序,打包正常,提交运行时提示找不到对应的类
sbt打包Scala写的Spark程序,打包正常,提交运行时提示找不到对应的类 详述 使用sbt对写的Spark程序打包,过程中没有问题 spark-submit提交jar包运行提示找不到对应的类 解 ...
- 使用pyinstaller打包使用cx_Oracle模块的程序出现The specified module could not be found的问题
pyinstaller看起来并不会将动态链接库自动打包,所以我们需要告诉pyinstaller要打包哪些动态链接库,步骤如下(假设python文件名为 oracletest.py): 1. 使用pyi ...
- 使用pyinstaller打包使用scrapy模块的程序运行时出现No such file or directory的问题解决
解决的方案是利用pyinstaller的hook特性,步骤如下: 1.在项目目录新建hooks目录,目录中新建hooks-scrapy.py 文件,文件内容如下: from PyInstaller.u ...
- 用java程序调用ffmpeg执行视频文件格式转换flv
用java小例题说明更直观:(可以直接编译运行)环境我在windows平台下测试的...需要在e:/下有ffmpeg.exe;mencoder.exe;drv43260.dll;pncrt.dll共4 ...
- 设置 Qt GUI程序 printf输出到独立控制台
- 【Python开发】PyInstaller打包Python程序
PyInstaller是一个能将Python程序转换成单个可执行文件的程序, 操作系统支持Windows, Linux, Mac OS X, Solaris和AIX.并且很多包都支持开箱即用,不依赖环 ...
- pyinstaller打包shotgun有关的程序
By 鬼猫猫 http://www.cnblogs.com/muyr/ 背景 使用pyinstaller打包跟shotgun有关的程序后,在自己电脑上运行都OK,但是编译好的exe在其他人的电脑上运行 ...
- python应用(2):写个python程序给自己用
用python写一个程序,然后在命令行上执行,看不到界面(UI),这种程序很常见了,叫命令行程序.然而很多人,特别是不懂程序的人,更需要看到的是一个有界面的,能通过鼠标操作的程序,毕竟已经迈进&quo ...
- 笔记: c开发gui程序 (WM_CREATE, WS_CLIPCHILDREN , SetWindowPos)
过去两年,用c写的gui程序我一般使用的套路是: 在 winMain()中, 先创建一个主窗口, 紧接着就是在下面创建子窗口(子控件). 可能是因为写这方面的程序较少,所以也没遇到什么大问题,之前就是 ...
随机推荐
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 表格:表示一个警告的操作
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- myBatis 操作 mysql时,使用 like 关键进行模糊查询的方法
参考:https://blog.csdn.net/rainbow702/article/details/50519424 like CONCAT('%', #{mkName}, '%')
- 二、java基础-运算符_控制语句_break_continue_return
1.运算符 1)算术运算符:6个+ — * \ % ++ --2)关系运算符:6个> >= < <= == !=3)布尔运算符&&并且 ||或 ...
- http请求常见的状态码
状态码是开发者需要了解的一项内容,日常开发中浏览器会返回给我们一些状态码,然后我们可以根据状态码所代表的含义进行问题解决. 1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态代码. 100 ...
- 「Luogu P2253 好一个一中腰鼓!」
就这道题的理论难度来说绿题是有点低了,但是这道题的实际难度来看,顶多黄题,所以建议加强数据或出数据升级版. 前置芝士 线段树:具体可以看我的另一篇文章. 具体做法 暴力的方法想必都会,所以来讲一下正解 ...
- Memcache和Redis的详细理解与区别
1. Memcache Memcache是一个高性能,分布式内存对象缓存系统,通过在内存中缓存一个巨大的hash表,他能够存储包括图像,文件,索引,sql语句结果等数据,可以理解为它理解为一个为提升读 ...
- 【Python数组及其基础操作】【numpy ndarray】
一.创建数组 在python中创建数组最简单的办法就是使用array函数.它接受一切序列型的对象,然后产生一个含有传入数据的numpy数组.其中,嵌套序列(比如由一组等长列表组成的列表)会被转换为一个 ...
- require - 引入文件
导入 /** * Creates the node for the load command. Only used in browser envs. */ req.createNode = funct ...
- java 获取当前时间,前一天时间
java获取当前时间,并按一定格式输出 1.用Calendar获取Date Calendar calendar=Calendar.getInstance(); SimpleDateFormat for ...
- 1-7SpringBoot之表单验证@Valid
SpringBoot提供了强大的表单验证功能实现,给我们省去了写验证的麻烦: 这里我们给下实例,提交一个有姓名和年龄的表单添加功能, 要求姓名不能为空,年龄必须是不小于18 : 我们先新建一个Stud ...