Motion is a program that monitors the video signal from one or more cameras and is able to detect if a significant part of the picture has changed; in other words, it can detect motion.
Installation is quite simple and straight foward; once you get your webcam drivers up and running, just follow these steps: http://www.lavrsen.dk/foswiki/bin/view/Motion/MotionGuideInstallation.
All in all it works well out of the box, you can have a live stream from your webcams, software detects motion and enables you to execute a piece of code or external command when it happens. It supports multiple cameras and has a bunch of options that can are in config file, usually located in /etc/motion/motion.conf.
So, you have your motion daemon that works in background and analises frames as they come from webcam. If difference between two consecutive frames (after noise filtering etc) is above some defined threshold then this is considered as motion or event and it is given it’s own ID. At this point motion starts taking snapshots and create video from these snapshots, stores them in predefined location as long as something is moving. As soon as motion stops, event is finished and snapshots are no longer taken. As software is taking snapshots, for each snapshot it will call any code defined in on_picture_save (defined in motion.conf file).
Now, let’s assume that motion is up and running and you’d like to get email with attached images when something moves in cameras viewport.
One solution would be to put some code on on_picture_save event (which denotes that picture is taken), i.e.:
on_picture_save sendEmail -f <email_from> -t <email_to> -u 'Subject...' -a %f
However, this will be triggered for each snapshot taken resulting in mountain of emails that will be hard to review or make sense of them all. Different approach would be to send all snapshots when event is finished. In order to do that we can hook on_movie_end event.
on_movie_end is triggered when motion stops and video ends as well, this might be a good moment to gather all snapshots that belong to that event and send them to your email address.
As mentioned before snapshots reside in predefined location and filenames follow simple logic, by default: %v-%Y%m%d%H%M%S-snapshot, meaning that event ID (%v) and timestamp (%Y%m%d%H%M%S) are in filename.
Helpfully Motion exposes several conversion specifiers that can be used to identify current event, timestamp, noise levels and all other kind of data. Here’s a list from default config file:
# External Commands, Warnings and Logging:
# You can use conversion specifiers for the on_xxxx commands
# %Y = year, %m = month, %d = date,
# %H = hour, %M = minute, %S = second,
# %v = event, %q = frame number, %t = thread (camera) number,
# %D = changed pixels, %N = noise level,
# %i and %J = width and height of motion area,
# %K and %L = X and Y coordinates of motion center
# %C = value defined by text_event
# %f = filename with full path
# %n = number indicating filetype
# Both %f and %n are only defined for on_picture_save,
# on_movie_start and on_movie_end
# Quotation marks round string are allowed.
so this might end up like this:
# Command to be executed when a movie file (.mpg|.avi) is closed. (default: none)
# To give the filename as an argument to a command append it with %f
on_movie_end sendEmail -f <from: email> -t <to: email> -u 'Subject...' -a /tmp/motion/%v-*.jpg
This will send all snapshots from /tmp/motion/<event_ID>-*.jpg as email attachment. However, this autoincrementing ID tends to reset every time daemon is restarted so you’ll get all images that were ever captured with the same ID. Application itself is rather stable but still I extended event ID with year-month-day timestamp that aligns with snapshots filename.
on_movie_end sendEmail -f <from: email> -t <to: email> -u 'Subject...' -a /tmp/motion/%v-%Y%m%d*.jpg
Another aproach might be to periodically move or delete old snapshots…
It might be a bit easier to maintain everything if you keep your code in separate file and have Motion call your script, e.g.:
on_movie_end /home/user/on_movie_end.sh %v %Y%m%d %H:%M:%S
sendEmail -f <from: email> -t <to: email> -u 'Subject...' -m 'Info:\n'"EventID: $1"'\n'"Datestamp: $2"'\n'"Timestamp: $3" -s <your_smtp_server>:25 -xu <your_smtp_user> -xp <your_smtp_password> -a /tmp/motion/$1-$2*.jpg
(don’t forget to make your script executable e.g. chmod +x /home/user/on_movie_end.sh)
Code above uses custom smtp settings to send email (so you won’t need to configure your machine as email server if you don’t want to) so just adjust it to your settings…