Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python subprocesses (ffmpeg) only start once I Ctrl-C the program?

I'm trying to run a few ffmpeg commands in parallel, using Cygwin and Python 2.7.

This is roughly what I have:

import subprocess
processes = set()

commands = ["ffmpeg -i input.mp4 output.avi", "ffmpeg -i input2.mp4 output2.avi"] 

for cmd in commands:
  processes.add(
    subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
  )

for process in processes:
  if process.poll() is None:
    process.wait()

Now, once I am at the end of this code, the whole program waits. All the ffmpeg processes are created, but they're idle, i.e., using 0% CPU. And the Python program just keeps waiting. Only when I hit Ctrl-C, it suddenly starts encoding.

What am I doing wrong? Do I have to "send" something to the processes to start them?

like image 948
slhck Avatar asked Jul 26 '26 09:07

slhck


2 Answers

This is only a guess, but ffmpeg usually produces a lot of status messages and output on stderr or stdout. You're using subprocess.PIPE to redirect stdout and stderr to a pipe, but you never read from those, so if the pipe buffer is full, the ffmpeg process will block when trying to write data to it.

When you kill the parent process the pipe is closed on its end, and probably (i haven't checked) ffmpeg handles the error by just not writing to the pipe anymore and is therefore unblocked and starts working.

So eiter consume the process.stdout and process.stderr pipes in your parent process, or redirect the output to os.devnull if you don't care about it.

like image 112
mata Avatar answered Jul 27 '26 23:07

mata


In addition to what @mata says, ffmpeg may also be asking you if you want to overwrite output.avi and waiting on you to type "y". To force-overwrite, use the "-y" command-line option (ffmpeg -i $input -y $output).

like image 43
Ronald S. Bultje Avatar answered Jul 27 '26 21:07

Ronald S. Bultje