subprocess.Popen()将标准输出写入日志文件

时间:2019-12-16 14:23:24

标签: python ffmpeg

我正在使用以下命令将ffmpeg的输出重定向到终端和文本文件。

p1 = subprocess.Popen (['ffmpeg', 'some_ffmpeg_command', '-f', 'mpegts', 'outfile.ts'], stdout=subprocess.PIPE, stderr=STDOUT, universal_newlines=True)
for line in p1.stdout:
    sys.stdout.write(line)
    logfile.write(line)
p1.stdout.close()
p1.wait()

在需要手动干预的情况下,代码可以正常工作。例如,如果文件outfile.ts已经存在,则控制台中不会显示以下对话框, File 'Desktop/mytestfolder/outfile.ts' already exists. Overwrite ? [y/N]

您知道以上内容有什么问题吗?

3 个答案:

答案 0 :(得分:0)

由于您不能依赖用户交互,因此您需要添加-y标志以强制执行“是”响应。

答案 1 :(得分:0)

问题在于此提示没有以\n结尾,因此python read line方法在获取整行之前会等待它。

解决方法是逐字符读取输入的字符。例如这样的

current_line = []
while True:
   c = p1.stdout.read(1).decode()
   if not c:
      break
   current_line.append(c)
   # here you can test if the last character is "]" to avoid creating a partial line everytime
   if c == ']':
      partial_line = ''.join(current_line)
      if partial_line.endswith("Overwrite ? [y/N]"):
         # do something, for instance, print it
         print("PROMPT: {}\n".format(partial_line))
   elif c == '\n':
      # full line: print it
      line = ''.join(current_line)
      # reset the current line buffer
      current_line = []
      # and write the line
      sys.stdout.write(line)
      logfile.write(line)

当然,如果不回答,该过程将被阻止。因此,Popen也需要stdin=subprocess.PIPE,因此您可以使用p1.stdin.write("Y\n")来回复提示(或"N\n"取决于问题)。

答案 2 :(得分:0)

您必须将y传递到STDIN。

使用Popen的解决方案:

from subprocess import Popen, PIPE

foo_proc = Popen(['foo', 'bar'], stdin=PIPE, stdout=PIPE)
yes_proc = Popen(['y'], stdout=foo_proc.stdin)
foo_output = foo_proc.communicate()[0]
yes_proc.wait()

用STDIN编写的解决方案:

foo_proc = Popen(['foo', 'bar'], stdin=PIPE, stdout=PIPE)
sp.stdin.write("y\n")  # "\n" is important!
foo_output = foo_proc.communicate()[0]
yes_proc.wait()