我正在 ffmpeg 上循环来转换一堆视频,我想强调 ffmpeg 输出中的一些术语。但我尝试的解决方案总是使转换的实时进度消失。
我尝试的主要是将stderr重定向到stdout,然后像这样grep或ack(为了可读性简化了ffmpeg的命令):
ffmpeg -i input.mp4 ouput.mkv 2>&1 | ack --passthru --color "pcm_s16le|aac"
或者
ffmpeg -i input.mp4 ouput.mkv 2>&1 | grep -E "pcm_s16le|aac|$"
(注意|$
允许匹配所有内容而无需着色的技巧,就像直通一样)
我所说的实时进度信息是指如下所示的行:
frame=190 fps=3.7 q=-0.0 size=308kB time=06:08.66 bitrate=677kbits/s speed=0.17x
那么,有没有办法突出显示一些输出的单词,和保持实时进度?
答案1
您看到的问题几乎肯定是由于进度信息是用 CR(回车,ASCII 13)行结尾打印的,而不是传统的 Unix LF(换行,ASCII 10)。这样做是为了允许每个新的进度更新都可以套印上一个进度。
不幸的是,这意味着整套进度更新将grep
和ack
所有其他面向行的工具视为一条线。这就是为什么它们似乎“锁定”并且在ffmpeg
完成之前不打印任何内容,而且我想不出除了标准 Unix 行基础之外的任何类似的突出显示工具。
你可以尝试类似的东西:
ffmpeg ... | tr \\015 \\012 | grep ...
它将所有 CR 转换为 LF。这让grep
等人将每个进度更新视为单独的一行,代价是看到每个更新都作为单独的行,填充您的终端:
frame= 85 fps=0.0 q=28.0 size= 0kB time=00:00:03.79 bitrate= 0.1kbits/s dup=1 drop=0 speed=7.55x
frame= 129 fps=129 q=28.0 size= 0kB time=00:00:05.65 bitrate= 0.1kbits/s dup=1 drop=0 speed=5.64x
frame= 172 fps=111 q=28.0 size= 256kB time=00:00:07.42 bitrate= 282.6kbits/s dup=1 drop=0 speed=4.81x
frame= 213 fps=104 q=28.0 size= 512kB time=00:00:09.17 bitrate= 457.3kbits/s dup=1 drop=0 speed=4.49x
frame= 254 fps= 99 q=28.0 size= 512kB time=00:00:10.85 bitrate= 386.3kbits/s dup=1 drop=0 speed=4.22x
frame= 295 fps= 96 q=28.0 size= 768kB time=00:00:12.56 bitrate= 500.7kbits/s dup=1 drop=0 speed=4.08x
frame= 333 fps= 93 q=28.0 size= 1024kB time=00:00:14.14 bitrate= 593.1kbits/s dup=1 drop=0 speed=3.94x
frame= 382 fps= 93 q=28.0 size= 1024kB time=00:00:16.19 bitrate= 518.1kbits/s dup=1 drop=0 speed=3.93x
frame= 428 fps= 93 q=28.0 size= 1280kB time=00:00:18.11 bitrate= 579.0kbits/s dup=1 drop=0 speed=3.92x
frame= 473 fps= 92 q=28.0 size= 1536kB time=00:00:20.00 bitrate= 628.9kbits/s dup=1 drop=0 speed=3.91x
frame= 519 fps= 92 q=28.0 size= 1536kB time=00:00:21.93 bitrate= 573.8kbits/s dup=1 drop=0 speed= 3.9x
frame= 567 fps= 92 q=28.0 size= 1792kB time=00:00:23.91 bitrate= 613.9kbits/s dup=1 drop=0 speed=3.89x
frame= 601 fps= 90 q=28.0 size= 2048kB time=00:00:25.32 bitrate= 662.6kbits/s dup=1 drop=0 speed= 3.8x
frame= 637 fps= 89 q=28.0 size= 2304kB time=00:00:26.83 bitrate= 703.3kbits/s dup=1 drop=0 speed=3.75x
frame= 684 fps= 89 q=28.0 size= 2304kB time=00:00:28.77 bitrate= 655.9kbits/s dup=1 drop=0 speed=3.74x
frame= 720 fps= 84 q=-1.0 size= 2924kB time=00:00:30.01 bitrate= 798.0kbits/s dup=1 drop=0 speed= 3.5x
...
您可能还想禁用此管道中组件之间的 stdio 缓冲,以获得最大响应能力:
stdbuf -o0 ffmpeg ... 2>&1 | stdbuf -i0 -o0 tr \\015 \\012 | stdbuf -i0 -o0 grep ...
答案2
阿德里安的回答非常有帮助,但我失去了对话,提示
File 'output.mkv' already exists. Overwrite ? [y/N]
有了这个工具
vialog
,即使用xterm
它的日志文件,我可以让它一直工作stdbuf -o0 vialog ffmpeg -t 10 -i input.mp4 output.mkv | stdbuf -i0 -o0 tr -s '\015' '\012' | stdbuf -i0 -o0 grep --color -e 'time' -e 'speed' -e 'Audio:' -e 'Video:' -e '$'
xterm
与窗口中的对话在终端窗口中突出显示,从哪里
vialog
开始(这使其成为 的控制台窗口xterm
),
vialog
您可以通过此链接找到该工具,您可能想要进行修改
vialog
以更准确地执行您想要的操作。