I'm trying to run this command:
~ $ sudo ffmpeg -stream_loop -1 -re -i funnyVideo.mp4 -map 0:v -f v4l2 /dev/video2
which every second outputs the frame number it's displaying:
... other ...
frame= 1 fps=0.0 q=-0.0 size=N/A time=00:00:00.03 bitrate=N/A speed=0.0665x
then the last line is replaced with the new displayed frame number.
frame= 23 fps= 23 q=-0.0 size=N/A time=00:00:00.76 bitrate=N/A dup=15 drop=0
and so on. I'm trying to wait for the string "frame= 205", execute another script and let the process continue:
while IFS= read -r line; do
if [[ "$line" =~ "frame= 205" ]]; then
echo "Frame 205 has been reached"
break;
fi
done < <(sudo ffmpeg -stream_loop -1 -re -i funnyVideo.mp4 -map 0:v -f v4l2 /dev/video2)
I have no idea what's going on here. Why isn't it echo
ing Frame 205 has been reached
even if I can see the line containing text frame= 205
after a while?
CodePudding user response:
The fact that you can see it is the problem. You never output the lines you read, so how are they showing up? It's because they're not captured.
To capture such lines, redirect stderr to stdout with <(sudo ffmpeg ... 2>&1)
You will then find that ffmpeg
doesn't output \n
s between these updates, which is how it's making the line update in place. You can use IFS= read -d $'\r' -r line
to read carriage returns separators instead.
PS: The frame numbers are based on a timer and therefore not deterministic. Sometimes it'll give you frame= 205
and sometimes frame= 209
.