将ffmpeg输出到命名管道

时间:2015-06-18 18:21:37

标签: linux ffmpeg named-pipes

我正在尝试将ffmpegs输出到命名管道,我可以从另一个shell读取。我不需要传输视频流,只需要下面的信息就可以获得转换过程的状态。我无法以任何方式实现管道行为,但我可以使用以下命令将数据写入文件:

ffmpeg -i vid.mov -vcodec h264 -acodec aac -strict -2 -y vid.mp4 > fflog.txt 2>&1

这导致fflog.txt

中的以下输出
Stream mapping:
Stream #0:1 -> #0:0 (h264 (native) -> h264 (libx264))
Stream #0:0 -> #0:1 (aac (native) -> aac (native))
Press [q] to stop, [?] for help
frame=   50 fps=0.0 q=0.0 size=       0kB time=00:00:03.20 bitrate=   0.1kbits/s
frame=   73 fps= 70 q=28.0 size=     230kB time=00:00:04.05 bitrate= 465.4kbits/s
frame=  100 fps= 65 q=28.0 size=     462kB time=00:00:05.44 bitrate= 695.3kbits/s

之后我可以通过

获得线路
tail -f -1 fflog.txt

文件外。但我认为这些线路没有正确转义。 Vi向我展示了以下内容:

frame=   50 fps=0.0 q=0.0 size=       0kB time=00:00:03.20 bitrate=   0.1kbits/s
^Mframe=   73 fps= 70 q=28.0 size=     230kB time=00:00:04.05 bitrate= 465.4kbits/s
^Mframe=  100 fps= 65 q=28.0 size=     462kB time=00:00:05.44 bitrate= 695.3kbits/s
^Mframe=  125 fps= 61 q=28.0 size=     608kB time=00:00:06.48 bitrate= 767.5kbits/s

所以问题是:

  1. 如何将CRLF转换为UNIX,如LF,以通过tail -n?
  2. 正确返回数据
  3. 甚至更好:如何将ffmpeg结果正确地传递给mkfifo命名管道?
  4. 或者最一般的:有没有不同的方式以更聪明的方式实现我的目标?

1 个答案:

答案 0 :(得分:1)

让我们先解决这些行结尾。 ffmpeg使用回车符('\ r')将光标发送回行的开头,因此它不会使用进度消息填充终端。使用tr,修复很简单。

ffmpeg -i input.mov output.webm 2>&1 | tr '\r' '\n'

现在您应该分别看到每个进度线。如果我们管道或重定向到其他地方,事情会变得更有趣。

ffmpeg -i input.mov output.webm 2>&1 | tr '\r' '\n' | cat

请注意,输出显示为块而不是逐行。如果您的目的无法接受,则可以使用stdbuf来禁用tr的输出缓冲。

ffmpeg -i input.mov video.webm 2>&1 | stdbuf -o0 tr '\r' '\n' | cat

为了从另一个shell读取输出,命名管道可能会起作用。但是,管道在ffmpeg完成之前不会结束,因此tail在此之前不会打印任何内容。您可以使用其他工具(例如catgrep)读取正在进行的管道,但使用普通文件可能更容易。

# shell 1
ffmpeg -i input.mov output.webm 2>&1 | stdbuf -o0 tr '\r' '\n' > fflog.txt

# shell 2
tail -f fflog.txt