从 ffmpeg 获取实时输出以在进度条中使用(PyQt4,stdout)

Getting realtime output from ffmpeg to be used in progress bar (PyQt4, stdout)(从 ffmpeg 获取实时输出以在进度条中使用(PyQt4,stdout))
本文介绍了从 ffmpeg 获取实时输出以在进度条中使用(PyQt4,stdout)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经查看了许多问题,但仍然无法完全弄清楚这一点.我正在使用 PyQt,并希望运行 ffmpeg -i file.mp4 file.avi 并在流式传输时获取输出,以便创建进度条.

I've looked at a number of questions but still can't quite figure this out. I'm using PyQt, and am hoping to run ffmpeg -i file.mp4 file.avi and get the output as it streams so I can create a progress bar.

我查看了以下问题:ffmpeg可以显示进度条吗?从子进程实时捕获标准输出

我可以看到 rsync 命令的输出,使用以下代码:

I'm able to see the output of a rsync command, using this code:

import subprocess, time, os, sys

cmd = "rsync -vaz -P source/ dest/"
p, line = True, 'start'


p = subprocess.Popen(cmd,
                     shell=True,
                     bufsize=64,
                     stdin=subprocess.PIPE,
                     stderr=subprocess.PIPE,
                     stdout=subprocess.PIPE)

for line in p.stdout:
    print("OUTPUT>>> " + str(line.rstrip()))
    p.stdout.flush()

但是当我将命令更改为 ffmpeg -i file.mp4 file.avi 时,我没有收到任何输出.我猜这与标准输出/输出缓冲有关,但我不知道如何读取看起来像

But when I change the command to ffmpeg -i file.mp4 file.avi I receive no output. I'm guessing this has something to do with stdout / output buffering, but I'm stuck as to how to read the line that looks like

frame=   51 fps= 27 q=31.0 Lsize=     769kB time=2.04 bitrate=3092.8kbits/s

我可以用它来计算进度.

Which I could use to figure out progress.

有人可以告诉我一个例子,说明如何使用或不使用 PyQt(如果可能的话)将这些信息从 ffmpeg 获取到 python 中

Can someone show me an example of how to get this info from ffmpeg into python, with or without the use of PyQt (if possible)

我最终选择了 jlp 的解决方案,我的代码如下所示:

I ended up going with jlp's solution, my code looked like this:

#!/usr/bin/python
import pexpect

cmd = 'ffmpeg -i file.MTS file.avi'
thread = pexpect.spawn(cmd)
print "started %s" % cmd
cpl = thread.compile_pattern_list([
    pexpect.EOF,
    "frame= *d+",
    '(.+)'
])
while True:
    i = thread.expect_list(cpl, timeout=None)
    if i == 0: # EOF
        print "the sub process exited"
        break
    elif i == 1:
        frame_number = thread.match.group(0)
        print frame_number
        thread.close
    elif i == 2:
        #unknown_line = thread.match.group(0)
        #print unknown_line
        pass

给出这个输出:

started ffmpeg -i file.MTS file.avi
frame=   13
frame=   31
frame=   48
frame=   64
frame=   80
frame=   97
frame=  115
frame=  133
frame=  152
frame=  170
frame=  188
frame=  205
frame=  220
frame=  226
the sub process exited

完美!

推荐答案

我发现从子进程获取动态反馈/输出的唯一方法是使用 pexpect 之类的东西:

The only way I've found to get dynamic feedback/output from a child process is to use something like pexpect:

#! /usr/bin/python

import pexpect

cmd = "foo.sh"
thread = pexpect.spawn(cmd)
print "started %s" % cmd
cpl = thread.compile_pattern_list([pexpect.EOF,
                                   'waited (d+)'])
while True:
    i = thread.expect_list(cpl, timeout=None)
    if i == 0: # EOF
        print "the sub process exited"
        break
    elif i == 1:
        waited_time = thread.match.group(1)
        print "the sub process waited %d seconds" % int(waited_time)
thread.close()

被调用的子进程 foo.sh 只是等待 10 到 20 秒之间的随机时间,这是它的代码:

the called sub process foo.sh just waits a random amount of time between 10 and 20 seconds, here's the code for it:

#! /bin/sh

n=5
while [ $n -gt 0 ]; do
    ns=`date +%N`
    p=`expr $ns % 10 + 10`
    sleep $p
    echo waited $p
    n=`expr $n - 1`
done

您需要使用一些与您从 ffmpeg 获得的输出相匹配的正则表达式,并对其进行某种计算以显示进度条,但这至少可以让您获得 ffmpeg 的无缓冲输出.

You'll want to use some regular expression that matches the output you're getting from ffmpeg and does some kind of calculation on it to show the progress bar, but this will at least get you the unbuffered output from ffmpeg.

这篇关于从 ffmpeg 获取实时输出以在进度条中使用(PyQt4,stdout)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Leetcode 234: Palindrome LinkedList(Leetcode 234:回文链接列表)
How do I read an Excel file directly from Dropbox#39;s API using pandas.read_excel()?(如何使用PANDAS.READ_EXCEL()直接从Dropbox的API读取Excel文件?)
subprocess.Popen tries to write to nonexistent pipe(子进程。打开尝试写入不存在的管道)
I want to realize Popen-code from Windows to Linux:(我想实现从Windows到Linux的POpen-code:)
Reading stdout from a subprocess in real time(实时读取子进程中的标准输出)
How to call type safely on a random file in Python?(如何在Python中安全地调用随机文件上的类型?)