quiet mode for run_async method might cause ffmpeg process to stick.
See original GitHub issueWhat I experienced
Recently, I was using this module in my project for decoding video into pipe as well as encoding target frames into a result video. But I found that setting the parameter “quiet” of the encoder process to True (which set both stdout and stderr to PIPE) will cause the ffmpeg process to stick at some stage ( and in this case, I cannot write anything into its stdin). If I leave “quiet” to default or set both pipe_stdout and pipe_stderr to False, everything goes well.
What I tried
I tried to edit the run_async function, changing it from
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=stdin_stream, stdout=stdout_stream, stderr=stderr_stream)
to
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 else None
stderr_stream = subprocess.PIPE if pipe_stderr else None
if quiet:
stdout_stream = stderr_stream = subprocess.DEVNULL
return subprocess.Popen(
args, stdin=stdin_stream, stdout=stdout_stream, stderr=stderr_stream)
Then, using this modified version of ffmpeg-python in my project, it works without any problems.
After all, I don’t think this issue is solved, for it will stick again if setting either pipe_stdout or pipe_stderr (I confirmed).
My forked version works. Should I make a pull request? Or do it only when we find the real reason for this issue.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:7
- Comments:7 (1 by maintainers)
Top GitHub Comments
The issue seems to be that pipe buffers are finite in size, so they fill up and eventually block. One workaround when running asynchronously is to just read() from the output pipes periodically. E.g., if you have a loop where you’re feeding frames to stdin:
But this is a bit hacky and relies on ffmpeg not producing too much output to stderr in one frame. I’d like it if the
pipe_stdout
andpipe_stderr
arguments could take subprocess pipes directly. E.g.,run_async(pipe_stdout=subprocess.PIPE, pipe_stderr=subprocess.DEVNULL)
.No. It is still a forked ffmpeg-python repo. And since I have been away from such stuff for a long time, it is out of date with the repo now.