3

I am attempting to run the following code in a python app executable made using

pyinstaller -w -F script.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()

The above code is run when a Tkinter button is pressed and this code is called from the button click handler.

My problem is that when I am running the exe this doesn't run ffmpeg. However, If I set the command to be:

proc = subprocess.Popen(cmd1)

FFMPEG does run, I get the movie file I wanted but I can see the console window for FFMPEG. So I end up getting the console window in my movie. (I take care of minimizing the Tkinter window in the button click handler)

My question is how do I suppress the console window and still have FFMPEG run the way I want it to? I looked at the following threads but couldn't make it work: How to hide output of subprocess in Python 2.7, Open a program with python minimized or hidden

Thank you

Eliad Cohen
  • 111
  • 10
  • try adding parameter **shell=True** to proc = subprocess.Popen(cmd1,stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) – Stack Jun 15 '17 at 16:18
  • @Stack - Thank you for commenting. I tried modifying it to : `proc = subprocess.Popen(cmd1,shell=True,stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) ` But I'm still getting the same results :( – Eliad Cohen Jun 15 '17 at 16:23
  • 1
    If you're using Windows 7 or older, you may have a bad stdin handle. Replace it via `stdin=subprocess.DEVNULL`. However, setting the handles to the `NUL` device won't prevent the allocation of a console or hide it. `shell=True` will hide it via the `STARTUPINFO`, but it's best to avoid the shell if possible and simpler to not attach to a console at all. Define `DETACHED_PROCESS = 8` and use `creationflags=DETACHED_PROCESS`. – Eryk Sun Jun 15 '17 at 17:35
  • @eryksun - Changing to `proc = subprocess.Popen(cmd1,shell=True,stdin=subprocess.DEVNULL,stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)` Makes it run like I want but now I can't terminate FFMPEG, it just keeps on screen-capturing. However `proc = subprocess.Popen(cmd1,stdin=subprocess.DEVNULL,stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)` supresses the output but shows the console window. Could you please give more details on hiding the console window with `STARTUPINFO` ? – Eliad Cohen Jun 15 '17 at 17:49
  • @eryksun I did further digging from your comment and STARTUPINFO indeed solved it for me. Thank you! Editing with solution – Eliad Cohen Jun 15 '17 at 18:03
  • 1
    How were you terminating it before, by closing the console window? If you want to terminate the process, use `proc = subprocess.Popen(cmd1,shell=True,stdin=subprocess.DEVNULL,st‌​dout=subprocess.DEVN‌​ULL, stderr=subprocess.DEVNULL, creationflags=DETACHED_PROCESS)`. Then to kill it call `proc.terminate()`. – Eryk Sun Jun 15 '17 at 18:04
  • @eryksun I used `proc.terminate()' after counting down... – Eliad Cohen Jun 15 '17 at 18:10

1 Answers1

6

Thank you @Stack and @eryksun! I changed to the following code:

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)

Achieved what I wanted. Indeed, as @eryksun suggested, only redirecting the output didn't do it and I had to use stdin=subprocess.DEVNULL as well to suppress all output.

That still left the console window visible but by setting the startupinfo as mentioned above, the console window was hidden. Also verified that FFMPEG goes away when the time expires.

Thank you for your help!

Eliad Cohen
  • 111
  • 10
  • 2
    You say that you kept `shell=True`, but you're not using it in the above code, which is for the best since this command doesn't require the shell. I still recommend telling Windows to not create a console at all via the `DETACHED_PROCESS` creation flag. – Eryk Sun Jun 15 '17 at 18:17