0

I am trying to redirect both the stderr and stdout of a ffmpeg command to a file and to suppress them when executing the Python script. This is my code:

import subprocess, shlex

cmd = 'ffmpeg -hide_banner -i input.mp4 -c:v libx264 -b:v 2M -c:a copy enc_out.mp4'

with open("ffmpeg_out.txt", 'w') as log:
    ffmpeg_cmd = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE)
    ffmpeg_stdout = ffmpeg_cmd.communicate()
    for i in range(len(ffmpeg_stdout) - 1):
        log.write(str(ffmpeg_stdout[i]) + "\n")

So in general I want to do something similar to ffmpeg -hide_banner -i input.mp4 -c:v libx264 -b:v 2M -c:a copy enc_out.mp4 &> ffmpeg_out.txt. So currently in the ffmpeg_stdout I have only (b'', None) and the stdout and stderr are both printed when executing the script.

Georgi Stoyanov
  • 594
  • 1
  • 9
  • 26

2 Answers2

4

oguzismail's answer is probably superior in this particular case, but just for the record, it's not hard at all.

with open("ffmpeg_out.txt", 'w') as log:
    ffmpeg_cmd = subprocess.run(shlex.split(cmd), 
        stdout=log, stderr=log)

Notice also the preference for subprocess.run() over raw Popen. (Probably add check=True as well.)

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • More tangentially, `shlex.split()` doesn't do anything you can't do yourself here. Just replace the spaces with `', '` and make the command a list. – tripleee Nov 09 '18 at 11:11
  • @tripleee actually the command I want to execute is way longer, so this is saving me some time and also in the past I was constantly missing to put the `,` so the script was crashing and I needed to look where I have missed to put one... – Georgi Stoyanov Nov 09 '18 at 12:08
1

ffmpeg can redirect stderr to a file on its own, and since it doesn't print anything necessary to stdout in most cases, this would be a useful workaround

my_env = os.environ.copy()
my_env["FFREPORT"] = "file=ffmpeg_out.txt:level=32"
subprocess.Popen(shlex.split(cmd), env=my_env)
oguz ismail
  • 1
  • 16
  • 47
  • 69