Extracting frames from video while recording using ffmpeg - ffmpeg

I am using ffmpeg to record a video using a Raspberry Pi with its camera module.
I would like to run a image classifier on a regular interval for which I need to extract a frame from the stream.
This is the command I currently use for recording:
$ ffmpeg -f video4linux2 -input_format h264 -video_size 1280x720 -framerate 30 -i /dev/video0 -vcodec copy -an test.h264
In other threads this command is recommended:
ffmpeg -i file.mpg -r 1/1 $filename%03d.bmp
I don't think this is intended to be used with files that are still appended to and I get the error "Cannot use -sseof, duration of test.h264 not known".
Is there any way that ffmpeg allows this?

I don't have a Raspberry Pi set up with a camera at the moment to test with, but you should be able to simply append a second output stream to your original command, as follows to get, say, 1 frame/second of BMP images:
ffmpeg -f video4linux2 -input_format h264 -video_size 1280x720 -framerate 30 -i /dev/video0 -vcodec copy -an test.h264 -r 1 frame-%03d.bmp

Related

ffmpeg - How do I capture AND rotate a video at the same time?

I need to record video from a USB camera using ffmpeg. The issue is that the camera is upside down and can't be repositioned, so I have to rotate 180°.
So far I'm using this command to capture:
ffmpeg -framerate 30 -video_size 1280x720 -t 00:58:00 -i /dev/video0 output.mp4
And then I rotate it using this other command:
ffmpeg -i output.mp4 -vf "rotate=180*(PI/180), format=yuv420p" -metadata:s:v rotat=0 -codec:v libx264 -codec:a copy ROTATED_output.mp4;
Both commands are working perfeclty but it takes me twice the time. Is it possible to capture with the filter enabled so that the frames are rotated before being saved the first time?
Just add the filters from your second command to your first command:
ffmpeg -framerate 30 -video_size 1280x720 -t 00:58:00 -i /dev/video0 -vf "rotate=180*(PI/180),format=yuv420p" output.mp4

How to get non-decoded h264 stream from the webcam using ffmpeg?

I want to get the file which is non-decoded h264 format to use in another client application. I know how to stream to disk using below command from the docs.
Example to encode video from /dev/video0:
ffmpeg -f v4l2 -framerate 25 -video_size 640x480 -i /dev/video0 output.mp4
High level Diagram
This is typical producer and consumer problem -
Webcam =============> ffmpeg to video stream into file. (producer)
^
|
|
Client ________________________________|
(consumer)
// reads only Non-decoded h264 format from a file.
Use
ffmpeg -f v4l2 -framerate 25 -video_size 640x480 -i /dev/video0 output.mp4 -c copy out.h264
out.h264 is the received H264 bitstream, saved as a file.
I found this as solution
ffmpeg -pix_fmt yuv420p -y -f v4l2 -vcodec h264 -i /dev/video0 out.h264

ffmpeg how to record and preview at the same time

I want to capture video+audio from directshow device like webcam and stream it to RTMP server. This part no problem. But the problem is that I want to be able to see the preview of it. After a lot of search someone said pipe the input using tee muxer to ffplay. but I couldn't make it work. Here is my code for streaming to rtmp server. how should I change it?
ffmpeg -rtbufsize 8196k -framerate 25 -f dshow -i video="Microsoft® LifeCam Studio(TM)":audio="Desktop Microphone (Microsoft® LifeCam Studio(TM))" -vcodec libx264 -acodec aac -strict -2 -b:v 1024k -b:a 128k -ar 48000 -s 720x576 -f flv "rtmp://ip-address-of-my-server/live/out"
Here is the final code I used and it works.
ffmpeg -rtbufsize 8196k -framerate 25 -f dshow -i video="Microsoft® LifeCam Studio(TM)":audio="Desktop Microphone (Microsoft® LifeCam Studio(TM))" -vcodec libx264 -acodec aac -strict -2 -f tee -map 0:v -map 0:a "[f=flv]rtmp://ip-address-and-path|[f=nut]pipe:" | ffplay pipe:
The core command for those running ffmpeg on a Unix-compatible system (e.g. MacOS, BSD and GNU-Linux) is really quite simple. It's to redirect or to "pipe" one of the outputs of ffmpeg to ffplay. The main problem here is that ffmpeg cannot autodetect the media format (or container) if the output doesn't have a recognizable file extension such as .avi or .mkv.
Therefore you should specify the format with the option -f. You can list the available choices for option -f with the ffmpeg -formats command.
In the following GNU/Linux command example, we record from an input source named /dev/video0 (possibly a webcam). The input source can also be a regular file.
ffmpeg -i /dev/video0 -f matroska - filename.mkv | ffplay -i -
A less ambiguous way of writing this for non-Unix users would be to use the special output specifier pipe.
ffmpeg -i /dev/video0 -f matroska pipe:1 filename.mkv | ffplay -i pipe:0
The above commands should be enough to produce a preview. But to make sure that you get the video and audio quality you want, you also need to specify, among other things, the audio and video codecs.
ffmpeg -i /dev/video -c:v copy -c:a copy -f matroska - filename.mkv | ffplay -i -
If you choose a slow codec like Google's AV1, you'd still get a preview, but one that stutters.

ffmpeg: Low framerate when capturing with -vcodec mjpeg but not with -vcodec copy

I'm trying to capture video from a webcam, and I find that when I use the -vcodec copy option, it works really well (far better than any other software I've tried). However, I'd like my files to be a bit smaller, and it seems that every attempt I make to compress the video leads to extremely jumpy video. If, for example, I switch the output vcodec to mjpeg, it changes from reporting 15 fps to reporting between 3 and 4 fps. Am I doing something wrong?? Here is the call with -vcodec copy:
ffmpeg -y -f dshow -vcodec mjpeg -s 1184x656 -framerate 25 -i video="HD 720P Webcam" -vcodec copy test.avi
-- which gets me 15 fps. But if I change to mjpeg, I get only 3-4 fps:
ffmpeg -y -f dshow -vcodec mjpeg -s 1184x656 -framerate 25 -i video="HD 720P Webcam" -vcodec mjpeg test.avi
Experimental attempts to put -framerate 25 or -r 25 before test.avi also does nothing to help the situation. I'm not getting any smoother video when experimenting with mpeg4 or libx264 either. Only the copy option gives me smooth video (btw I'm filming my hands playing a piano, so there is a lot of fast motion in the videos).
Help!!!! And thank you...
I don't understand why the framerate drops so much, but you could try a 2 pass approach where you first record it using -vcodec copy (as you pasted in the question)
ffmpeg -y -f dshow -vcodec mjpeg -s 1184x656 -framerate 25 -i video="HD 720P Webcam" -vcodec copy test.avi
Then transcode it into mjpeg once it's done (something like this):
ffmpeg -i test.avi -vcodec mjpeg test.mjpeg
note: I haven't actually tested any of the above command lines.
Sounds like your webcam is outputting a variable frame rate stream. Try the below on one of your copy captured files.
ffmpeg -i test.avi -vcodec libx264 -r 30 test.mp4
(You should avoid capturing to AVI, use MKV instead)

How to stream webcam video using ffmpeg?

I am very new to ffmpeg and just read some examples on how to open a video file and decode its stream.
But is it possible to open a webcam's stream, something like:
http://192.168.1.173:80/live/0/mjpeg.jpg?x.mjpeg
Is there any examples/tutorials on this?
I need to use ffmpeg as decoder to decode the stream in my own Qt based program.
Nyaruko,
First check if your webcam is supported... Do
ffmpeg -y -f vfwcap -i list
Next ,
ffmpeg -y -f vfwcap -r 25 -i 0 out.mp4 for encoding
This site has helpful info;
http://www.area536.com/projects/streaming-video/
Best of Luck.
This works for live video streaming:
ffplay -f dshow -video_size 1280x720 -i video0
The other option using ffmpeg is:
ffmpeg -f dshow -video_size 1280x720 -i video0 -f sdl2 -
Above both the solution are provided by FFMPED

Resources