If I run ffmpeg as follows:
ffmpeg -i H264-media-4.264 4.avi
It works OK (i.e. 4.avi created OK). However, if I try to run it in background
It hangs because after a certain point it can not write to it's output pipe any longer.
When you run a process it has 3 opened pipes for: stdin, stdout and stderr. A pipe has a memory buffer ( 4KB on Linux ) that can hold up to a certain amount of data and the next write operation will pause until some data is read from the other side of the pipe.
Since you never read from stdout and stderr of your child process and FFMpeg outputs quite a lot it will hang at some point.
As explained in the comment above you can simply redirect your ffmpeg output to /dev/null using:
ffmpeg .... > /dev/null 2>&1 < /dev/null
In this case ffmpeg will never output enough data to have the pipe 'hang'.
Another option would be to just close stdin, stdout and stderr of your child process as soon as you launch it.
And yet another option would be to actually read ( and optionally discard ) everything on stdout and stderr of your child process.
As others have pointed out, the issue is caused by ffmpeg saturating stdout and/or stderr with verbose messages. So another option could be to turn down the log level for ffmpeg:
ffmpeg -loglevel error -i H264-media-4.264 4.avi &
See this question for more information on log levels in ffmpeg.
ffmpeg
enables interaction with stdin by default. On Mac OS X and Linux systems, this causes an ffmpeg
job running in the background to suspend. Adding option -nostdin
to the invocation causes ffmpeg
to not enable stdin interaction, and so avoids suspending the background process.
In your example, try:
ffmpeg -nostdin -i H264-media-4.264 4.avi &
Note: the ffmpeg documentation, 5.4 Main options says that the input redirection mentioned in the other answers:
ffmpeg ... < /dev/null
achieves "roughly the same result" as the use of -nostdin
, but requires a shell.
When might you want to run ffmpeg
with no shell? When invoking it as a subprocess, for example with Python's subprocess.run()
.