Capturing frames of a video using a shell script

Categories Shell Scripts

A few weeks ago, an idea came into my mind of writing a shell script in order to capture all the different video frames as images from a video. I did that because I use my pc camera to record an outside area of my house for security reason, and I am lazy to watch the video 7-8 hours long every day for any suspicious movement. I know that there are a lot of cameras that record everything on a cloud and also notify you for any movement but before I manage to buy one of these, I decided to use my pc camera instead.

Parameters of the script

So, as I say above, I have written a shell script that takes three required parameters. Also, there is another parameter for help that explains with more details about the three mandatory parameters. This parameter is passed by typing -h as the majority of the shell scripts.

One of these three parameters is the video file. Symply, after the script name, this parameter is passed by typing -v and the video file. If the video file is not located in the same directory that the script runs then the video path should be specified as well.

Second parameter is about the number of seconds that are left between each captured frame of the video. For instance, if you want to capture each frame of the video every 30 seconds then the number of the seconds should be 30. This parameter can be passed by typing -s and the number of seconds.

Third parameter is the directory that all the images from the frames will be stored. This parameter can be passed by typing -o and the directory name. If the directory is not located inside the directory that the script runs then the full path of the directory needs to be specified.

An example running this command can be found below.

sh capture-diff-frames.sh -v /path/to/video.mp4 -s 30 -o /path/to/output-dir/
What the script does

In general, this script extracts all the frames of a video and it stores the frames as images inside a directory. The frequency of the exported frames can be set by passing a number counted as seconds.

The command ffmpeg is used inside the script in order to extract the frames as images with a time difference in seconds between them and afterwards it stores the images inside a folder.

In order to reduce the numbers of images, the script uses the compare command to compare the differences between the images and remove quite similar images.

At the end, with the images that have been left, there is a calculation in order to find the exact time in the video that each frame has been captured and this time is appended at the end of each corresponding image.

At this point, I would like to mention that I have done a lot of tests to find the best percentage of the frames differences and finally to keep the non similar images. This might not be the best percentage for you so this can be changed inside the script by changing the fuzzPercent variable from 10 to the best number for you. Also, this script has been tested on Linux and Mac machines.

Source of the script

The script source can be found here.