Reputation: 612
I'm trying to capture the output of a command with the following code:
lines = subprocess.run(['ffmpeg', '-hide_banner', '-nostats', '-i', in_filename, '-vn', '-af', 'silencedetect=n={}:d={}'.format(silence_threshold, silence_duration), '-f', 'null', '-'], capture_output=True, text=True, shell=True, check=True, encoding='utf-8').stdout
print (lines)
But lines is an empty string and nothing is printed.
When capture_output=True
is removed, the correct output is showed (without printing it).
I tested many combinations, including removing all the subprocess.run
parameters and only include capture_output=True
with the same result.
I also tested with few argument for a minimal example: subprocess.run(['ffmpeg', '-version'], capture_output=True, text=True, shell=True, check=True, encoding='utf-8').stdout
Also tested stdout=subprocess.PIPE
and stderr=subprocess.PIPE
as subprocess.run
arguments instead of capture_output=True
I can't figure out what is happening. Thanks in advance!
Upvotes: 6
Views: 2111
Reputation: 598
By default ffmpeg
logs to stderr
. You use capture_output=True
, so run()
func will capture stdout
and stderr
values
Q-1) Lines is an empty string and nothing is printed.
A-1) This is normal because ffmpeg not log to stdout by default.
Q-2) When capture_output=True
is removed, the correct output is showed (without printing it).
A-2) This is what we expected, when you remove capture_output=True
then ffmpeg
logs to stderr
(to your terminal/console by default) and you will see ffmpeg output on the screen(stdin,stdout,and stderr
these are typically attached to the user's terminal). When you use capture_output=True
, ffmpeg's logs go to the kernel pipe
file-like object in the RAM (In Unix and Linux, no knowledge about windows). That's why you don't see any output in the terminal/console without print()
'ing the captured stdout
subprocess.run()
func will return CompletedProcess(process.args, retcode, stdout, stderr)
instance and you can get stdout
attribute's value but we don't need this, we need stderr
attribute's value because ffmpeg
logs to stderr
by default as i said above.
You need to modify it like ;
lines = subprocess.run(['ffmpeg', '-hide_banner', '-nostats', '-i', in_filename, '-vn', '-af', 'silencedetect=n={}:d={}'.format(silence_threshold, silence_duration), '-f', 'null', '-'], capture_output=True, text=True, shell=True, check=True, encoding='utf-8').stderr
print (lines)
Upvotes: 3