6

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!

2
  • 1
    Have you tried check_output() from subprocess and subprocess.Popen().communicate()? Refer to this answer Commented Jul 20, 2020 at 8:39
  • According to the Python documentation I guess subprocess.run should be the prefered method. Anyway, I had always problems when using check_output() from subprocess Commented Jul 26, 2020 at 12:11

1 Answer 1

3

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)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.