Windows Vista SideBar Gadget for AirLink Web Cam
I've got an AirLink101 AIC250 Network Camera in the baby's room. I wrote about it when he was younger in a Coding4Fun article on Motion Detection. He's been sleeping through the night since he was about six months, so even though my Webcam application was a ClickOnce App, I got lazy, and didn't used it for several months. However, we just weaned Z and I'm now in charge of putting him to bed.
Putting a baby to sleep is a subtle art, not unlike defusing a bomb or tiptoeing through minefield. Sometimes he goes down well, other times, less so. We started using the Webcam again lately, but I wasn't really digging the application and the way that it integrated into our life. My wife and I like to check our email just after we put the baby down, and I like to watch the baby at the same time. The app was getting in the way, or it'd take up the second monitor, and while I could have fixed it, I realized that I really wanted to see Z in the Vista Sidebar.
I started digging into the various "Gadget APIs." A Windows Sidebar Gadget is just a tiny web page or pages, along with javascript, that runs in a specific secure host and has automatic access to the Vista Sidebar DOM as JavaScript Objects. If you want to access storage bags for settings or whatever, it's all javascript and bailing wire. MacGyver would love it. I, on the other hand, don't.
Well, that's not true. I mean, it's brilliant, really, all the Gadget APIs are very accessible to the Javascripty. I'm just not very Javascripty. The lack of a really good debugger has me using System.Debug.outputstring and dbgview.exe from Sysinternals. It's lovely, really, but "got here" debugging sucks.
Got here.
Got here.
Got here.
Anyway. Turns out that the AirLInk101 not only has a MJPEG (That's MotionJPEG, not MPEG, for those who are paying attention) stream, but there's as a single JPEG endpoint like this: http://babyroom/IMAGE.JPG?cidx=20071200134234234 where you append a random number on the end to make sure the browser doesn't cache.
Now, I could do this Sidebar a number of ways. I could:
- Use the Java Applet or the ActiveX control that comes with the camera and host it inside the Sidebar. However, you'd have to log into the admin console once, first, to authenticate. Not to mention the "meh" of having that stuff running inside the Sidebar process.
- Use Ajax/XMLHttp ala Flickr to get the image all async like and assign it to an image.
- Use XBAP or WPF/E to do the work for me...this was beyond my patience for new technology as I just wanted to spend and hour.
However, I'm old school. Smells like a job for "setInterval" to me. Hunting for Sidebar Samples got me to Microsoft Gadgets.com which is WAY old, but the Tutorial was useful. Interestingly the stuff that OdeToCode did was WAY clearer and more elegant, but I ended up using the stuff from the tutorial because it supported the many states that a Sidebar gadget can be in:
- Docked
- Docked, with a Flyout
- Undocked and large (via a Setting)
- Undocked and small (via a Setting)
I used the bare bones Virtual Earth sample to start with. Without getting to intense on the details, as you can just look at the code, I added a setting for the Camera Server that gets pulled out of the Gadget settings State Bag.
1: function procGadgetCore()
2: {
3: var serverName = System.Gadget.Settings.read("CameraServer");
4: if (serverName == '')
5: {
6: serverName = "babyroom";
7: }
8: gCameraServerURL = "http://" + serverName + "/image.jpg";
9:
10: UpdateGadget();
11:
12: startTimer();
13: }
It's my gadget, I use my camera's name as the default. The gadget can be many sizes, so I just resize the image as the gadget changes. I also append the unique-enough number to prevent caching.
1: function UpdateGadget()
2: {
3: var now = new Date();
4: imgCamera.src = gCameraServerURL + '?cidx=' + now.getTime();
5: imgCamera.style.width = gadgetContentFrame.style.width;
6: imgCamera.style.height = gadgetContentFrame.style.height;
7: System.Debug.outputString("Update Gadget" + imgCamera.src);
8: }
StartTimer() just does
1: function startTimer()
2: {
3: gTimerID = setInterval(UpdateGadget, gInterval);
4: }
I need to add the interval as a modifiable setting. Right now it's set to a half-second. Certainly less than the 10fps I get with the Webcam ClickOnce app, but I'm really just looking to see that he's OK, and 2fps fine for that and the CPU usage is negligible.
None of this matters to you if you don't have a Webcam like this, but here's the craptastical source. A gadget file is just a ZIP file, FYI. When you double-click it, Vista will ask install it and it'll show up in
%userprofile%\AppData\Local\Microsoft\Windows Sidebar\Gadgets
You can get there by pasting that into Start|Run. Enjoy. Take a look at these places that helped me in this little project:
- Gadget Corner - The SideBar Team Blog
- K. Scott Allen's Ode to Code - Developing SideBar Gadgets
- Sean Alexander and others on Channel9 talking about the SideBar 18 months ago
- XBAP, IFrames in the SideBar
- MicrosoftGadgets.com - Woefully out of date (as of 20-Jan-07), but useful info
- Sidebar Gadget Tutorial - This is what I ended up REALLY using...I took the "EmptyShell" gadget and went from there.
Night night.
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
About Newsletter
-Matt
I just need one of this to put on my Lego MXT and then remote the Lego from Vb.Net with camera support :D; all in a Vista Gadget !!!
Bye from Spain
Comments are closed.
I have the same camera and stuck it up a tree outside during our remodel so I could a) watch the contractors from my office and b) snag a jpg every 15 seconds which I eventually turned into a motion-stop movie of the 2 story addition being framed.
Inside the house I have wire everywhere and wireless coverage so I was going to go with a leviton camera (We use leviton for the switches and lights) which can be fed into an rg6 feed as a single channel or hooked into a sequencer.
This might be a better option though. I plan on being able to bring the server's desktop up on any tv by taking it's output as one of the inputs to an audio authority 6x6 video matrix. That also supports ir back to the source so I can use a Windows MC remote to control the server. Given I'm buying the Audio Authority gear anyway this removes all the cost of the leviton camera and rf injector/sequencer.
anyway - nice project!