【发布时间】:2017-02-05 01:38:21
【问题描述】:
我正在尝试让 Perl 程序处理 ffmpeg 编码的输出,但是我的测试程序似乎只以周期性块的形式接收 ffmpeg 的输出,因此我假设正在进行某种缓冲。如何让它实时处理?
我的测试程序(tr 命令在那里,因为我认为可能 ffmpeg 的回车导致 perl 看到一大长行或其他东西):
#!/usr/bin/perl
$i = "test.mkv"; # big file, long encode time
$o = "test.mp4";
open(F, "-|", "ffmpeg -y -i '$i' '$o' 2>&1 | tr '\r' '\n'")
or die "oh no";
while(<F>) {
print "A12345: $_"; # some random text so i know the output was processed in perl
}
当我用这个脚本替换 ffmpeg 命令时一切正常:
#!/bin/bash
echo "hello";
for i in `seq 1 10`; do
sleep 1;
echo "hello $i";
done
echo "bye";
当使用上面的脚本时,我每秒都会看到输出。使用ffmpeg,大约需要 5-10 秒左右才能输出,有时每个输出会输出 100 行。
我曾尝试在命令调用中在ffmpeg 之前使用程序unbuffer,但它似乎没有效果。是否可能是 2>&1 可能正在缓冲?
非常感谢任何帮助。
如果你不熟悉 ffmpeg 的输出,它会输出一堆文件信息和东西到STDOUT,然后在编码过程中输出类似
frame= 332 fps= 93 q=28.0 size= 528kB time=00:00:13.33 bitrate= 324.2kbits/s speed=3.75x
在STDERR(因此2>&1)上以回车而不是新行(因此tr)开头。
【问题讨论】:
-
试试
open(F,'-|:unix',"ffmpeg......") -
@SebastianKing:我对
ffmpeg很熟悉,但我没有在您的问题中看到任何可以告诉我为什么您需要实时查看输出的内容。该输出是供控制台使用的,如果您通过程序运行转换,那么您肯定只需要知道每个文件是否已成功转换? -
这是一个用于更新当前行的“技巧”。 // 如果他们不替换它们,他们就不能使用
<>。 (这很好;他们可以改用read。) // 这不是使用unbuffer的方式。 -
@SebastianKing:当然,但我的问题仍然存在,你为什么要查看“实时统计数据”?不是有人可以跳进去,修复源视频,让火车继续运行。这不就像看洗衣机旋转一样吗?
-
@Borodin 我的实时统计数据保持不变,我会以某种方式找到解决方案。
unbuffer不能通过管道传送到,正确的用法是unbuffer <bin> <args>。当我这样做时,我会得到一个实时输出,直到回车部分,在编码完成之前我没有输出。这就是我有tr的原因,但现在我们看到它似乎确实存在问题。