我试图将 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
所以问题是:
- 如何像LF一样将CRLF转为UNIX,通过tail -n正确返回数据?
- 甚至更好:如何将 ffmpeg 结果正确地传输到 mkfifo 命名管道?
- 或者最一般的:是否有其他方法可以更聪明地实现我的目标?
最佳答案
让我们先解决行尾问题。 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
请注意,输出显示为 block 而不是逐行。如果这对您的目的来说是 Not Acceptable ,您可以使用 stdbuf
来禁用 tr
的输出缓冲。
ffmpeg -i input.mov video.webm 2>&1 | stdbuf -o0 tr '\r' '\n' | cat
要从不同的 shell 读取输出,命名管道可能会起作用。然而,直到 ffmpeg
完成,管道才会结束,所以 tail
在那之前不会打印任何东西。您可以使用 cat
或 grep
等其他工具读取正在进行的管道,但使用普通文件可能更容易。
# shell 1
ffmpeg -i input.mov output.webm 2>&1 | stdbuf -o0 tr '\r' '\n' > fflog.txt
# shell 2
tail -f fflog.txt
关于linux - 将 ffmpeg 输出管道传输到命名管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30922897/