I'm trying to get ffmpegs output to a named pipe, where I could read from another shell. I do not need the video stream piped, just the informations below to get a state of the conversion process back. I am not able to achieve the piping behavior in any way, but I can write the data to a file with the following command:
ffmpeg -i vid.mov -vcodec h264 -acodec aac -strict -2 -y vid.mp4 > fflog.txt 2>&1
This leads to the following output in 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
Afterwards I can get lines via
tail -f -1 fflog.txt
out of the file. But the lines are not escaped correctly, I think. Vi shows me the following:
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
So the questions are:
- How to convert the CRLF to UNIX like LF to return data correctly via tail -n?
- Or even better: How to pipe the ffmpeg results correctly to a mkfifo named pipe?
- Or the most general: Is there a different way to achieve my goal in a more clever manner?
Let's tackle the line endings first.
ffmpeg
uses carriage return ('\r') to send the cursor back to the start of the line so it doesn't fill up the terminal with progress messages. Withtr
, the fix is simple.Now you should see each progress line separately. Things get more interesting if we pipe or redirect somewhere else.
Notice that the output appears as chunks rather than line-by-line. If that's not acceptable for your purposes, you can use
stdbuf
to disabletr
's output buffering.For reading the output from a different shell, a named pipe might work. However, the pipe won't end until
ffmpeg
finishes, sotail
won't print anything until then. You can read a pipe in progress with other tools likecat
orgrep
, but it's probably easier to just use a plain file.