Click here to Skip to main content
15,397,498 members
Articles / Multimedia / DirectX
Posted 16 May 2010


150 bookmarked

Cam Alarm 2.0 - Alarm system run from a web camera

Rate me:
Please Sign up or sign in to vote.
4.86/5 (33 votes)
16 Jun 2010CPOL3 min read
Simple alarm system for those on a budget..


Just a quickie..

I wrote the original version of this in VB6 about 4 years ago, and published it as freeware (might even be floating around the wild somewhere still..), and decided it was a good starter app for learning C#, when I began migrating my skills almost two years ago. So, the uncompleted version of this has been sitting in a folder on my dev box for some time, just waiting for a few tweaks - which I got around to the other day. I thought this would be a good target freeware, because unfortunately, many of us have had the misfortune of being robbed at some point in our lives, and students, young working people, or someone in an apartment may not be able to afford or install a proper alarm system.

I use a Creative 5.1 speaker rig, and with the amp cranked, the siren this sounds is at least as loud as a conventional alarm system, and would probably cause an intruder to bolt rather than attempt to find the source and disarm.

The original used the avicap32.dll library, which seemed to work fine on my older Logitech camera, but will not work on newer devices (this was tested with both an Acer notebook camera, and an MS Lifecam). At this point, I realized I had to go to the DirectShow library to capture video from a wider range of input devices. A search on CodeProject turned up the Motion Detection project by Andrew Kirillov. I removed dependencies on the AForge library, and reworked the AVI reader/writer classes, but the DirectShow wrappers and detection algorithms are his work (thanks Andrew).

The highlights

When the application loads, it tests for the WMV AVI recording codec by enumerating the installed codecs; if it isn't found, a dialog is launched, asking the user to install it. The installation executable is an embedded resource, which is pulled from the resource assembly and recreated as a file in the temp directory, then launched with the ShellExecute API.

private void codecTest()
    FilterCollection filters = new FilterCollection(FilterCategory.VideoCompressorCategory);
    bool found = false;
    foreach (Filter filter in filters)
        found = filter.Name.Contains("Media Video 9");
        if (found)
    if (!found)
        if (MessageBox.Show("The video capture feature requires the Microsoft " + 
            "WMV9 codec. Do you want to install this now?", 
            "Codec Installation Required",
            MessageBoxIcon.Question) == DialogResult.OK)
            _bCanRecord = false;

private bool executeCodec()
        Assembly assembly = Assembly.GetExecutingAssembly();
        using (Stream stream = assembly.GetManifestResourceStream(
            if (stream != null)
                BinaryReader br = new BinaryReader(stream);
                using (FileStream fs = new FileStream(
                       Environment.GetEnvironmentVariable("TEMP") + 
                       "\\wmv9VCMsetup.exe", FileMode.Create))
                    BinaryWriter bw = new BinaryWriter(fs);
                    byte[] bt = new byte[stream.Length];
                    stream.Read(bt, 0, bt.Length);
                executeProgram(Environment.GetEnvironmentVariable("TEMP") + 
        return true;
    catch { return false; }

A timer is run that waits for the camera to focus in, then the control panels are activated. Settings like the keycode and option control states are stored in the application's default properties. When first run, or if the keycode property is cleared, the Arm/Disarm button acts as the keycode set button. The sounds used in the application are instances of the System.Media.SoundPlayer class, instanced and loaded with a sound file when the app initializes:

private void loadWarning()
    if (_cWarningSound != null)
    _cWarningSound = new SoundPlayer(CamAlarm.Resource1.beep);

The camera's motion trigger-state is polled periodically using a custom timer class; if motion has occurred, an alarm timer is fired, which will loop until the alarm is deactivated, or the max alarm timeout occurs:

private void _cAlarmTimer_Tick(object sender)
    // timer starts 5 states: standby, armed, arming, triggered, sounding
    //1) if arming warning period elapses, optional beeps
    //2) if not arming, warning sounds and counts to min elapse
    //3) if min elapse and _activetick over threshhold, loops again
    //4) if standby -stop timer
    if (_eAlarmState == AlarmState.Arming)
        if (_iTimerTick > stringToInt(txtArmingDelay.Text))
    else if (_eAlarmState == AlarmState.Armed)
        if (_iActiveTick > 5)
    else if (_eAlarmState == AlarmState.Sounding)
        if (_iTimerTick > stringToInt(txtDuration.Text))
            if (_iActiveTick < 5)
                //loop again
    else if (_eAlarmState == AlarmState.Standby)
    else if (_eAlarmState == AlarmState.Triggered)
        if (_iTimerTick > stringToInt(txtAlarmDelay.Text))
            if (!chkSilent.Checked)

When the alarm is in Armed mode, all but the keypad and disarm switch are disabled. This is done by disabling the GroupBox that houses the controls. The main form close button also needs to be deactivated. This is done both by cancelling the form's exit in the FormClosing event, and by disabling the Close button using the GetSystemMenu/EnableMenuItem API:

private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
    if (_bCloseDisabled)
        e.Cancel = true;
        if (_cAlarmTimer != null)

private void enableClose(bool enable)
    if (enable)
        EnableMenuItem(GetSystemMenu(this.Handle, false), SC_CLOSE, MF_ENABLED);
        EnableMenuItem(GetSystemMenu(this.Handle, false), SC_CLOSE, MF_GRAYED);
    _bCloseDisabled = !enable;

All in all, fairly simple approach; though I wasn't all that generous with comments in code, it is fairly straightforward..

Using the application..

Keep the camera view up where pets won't trigger it, and away from windows. Crank the volume on your speakers, and adjust application volumes through the mixer; CamAlarm has an option to push to the maximum volume when the alarm is activated, but this won't mean much if the master volume is down low.

Well.. enjoy! If you find any bugs, be sure to leave a message.

Change log

May 17, 2010

  • First time loading of help page creates page in user app folder.
  • Alarm volume raised after triggering warning beeps.
  • Fixed lock when capturing video, changed from Monitor.Enter to TryEnter in Camera.cs.
  • Added tooltip to Clear and Video buttons.
  • Added menu buttons to disabled items when alarm is activated.

June 16, 2010

  • Fixed codec URL in executeCodec().
  • Fixed disabled OK button in device selection form.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

John Underhill
Network Administrator
Canada Canada
Network and programming specialist. Started in C, and have learned about 14 languages since then. Cisco programmer, and lately writing a lot of C# and WPF code, (learning Java too). If I can dream it up, I can probably put it to code. My software company, (VTDev), is on the verge of releasing a couple of very cool things.. keep you posted.

Comments and Discussions

QuestionThis app does not work in net 4.6.1 Pin
AndySolo5-Jul-19 8:24
MemberAndySolo5-Jul-19 8:24 
QuestionMultiple Cameras Pin
chaitanya services and travels4-Aug-16 20:10
Memberchaitanya services and travels4-Aug-16 20:10 
GeneralMy vote of 5 Pin
thatraja23-Sep-10 2:02
professionalthatraja23-Sep-10 2:02 
GeneralCompression Pin
belzer8-Jul-10 14:44
Memberbelzer8-Jul-10 14:44 
GeneralInclude or exclude areas Pin
chinkuanyeh28-Jun-10 9:32
Memberchinkuanyeh28-Jun-10 9:32 
GeneralRe: Include or exclude areas Pin
John Underhill5-Jul-10 14:17
MemberJohn Underhill5-Jul-10 14:17 
GeneralAVIMakeCompressedStream // -- fails Pin
MU Jon Frost9-Jun-10 17:22
MemberMU Jon Frost9-Jun-10 17:22 
GeneralRe: AVIMakeCompressedStream // -- fails Pin
John Underhill10-Jun-10 2:18
MemberJohn Underhill10-Jun-10 2:18 
GeneralHidden electricity costs Pin
S.H.Bouwhuis24-May-10 21:51
MemberS.H.Bouwhuis24-May-10 21:51 
GeneralRe: Hidden electricity costs Pin
John Underhill25-May-10 4:15
MemberJohn Underhill25-May-10 4:15 
GeneralNew version 2.1 Pin
John Underhill17-May-10 11:24
MemberJohn Underhill17-May-10 11:24 
GeneralWhow Nice Pin
redspiderke17-May-10 6:51
Memberredspiderke17-May-10 6:51 
GeneralRe: Whow Nice Pin
John Underhill17-May-10 11:19
MemberJohn Underhill17-May-10 11:19 
QuestionNice aticle! 5 from me. Pin
BryanWilkins17-May-10 5:28
professionalBryanWilkins17-May-10 5:28 
AnswerRe: Nice aticle! 5 from me. Pin
John Underhill17-May-10 5:42
MemberJohn Underhill17-May-10 5:42 
GeneralNice article Pin
Jitendra Zaa17-May-10 2:44
MemberJitendra Zaa17-May-10 2:44 
GeneralRe: Nice article Pin
John Underhill17-May-10 5:42
MemberJohn Underhill17-May-10 5:42 
GeneralGreat Article.. Pin
Gaurav Dudeja India16-May-10 19:32
MemberGaurav Dudeja India16-May-10 19:32 
GeneralRe: Great Article.. Pin
John Underhill17-May-10 5:43
MemberJohn Underhill17-May-10 5:43 
GeneralLooks Interesting .... Pin
Garth J Lancaster16-May-10 12:12
professionalGarth J Lancaster16-May-10 12:12 
GeneralRe: Looks Interesting .... Pin
John Underhill16-May-10 12:21
MemberJohn Underhill16-May-10 12:21 
GeneralRe: Looks Interesting .... Pin
Garth J Lancaster16-May-10 12:24
professionalGarth J Lancaster16-May-10 12:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.