1 问题描述

使用PySide2写了一个GUI程序,调用ffmpeg命令行工具,做简单的批量视频处理(调整帧宽度、帧高度、视频变速、降低视频码率达到限制视频大小),使用了ffmpeg、 ffmpeg-python库;

挺简单的事儿,但遇到一个问题:

pyinstaller打包程序时:

  1. 不加 -w 或 --noconsole,有CMD丑黑框,程序可以正常运行,但是程序界面背后一个大大的CMD黑框真心难看。。。
  2. 加上 -w 或 --noconsole,没有CMD黑框,程序会直接无限等待,无法正常运行,猜测是调用 ffmpeg 时需要一个shell环境供PIPE的输入输出

2 解决方案

心急的直接看 2.2 隐藏CMD黑框。。。

2.1 CMD黑框依旧在,不显示verbose信息(治标不治本)

  1. 使用subprocess.call():

    调用CMD命令时,在 ffmpeg 后面的参数加上 -loglevel quiet,就只有黑框,不显示实时进度信息

  2. 使用ffmpeg、ffmpeg-python库

    ffmpeg.run(quiet=True),将quiet设置为 True,就只有黑框,不显示实时进度信息

2.2 隐藏CMD黑框(啊哈哈哈舒服了)

(我使用到了ffmpeg库的 probe(调用ffprobe.exe获取视频流信息)和run(调用ffmpeg.exe执行操作)方法)

  1. 找到ffmpeg库的 _probe.py_run.py 文件

    备份这两个文件,修改完、打包完程序后再恢复原样

    把这两文件复制到桌面修改好再放回去(这步坑了我一点时间,win10没用管理员权限打开文件,由于ffmpeg库安装在C盘的Program...路径下,在PyCharm中做出的修改一直没保存。。。)

  2. 修改 _probe.py

    源码: p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    Popen 参数添加 shell=True, stdin=subprocess.PIPE

    def 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'))
  3. 修改 _run.py

    源码: return subprocess.Popen(args, stdin=pipe_stdin, stdout=stdout_stream, stderr=stderr_stream)

    添加 shell=True, 修改 stdin=subprocess.PIPE 或者修改 pipe_stdin=True

    def 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
    )
  4. 将修改完的 _probe.py 和 _run.py 放回 ffmpeg库

  5. 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控制台解决方案的更多相关文章

  1. sbt打包Scala写的Spark程序,打包正常,提交运行时提示找不到对应的类

    sbt打包Scala写的Spark程序,打包正常,提交运行时提示找不到对应的类 详述 使用sbt对写的Spark程序打包,过程中没有问题 spark-submit提交jar包运行提示找不到对应的类 解 ...

  2. 使用pyinstaller打包使用cx_Oracle模块的程序出现The specified module could not be found的问题

    pyinstaller看起来并不会将动态链接库自动打包,所以我们需要告诉pyinstaller要打包哪些动态链接库,步骤如下(假设python文件名为 oracletest.py): 1. 使用pyi ...

  3. 使用pyinstaller打包使用scrapy模块的程序运行时出现No such file or directory的问题解决

    解决的方案是利用pyinstaller的hook特性,步骤如下: 1.在项目目录新建hooks目录,目录中新建hooks-scrapy.py 文件,文件内容如下: from PyInstaller.u ...

  4. 用java程序调用ffmpeg执行视频文件格式转换flv

    用java小例题说明更直观:(可以直接编译运行)环境我在windows平台下测试的...需要在e:/下有ffmpeg.exe;mencoder.exe;drv43260.dll;pncrt.dll共4 ...

  5. 设置 Qt GUI程序 printf输出到独立控制台

  6. 【Python开发】PyInstaller打包Python程序

    PyInstaller是一个能将Python程序转换成单个可执行文件的程序, 操作系统支持Windows, Linux, Mac OS X, Solaris和AIX.并且很多包都支持开箱即用,不依赖环 ...

  7. pyinstaller打包shotgun有关的程序

    By 鬼猫猫 http://www.cnblogs.com/muyr/ 背景 使用pyinstaller打包跟shotgun有关的程序后,在自己电脑上运行都OK,但是编译好的exe在其他人的电脑上运行 ...

  8. python应用(2):写个python程序给自己用

    用python写一个程序,然后在命令行上执行,看不到界面(UI),这种程序很常见了,叫命令行程序.然而很多人,特别是不懂程序的人,更需要看到的是一个有界面的,能通过鼠标操作的程序,毕竟已经迈进&quo ...

  9. 笔记: c开发gui程序 (WM_CREATE, WS_CLIPCHILDREN , SetWindowPos)

    过去两年,用c写的gui程序我一般使用的套路是: 在 winMain()中, 先创建一个主窗口, 紧接着就是在下面创建子窗口(子控件). 可能是因为写这方面的程序较少,所以也没遇到什么大问题,之前就是 ...

随机推荐

  1. Eclipse之Cannot open Eclipse Marketplace

    今天给eclipse安装插件的时候出现各种cannot connect to...的问题, 想打开eclipse marketplace来安装插件出现Cannot open Eclipse Marke ...

  2. ProtoBuf开发者指南

    目录 1   概览 1.1   什么是protocol buffer 1.2   他们如何工作 1.3   为什么不用XML? 1.4   听起来像是为我的解决方案,如何开始? 1.5   一点历史 ...

  3. 2017 青岛现场赛 Suffix

    Consider n given non-empty strings denoted by s1 , s2 , · · · , sn . Now for each of them, you need ...

  4. @Qualifier

    当一个接口,有多个实现类且均已注入到spring容器中了,使用时@AutoWired是byType的,而这些实现类类型都相同,此时就需要使用@Qualifier明确指定使用那个实现类.因此,@Qual ...

  5. java并发:join源码分析

    join join join是Thread方法,它的作用是A线程中子线程B在运行之后调用了B.join(),A线程会阻塞直至B线程执行结束 join源码(只有继承Thread类才能使用) 基于open ...

  6. css 盒子模型简介

    盒子模型 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <ti ...

  7. jQuery EasyUI window窗口实例

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>j ...

  8. 神机iPhone6停产,苹果产业链应该感谢它还是痛恨它?

    据国内媒体报道,一些苹果上游供应商已经接到通知,iPhone6系列将会在5月底彻底停产,一时间,竟在网络上引发汹涌的怀念之情.iPhone6的特别之处在于它是苹果第一款大屏幕的智能手机,标志着库克彻底 ...

  9. Springboot项目的接口防刷(实例)

    技术要点:springboot的基本知识,redis基本操作, 首先是写一个注解类: import java.lang.annotation.Retention; import java.lang.a ...

  10. Unity3D渲染优化技巧

    优化图形性能 良好的性能对大部分游戏的成功具有决定作用.下面是一些简单的指导,用来最大限度地提高游戏的图形渲染. 图形需要哪些开销 游戏的图形部分主要开销来自电脑的两个系统: GPU 或 CPU.优化 ...