When I run “ffmpeg” in the background, how do I prevent “suspended (tty output)”?
Posted by Jim DeLaHunt on 04 Nov 2017 at 12:50 pm | Tagged as: robobait, software engineering
I recently had a problem, “When I run ffmpeg in the background, how do I prevent suspended (tty output)?”. I solved it. Here is my solution, in the hopes that it will help others seeing the same problem.
I have a sh script which calls ffmpeg on several files. When I try to run this script in the background, redirecting output to a file, the job starts but then immediately suspends:
% bin/mp3convert.sh path/a/b &> ~/tmp/log.txt & [1] 93352 % [1]Â + suspended (tty output)Â bin/mp3convert.sh path/a/b &>
If I try making the script continue in the background, it immediately suspends again:
% jobs[1] + suspended (tty output) bin/mp3convert.sh path/a/b &> % bg %1 [1] + continued bin/mp3convert.sh path/a/b &> % jobs [1] + suspended (tty output) bin/mp3convert.sh path/a/b &> %
I can make the script continue, by making it the foreground, but then my terminal is occupied until the script finishes. That means I don’t get the benefit of running the script in the background.
% [1] + suspended (tty output) bin/mp3convert.sh path/a/b &> % fg %1 [1] + continued bin/mp3convert.sh path/a/b &> % # much time passes with no activity on terminal, then script finishes %
How can I make the script run cleanly in the background?
A simplified version of my script is:
#!/bin/sh# mp3convert.shfor f in "$1"/*.flac; do  ffmpeg -i "$f" -c:v copy path/to/dest/"$(basename -s .flac "$f")".mp3 done
I am running on Mac OS X 10.11.6, with ffmpeg version 3.4Â supplied by MacPorts.
An apparently related question is StackOverflow’s why do I get “Suspended (tty output)†in one terminal but not in others?. The answer there is to set the terminal state with stty -tostop. That didn’t help me; I already had that state set.
Here is the answer I discovered:
ffmpeg enables interaction with stdin by default. (See the documentation on its -stdin option.) On Mac OS X and Linux systems, this causes an ffmpeg job running in the background to suspend, though oddly with a message about “tty output” rather than “tty input”.
Adding option -nostdin to the invocation causes ffmpeg to not enable stdin interaction, and so avoids suspending the background process.
So, when I changed my invocation from:
ffmpeg -i "$f" -c:v copy path/to/dest/"$(basename -s .flac "$f")".mp3
to:
ffmpeg -nostdin -i "$f" -c:v copy path/to/dest/"$(basename -s .flac "$f")".mp3
then the script ran without suspending.
You can get a similar effect by redirecting input to /dev/null. This can be done at the ffmpeg call, or at the invocation to the shell script where you send the run to the background. The nice thing about this is that you can work around ffmpeg’s need for stdin without having to modify the script which invokes ffmpeg. The drawback of this is that it works differently on Windows than on Linux and Mac OS X.
You would change the script invocation from:
% bin/mp3convert.sh path/a/b &> ~/tmp/log.txt &
to:
% bin/mp3convert.sh path/a/b < /dev/null &> ~/tmp/log.txt &
Note: I also posted this question and its answer at StackOverflow: When I run `ffmpeg` in the background, how do I prevent `suspended (tty output)`? Helpful information may get posted there. And, that question might migrate to SuperUser, or another more-appropriate site.
Editorial comment: it seems unhelpful that ffmpeg enables interaction with stdin by default. From my point of view, it would be better if it enabled stdin only if needed interaction. I haven’t been able to find a page on the ffmpeg site which explains this design decision. If you know of one, please tell me in the comments below.
In this October 2010 post to the ffmpeg-user email list, ffmpeg from a backgrounded bash script, Charles Fleche asks a better-phrased version of the same question I have, about the wisdom of ffmpeg requiring access to stdin. Unfortunately, no-one gave him a substantive answer.
I was able to contribute two FAQs to the FFmpeg documentation on this subject:
How do I run ffmpeg as a background task?
How do I prevent ffmpeg from suspending with a message like suspended (tty output)?
Hopefully this will help other FFmpeg users with the same question get answers even more quickly.
A data point: it took 14 days from when I started to download the FFmpeg source code and learn their contribution process, to when the extra documentation was accepted into their project and posted on the web site. Not quite as low-friction as, say, Wikipedia.
Dear JIM,
I would like your help to solve the following problem in my code:
I have a C++ program with multhreading architecture, on each thread represent a IP Security CAM where I streamig a video.
Inside of each Thread I execut the ffmpeg script, using C++ system(script.sh), to record video very tree minutes.
The process is OK in the first time and this is a output:
First Ciclo for all Thread:
Video 1: 3 minutes
Video 2: 3 minutes
Video 3: 3 minutes
Second Ciclo for all Thread:
But during a time running the program I get this output files:
Video 1: 3 minutes
Video 2: 2,5 minutes
Video 3: 1,5 minutes
Where we can see that the time is not the same for all cameras.
In same point one or two ffmpeg process dont finish correctly.
The error in output for ffmpeg say that is a DTS and PTS problem.
But I cannot found a solution.
Hello, Nuno,
I’m sorry to tell you that I am not able to provide support for use of ffmpeg. I just wrote this blog post to report what I learned about one aspect of ffmpeg. And, I do not know what a “DTS and PTS problem” might be.
I suggest that you subscribe to the ffmpeg-user@ffmpeg.org email list, and ask your question there.
They will ask you to run the ffmpeg command on its own in a shell, and to include the full output from the command. Include the messages which indicate that it is a “DTS and PTS problem”.
Good luck!