In 1995, the rage on the Internet was Netscape. They had just released Netscape 1.1, and it shipped with a new feature called "server-push". The guys at Netscape applied a concept from email (MIME type: multipart/mixed from mail attachments) and created multipart/mixed-replace. The idea was that sometimes you don't want people to download your web page, and have it remain on the screen-- sometimes you want the content to be refreshed, when and if the server chooses, and replace what was pushed a moment before.
I recall opening up Photoshop, creating several layers, and exporting GIFs that would get refreshed, and writing some CGI programs that would use this new mime type to display, what were in effect, server-driven animated GIFs. On the server side, you had to convince httpd (now apache) not to server-parse the response to the client... Since you, the programmer, had to decide what content to push to the client, having the server compute the mime type (is it a JPEG? A GIF? A HTML document?) or the content length (is this GIF larger or smaller than the one before it?) by parsing the content wouldn't work. So, a convention was born to precede any such scripts with "nph-", meaning, "let me tell the client what kind of file and how big it is..."
I just finished a project that incorporates this technology, but didn't realize that I'd be brushing up on this technique I first learned 13 years ago.
With a baby on the way, I wanted a baby-monitor I could check even when I was back at work. Most off-the-shelf baby monitors use limited range 900Mhz wireless spectrum with no Internet capabilities. Instead, I got a couple of Panasonic pan/tilt/zoom webcams, and to save $80/unit, I also got some Panasonic powerline adapters so I didn't have to buy the more expensive 802.11g versions. The adapters allow me to avoid inconvenient wiring, and keep the video IP traffic off my wireless network.
The cameras have a live video feature, which I didn't really think much about how it worked... It worked just fine in Safari and Firefox, and that's all that mattered. But live video is limited-- you can't see what activity has taken place throughout the day. Well it turns out the cameras have security features, allowing me to upload JPG still captures from the cameras when their motion detectors are tripped.
But the problem was, each time the sensor is tripped several dozen images would get uploaded to a remote directory, and I'd have to manually go through them one at a time.
It was neat, however, to be out and about, and to be able to pull up my iPhone and see who's been at my front door, or if my cats have been jumping into the crib...
The first incarnation of this project was simply an apache directory-index. Click the file, see the still, click back, click another file... Repeat ad nauseam.
So I thought, hmm, perhaps I can build a file manager and use some software to seam the images into an mpeg movie, or motion-jpeg. Group the images by hour of day, and provide a "delete" function so that I don't have thousands of images piling up...
Then the thought hit me to use server-push (by now you probably saw this coming), and as I did a little tcpdump (network packet sniffing) analysis, I realized that this is the exact same thing that the camera's firmware is doing for any browsers monitoring the "video" feed...
After a little web coding (1455 bytes to be exact-- I'll post it if anyone is interested), I wrote a simple script that lets me browse all the events that my camera has captured and uploaded to the Internet, view them in equivalent video quality as the camera's built-in server, and when I'm done, delete the batch of files representing that video.
But best of all, MobileSafari.app (the browser on the iPhone) can handle multipart/mixed-replace content!
Mon, 09 Jun 2008
My blog covers topics I find of interest or worth sharing. I tend to cover topics around software development, Internet, or personal interests like music, photography or Disney.
- June 2024 (1)
- March 2021 (1)
- October 2020 (1)
- September 2020 (3)
- September 2019 (1)
- April 2018 (1)
- January 2018 (1)
- October 2017 (2)
- January 2017 (2)
- December 2016 (1)
- November 2014 (1)
- February 2014 (1)
- October 2013 (1)
- August 2013 (1)
- July 2013 (1)
- June 2013 (1)
- December 2012 (1)
- October 2012 (1)
- May 2012 (1)
- April 2012 (6)
- January 2012 (1)
- October 2011 (1)
- September 2011 (1)
- August 2011 (3)
- July 2011 (1)
- June 2011 (1)
- May 2011 (2)
- February 2011 (1)
- January 2011 (1)
- December 2010 (1)
- September 2010 (4)
- August 2010 (2)
- July 2010 (1)
- June 2010 (1)
- May 2010 (2)
- March 2010 (1)
- February 2010 (1)
- January 2010 (5)
- December 2009 (3)
- November 2009 (3)
- October 2009 (7)
- September 2009 (7)
- August 2009 (6)
- July 2009 (2)
- June 2009 (4)
- May 2009 (5)
- April 2009 (7)
- February 2009 (1)
- January 2009 (3)
- December 2008 (4)
- November 2008 (2)
- October 2008 (2)
- September 2008 (7)
- August 2008 (11)
- July 2008 (1)
- June 2008 (4)
- May 2008 (5)
- April 2008 (8)
- March 2008 (9)
- February 2008 (1)
- January 2008 (3)
- December 2007 (3)
- November 2007 (3)
- October 2007 (10)
- September 2007 (8)
- August 2007 (2)
- July 2007 (1)
- June 2007 (14)
- May 2007 (8)
- April 2007 (5)
- March 2007 (4)
- January 2007 (4)
- December 2006 (2)
- November 2006 (1)
- October 2006 (1)
- May 2006 (1)
- March 2006 (3)
- January 2006 (7)
- December 2005 (1)
- November 2005 (1)
- October 2005 (12)
- August 2005 (6)
- July 2005 (5)