在 python 窗口(Tkinter)应用程序中抑制子进程控制台输出

Eli*_*hen 3 python subprocess ffmpeg pyinstaller windows-console

我正在尝试在使用的 python 应用程序可执行文件中运行以下代码

pyinstaller -w -F 脚本.py

def ffmpeg_command(sec):
    cmd1 = ['ffmpeg', '-f','gdigrab','-framerate',config.get('FFMPEG_Settings','Framerate'),'-i','desktop',gen_filename_from_timestamp_and_extension()]


    proc = subprocess.Popen(cmd1,stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

    duration = sec
    sleeptime = 0
    while proc.poll() is None and sleeptime < duration: 
        # Wait for the specific duration or for the process to finish
        time.sleep(1)
        sleeptime += 1

    proc.terminate()
Run Code Online (Sandbox Code Playgroud)

当按下 Tkinter 按钮时运行上面的代码,并且从按钮单击处理程序调用此代码。

我的问题是,当我运行 exe 时,它​​不会运行 ffmpeg。但是,如果我将命令设置为:

proc = subprocess.Popen(cmd1)
Run Code Online (Sandbox Code Playgroud)

FFMPEG 确实运行了,我得到了我想要的电影文件,但我可以看到 FFMPEG 的控制台窗口。所以我最终在我的电影中获得了控制台窗口。(我负责最小化按钮单击处理程序中的 Tkinter 窗口)

我的问题是如何抑制控制台窗口并仍然让 FFMPEG 以我想要的方式运行?我看着下面的线程,但不能使它工作: 如何子的隐藏输出在Python 2.7打开一个程序与Python最小化或隐藏

谢谢

Eli*_*hen 6

谢谢@Stack 和@eryksun!我改为以下代码:

startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
startupinfo.wShowWindow = subprocess.SW_HIDE
cmd1 = ['ffmpeg', '-f','gdigrab','-framerate',config.get('FFMPEG_Settings','Framerate'),'-i','desktop',gen_filename_from_timestamp_and_extension()]  
proc = subprocess.Popen(cmd1,stdin=subprocess.DEVNULL,stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,startupinfo=startupinfo)
Run Code Online (Sandbox Code Playgroud)

达到了我想要的。事实上,正如@eryksun 所建议的那样,仅重定向输出并没有做到这一点,我也不得不使用stdin=subprocess.DEVNULL它来抑制所有输出。

这仍然使控制台窗口可见,但通过startupinfo如上所述设置,控制台窗口被隐藏。还验证了 FFMPEG 在时间到期时消失。

感谢您的帮助!

  • 你说你保留了 `shell=True`,但你没有在上面的代码中使用它,这是最好的,因为这个命令不需要 shell。我仍然建议通过 `DETACHED_PROCESS` 创建标志告诉 Windows 根本不要创建控制台。 (2认同)