Twitter Security Cam

Friday, February 5, 2010 by BBTUNA

So its Saturday afternoon and you have nothing to do. As you glance around your room you spot a half full beer, a webcam, and that linux box that you have been wondering what you were going to do with. Seriously, why did you buy that piece of crap webcam anyway? A quick google search reveals that you might have a hard time even getting that thing working in XP, let alone your preferred OS of choice, OSX. =)

Ok, I know what to do. First dont drink that beer.. Its old. Throw it away and clean up your room a little bit. Then go get another beer -- and lets try to finish this one Nancy. As you sit back and nurse your new beer you notice that your Asus EEE with BackTrack4 is in a somewhat different place than you left it. Instead of simply plotting your revenge on who ever you feel deserves the blame, lets try catching them next time red-handed.

The following will walk you through setting up a video-surveillance system that will detect motion, enable your webcam, take pictures of the intruder, and upload the pics online and notify your cell phone via an twitter SMS message.

You will need:

  • USB Webcam
  • Linux installed on a machine (I will use Ubuntu "Gutsy Gibbon" in my example, but should be similar for other Linux distros)
  • All ways on internet connection

Before we begin, you will want to make sure your webcam is supported by your Linux distro. First lets check to see if it works out of the box. Turn on your machine and login. Plug in your USB video camera and open a terminal window. Type:

lsusb

to determine if your webcam was detected. Your output should look something simiar to:

hevnsnt@linuxbox:~/motion$ lsusb
Bus 003 Device 001: ID 0000:0000
Bus 002 Device 007: ID 045e:0039 Microsoft Corp. IntelliMouse Optical
Bus 002 Device 006: ID 0553:0002 STMicroelectronics Imaging Division (VLSI Vision) CPiA WebCam Bus 002 Device 001: ID 0000:0000

(Although of course your output will match your configuration)

Record the bus location and device id of your webcam. (Bus 002 Device 006 in this example.) Now open "Ekiga Softphone" (installed by default in Ubuntu under Applications / Internet / Ekiga Softphone).

We are going to use this application to make sure that your USB camera is working (so far without ANY WORK!) You might have to click the camera icon, and if everything works, you should be getting a live picture. If not, check your Ekiga Preferences (Edit/Preferences/Video Devices) and change your input device to the device you discovered earlier. If this doesn't work you should Google for the device ID plus Linux driver. (eg 0553:0002 linux driver) Come back to this tutorial when you get it working. If you cant get it working check craigslist.org for a newer camera, but I doubt you will need to. Seriously If I got this crusty old zoom 1595 camera working, I am sure you can get yours working.

Detecting Motion:

In order to detect motion, we are going to use a software motion detection package appropriately titled "motion". Now since I know you probably are on a debian Ubuntu machine, so you are thinking "Oh this will be easy, apt-get install motion". Well you did get one thing right, it will be easy, but we are not going to use apt-get. The ubuntu repositories still have a much older version of "motion" than we want. To get the latest version (this tutorial was written using build 3.2.11) open a terminal window and type the following commands: (note this will download and install a .deb, you could always install from source)

mkdir ~/motion
cd ~/motion
wget
http://prdownloads.sourceforge.net/motion/motion_3.2.11-1.ubuntu.hardy_i386.deb?download
sudo dpkg -i motion_3.2.11-1.ubuntu.hardy_i386.deb

Congratulations, you have installed motion. Yeah Ubuntu! Now you just need to configure it. And let me tell you, there is A TON of configuration options, luckily it comes with a very well commented configuration file located at /etc/motion/motion.conf. Should you want to tweak your installation later, I would start with this configuration file.

However, for the sake of quicky-ness, I will share my configuration file that I spent a lot of time tuning and testing for my setup. Save it to ~/motion/motion.conf

# TwitterSecuritySystem motion.conf
# This config file was created for motion 3.2.11

############################################################
# Daemon
############################################################

# Start in daemon (background) mode and release terminal (default: off)
daemon on

# File to store the process ID, also called pid file. (default: not defined)
process_id_file /var/run/motion/motion.pid

###########################################################
# Capture device options
############################################################

# Videodevice to be used for capturing (default /dev/video0)
videodevice /dev/video0
v4l2_palette 8

# The video input to be used (default: 8)
# Should normally be set to 0 or 1 for video/TV cards, and 8 for USB cameras
input 8

# The video norm to use (only for video capture and TV tuner cards)
# Values: 0 (PAL), 1 (NTSC), 2 (SECAM), 3 (PAL NC no colour). Default: 0 (PAL)
norm 1

# Rotate image this number of degrees. The rotation affects all saved images as
# well as mpeg movies. Valid values: 0 (default = no rotation), 90, 180 and 270.
rotate 0

# Image width (pixels). Valid range: Camera dependent, default: 352
width 320

# Image height (pixels). Valid range: Camera dependent, default: 288
height 240

# Maximum number of frames to be captured per second.
# Valid range: 2-100. Default: 100 (almost no limit).
framerate 2

# Minimum time in seconds between capturing picture frames from the camera.
# Default: 0 = disabled - the capture rate is given by the camera framerate.
# This option is used when you want to capture images at a rate lower than 2 per second.
minimum_frame_time 3

auto_brightness off
brightness 0
contrast 0
saturation 0
hue 0

############################################################
# Motion Detection Settings:
############################################################

# Threshold for number of changed pixels in an image that
# triggers motion detection (default: 1500)
threshold 1500

# Automatically tune the threshold down if possible (default: off)
threshold_tune off

# Noise threshold for the motion detection (default: 32)
noise_level 32

# Automatically tune the noise threshold (default: on)
noise_tune on

# Despeckle motion image using (e)rode or (d)ilate or (l)abel (Default: not defined)
# Recommended value is EedDl. Any combination (and number of) of E, e, d, and D is valid.
# (l)abeling must only be used once and the 'l' must be the last letter.
# Comment out to disable
despeckle EedDl

# Ignore sudden massive light intensity changes given as a percentage of the picture
# area that changed intensity. Valid range: 0 - 100 , default: 0 = disabled
lightswitch 0

# Picture frames must contain motion at least the specified number of frames
# in a row before they are detected as true motion. At the default of 1, all
# motion is detected. Valid range: 1 to thousands, recommended 1-5
minimum_motion_frames 1

# Specifies the number of pre-captured (buffered) pictures from before motion
# was detected that will be output at motion detection.
# Recommended range: 0 to 5 (default: 0)
# Do not use large values! Large values will cause Motion to skip video frames and
# cause unsmooth mpegs. To smooth mpegs use larger values of post_capture instead.
pre_capture 0

# Gap is the seconds of no motion detection that triggers the end of an event
# An event is defined as a series of motion images taken within a short timeframe.
# Recommended value is 60 seconds (Default). The value 0 is allowed and disables
# events causing all Motion to be written to one single mpeg file and no pre_capture.
gap 60

############################################################
# Image File Output
############################################################

# Output 'normal' pictures when motion is detected (default: on)
# Valid values: on, off, first, best, center
# When set to 'first', only the first picture of an event is saved.
# Picture with most motion of an event is saved when set to 'best'.
# Picture with motion nearest center of picture is saved when set to 'center'.
# Can be used as preview shot for the corresponding movie.
output_normal center

# The quality (in percent) to be used by the jpeg compression (default: 75)
quality 75

############################################################
# Text Display
# %Y = year, %m = month, %d = date,
# %H = hour, %M = minute, %S = second, %T = HH:MM:SS,
# %v = event, %q = frame number, %t = thread (camera) number,
# %D = changed pixels, %N = noise level, \n = new line,
# %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 - do not use with text_event!
# You can put quotation marks around the text to allow
# leading spaces
############################################################

# Locate and draw a box around the moving object.
# Valid values: on, off and preview (default: off)
# Set to 'preview' will only draw a box in preview_shot pictures.
locate on

# Draws the timestamp using same options as C function strftime(3)
# Default: %Y-%m-%d\n%T = date in ISO format and time in 24 hour clock
# Text is placed in lower right corner
text_right %Y-%m-%d\n%T-%q
text_event %Y%m%d%H%M%S

# Draw characters at twice normal size on images. (default: off)
text_double off

############################################################
# Target Directories and filenames For Images And Films
# For the options snapshot_, jpeg_, mpeg_ and timelapse_filename
# you can use conversion specifiers
# %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
# Quotation marks round string are allowed.
############################################################

# Target base directory for pictures and films
# Recommended to use absolute path. (Default: current working directory)
target_dir ~/motion/

# File path for snapshots (jpeg or ppm) relative to target_dir
# Default: %v-%Y%m%d%H%M%S-snapshot
# Default value is equivalent to legacy oldlayout option
# For Motion 3.0 compatible mode choose: %Y/%m/%d/%H/%M/%S-snapshot
# File extension .jpg or .ppm is automatically added so do not include this.
# Note: A symbolic link called lastsnap.jpg created in the target_dir will always
# point to the latest snapshot, unless snapshot_filename is exactly 'lastsnap'
snapshot_filename %v-%Y%m%d%H%M%S-snapshot

# File path for motion triggered images (jpeg or ppm) relative to target_dir
# Default: %v-%Y%m%d%H%M%S-%q
# Default value is equivalent to legacy oldlayout option
# For Motion 3.0 compatible mode choose: %Y/%m/%d/%H/%M/%S-%q
# File extension .jpg or .ppm is automatically added so do not include this
# Set to 'preview' together with best-preview feature enables special naming
# convention for preview shots. See motion guide for details
jpeg_filename %v-%Y%m%d%H%M%S-%q

############################################################
# Live Webcam Server
############################################################

# The mini-http server listens to this port for requests (default: 0 = disabled)
webcam_port 0
webcam_quality 50
webcam_motion off
webcam_maxrate 1
webcam_localhost on
webcam_limit 0

############################################################
# HTTP Based Control
############################################################

# TCP/IP port for the http server to listen on (default: 0 = disabled)
control_port 0
control_localhost on
control_html_output on

############################################################
# 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.
############################################################

# Do not sound beeps when detecting motion (default: on)
# Note: Motion never beeps when running in daemon mode.
quiet on

# Command to be executed when a picture (.ppm|.jpg) is saved (default: none)
# To give the filename as an argument to a command append it with %f
# on_picture_save echo I would have said on save %f
on_picture_save perl ~/motion/updateTwitter.pl --username YOURUSERNAME --password YOURPASSWORD --message "At %H:%M:%S Motion Was Detected" --picture %f

# Command to be executed when a camera can't be opened or if it is lost
# NOTE: There is situations when motion doesn't detect a lost camera!
# It depends on the driver, some drivers don't detect a lost camera at all
# Some hang the motion thread. Some even hang the PC! (default: none)
on_camera_lost perl ~/motion/updateTwitter.pl --username YOURUSERNAME --password --message "WARNING Camera Was Not Detected"


Notification of Motion:

Now for the fun part, if you used the above configuration file at this point your system is configured to detect motion, and then snap a picture. It also is configured to save the "best" picture, and outline the movement that it captured. Yeah so what. Lets use kick it up a notch by using Web2.0 tools to notify us so that we can take appropriate action.

First create ANOTHER (assuming you already have a twitter account) twitter account, naming it something like mySECURITY or something that is specific to you. You will not give this name out to anyone so feel free to name it whatever you want. I gave my new twitter account an profile image of a security monkey.

In order to upload the motion-detected captured picture utilizing twitter (and more specifically twitpic) we are going to need call a script written by rtadlock at http://rtadlock.blogspot.com via the motion.conf. (these lines are bolded above) Save the following as ~/motion/updateTwitter.pl

#!/usr/bin/perl

use strict;
use LWP::UserAgent;
use HTTP::Request::Common;
use Getopt::Long;

# Values to use when uploading to TwitPic
# You can change these defaults and you can
# override them with the command line options
my $picture;
my $username = 'USERNAME'; # This has to be your twitter username, not your email
my $password = 'PASSWORD'; # Twitter password
my $message = 'New Motion Detected'; # message you'd like to post
my $uploadOnly = 0; # Upload only, don't update Twitter
my $verbose = 0;

# These can be changed if the TwitPic API
# locations change
my $uploadAndPostSite = "http://twitpic.com/api/uploadAndPost";
my $uploadOnlySite = "http://twitpic.com/api/upload";

GetOptions( "help|h|?" => sub { Usage() && exit( 0 ) },
"picture=s" => \$picture,
"username=s" => \$username,
"password=s" => \$password,
"uploadOnly" => \$uploadOnly,
"verbose" => \$verbose,
"message=s" => \$message ) or Usage() && exit( -1 );

if( !$picture || !$username || !$password )
{
print "ERROR: Please provide all required arguments\n";
Usage() && exit( -1 );
}

if( ! -e $picture || ! -f $picture )
{
print "ERROR: The picture you specified $picture doesn't seem to exist\n";
exit( -1 );
}

if( $verbose )
{
print "Attempting to upload pic to TwitPic with the following options:\n";
print "Picture: $picture\n";
print "Username: $username\n";
print "Password: $password\n";
print "Message: $message\n";
print "Upload only: ";
if( $uploadOnly )
{
print "Yes";
}
else
{
print "No";
}
print "\n\n";
}

my $response;
my $ua = LWP::UserAgent->new( env_proxy => 1,
keep_alive => 1,
timeout => 30 );
if( $verbose )
{
print "Uploading picture to TwitPic.com...\n";
}

if( $uploadOnly )
{
$response = $ua->request( POST $uploadOnlySite,
Content_Type => 'multipart/form-data',
Content => [
media => ["$picture"],
username => $username,
password => $password ] );
}
else
{
$response = $ua->request( POST $uploadAndPostSite,
Content_Type => 'multipart/form-data',
Content => [
media => ["$picture"],
username => $username,
password => $password,
message => $message ] );
}

if( !$response->is_success )
{
print "ERROR: There was a problem while trying to contact to TwitPic\n";
die $response->status_line;
}

if( $verbose )
{
print "Done trying to uploading picture, checking response for errors\n";
}

# I guess we could actually use XML::Parser to parse this, but it's kind of
# over kill in this situation
if( $response->content =~ /stat="fail"/ )
{
$response->content =~ /msg="(.*)"/;
print "\nERROR: There was an error uploading your picture to TwitPic\n";
print "INFO: $1\n";
exit( -1 );
}

# If verbose, print out the response, so the user can access the picture
if( $verbose )
{
print "\nUploade successful, here are the details:\n";
$response->content =~ /(.*)<\/mediaid>/;
print "Media id: $1\n";
$response->content =~ /(.*)<\/mediaurl>/;
print "Media url: $1\n";

}

sub Usage()
{
print "\n";
print "updateTwitter.pl --username user --password pass --picture pathToPicture [--message messageToTwitter] [--uploadOnly]\n\n";

print "--username\tYour Twitter.com username\n";
print "--password\tYour Twitter.com password\n";
print "--picture\tPath to the picture you want to post\n";
print "--message\tOptional message to Tweet with your picture\n";
print "--uploadOnly\tUpload to TwitPic.com only and don't Tweet. This will ignore any message passed in\n";

}

Putting it all together

At this point you should have:

  • motion installed
  • motion.conf located in your ~/motion/ folder
  • updateTwitter.pl located in your ~/motion/ folder
  • A new twitter account created, and all relevant user/pass information updated in both motion.conf and updateTwitter.pl

In your terminal type the following:

motion -n -c ~/motion/motion.conf

(-n does not allow it to go into daemon mode, and -c passes a custom configuration)

If everything goes right, you should start capturing images, storing them into your ~/motion/ directory, and updating your new twitter feed. Now all you need to do is simply follow your new twitter account with your original one, and allow for device updates.

Now whenever somone comes into range of your camera, it will take a picture, upload to twitpic, and then send your cell phone a SMS message notifying you. If you have a web enabled phone, you can see the pictures in real time!

Posted in | 0 Comments »

0 comments:

Post a Comment

About Me

Blog Archive