Joined: 04 Jan 2008
|Posted: Mon Apr 28, 2008 3:03 pm Post subject: Experimental: Network Camera Plugin for PyTivo
|Experimental network camera plugin for pyTivo
I've been tinkering with a network camera. I thought it would be cool to display the images from the network camera "live" on my Tivo, so I decided to develop a network camera plugin for pyTivo. I only have one network camera to play with so support is limited to that camera.
I'd describe my programming skills with Python at a novice level. I'm still learning Python so if you delve into the code, I'm sure you will find better python-esque ways of accomplishing tasks. I'm sorry to say that there is some Windows specific code. Portability was not high on my list of program requirements because I believe this to be a very narrow field of interest.
IP Camera - Dlink DCS-G900. It's cheap, old technology and toy-like. Video quality is fair, poor in low light. This camera supports MJPEG which streams JPEG images. Newer, better and more expensive cameras support MP4 or H.264 streams but that is a project for another day. There is a lot of variability among manufacturers on communication protocols so I'd expect rework for other network cameras.
What I've done so far:
ipcam.py is a Python program to communicate with the Dlink DCS-G900 camera. The program takes images from a network camera or directory of JPGs and saves the JPG images into a directory and/or send them to stdout. The idea was to take the stdout and pipe that as input into ffmpeg. The directory support of images was added for debug purposes so I could work on the program while I didn't have access to the network camera.
Scouring the web and playing around with ffmpeg, I figured out how to convert JPGs into a video file with either of the following commands:
cat *.jpg | ffmpeg -vcodec mjpeg -f image2pipe -i - -y -target ntsc-dvd tst.mpg
ipcam.py | ffmpeg -vcodec mjpeg -f image2pipe -i - -y -target ntsc-dvd tst.mpg
Then I made sure that the resulting mpg would play on my Tivo, which it did. At 640x320 resolution on the ip camera, I get between 6-9 JPGs per second on a lightly loaded wireless network.
I wanted a flexible configuration method for the program so it accepts .conf file configuration parameters as well as command line options. Command line options take precedence over .conf file options.
Generating 6-9 images per second gobbles up storage at a significiant rate. If I wanted to keep multiple days of recordings, I was looking at approximately 28-30GB / 12 hour recording period. I found some simple motion detection code on the web and modified it to increase the processing speed while hopfully retaining it's ability to detect motion. My typical daily recording file is in the 1-2GB range. I also found some python code, Sun.py, to calculate sunrise and sunset which I then incorporated into the program since my network camera is pointed out my front window.
I implemented a buffering system to retain a configurable number of seconds of images prior to the motion detection event as well as continuing to save images for a configurable number of seconds of images after motion is detected. I spent a lot of time tuning this code to balance the tradeoffs betweeen image latency and saving the images to disk. Finally, I found some more code on the web, imprint.py, which allowed me to timestamp each image.
Error recovery is not robust and needs work however the program works very well in my environment.
I cloned (mid to late March drop) then hacked the video plugin for pyTivo to create a new plugin called netcam. Hacked is the key word here as I applied mostly brute force to get the desired results. The netcam plugin is a superset of the video plugin as it handles both video files and network cameras.
Typical pyTivo.conf file entry for the netcam plugin looks like the following:
The netcam plugin looks for a different file type when communicating to the network camera. Strangely enough, I decided to use .conf files for the network camera plugin. These .conf files are then special cased by the netcam plugin and transcode.py. The .conf file name is what is displayed on the NPL of the Tivo and contains the configuration file for the ipcam.py program and are passed as input. The duration of the how long to record is contained within the .conf file. I got the netcam plugin to work on my Tivo HD, however there are issues.
Problem areas in the netcam plugin:
Piping data between subprocesses proved to be elusive for me on a Windows platform. What I was hoping would work in Python did not work at all. I tried lots of variations, and searched the web and newsgroups. What I wound up with was a Windows specific implementation of creating a batch file, and then executing the batch file.
Typical batch file contents:
".\plugins\netcam\ipcam.py" -c "c:\DCSG900\live300.conf" | "c:\ntbin\ffmpeg.exe" -r 10 -vcodec mjpeg -f image2pipe -i - -vcodec mpeg2video -r 29.97 -b 8192k -maxrate 17408k -bufsize 1024k -comment pyTivo.py -ab 384k -ar 48000 -acodec ac3 -f vob -
Passing file paths with spaces in them and having the right quoting is messed up. I worked around the issue by dropping the batch file into c:\temp which makes the c:\temp directory a dependancy. I haven't gone back to re-examine it.
FPS and Duration: Trying to estimate FPS, estimating file size for Tivo, and having the actual duration align have been very difficult to date. Actual FPS from the network camera can vary based on load of the network which effects file size. Also, I hard coded an input rate of 10 FPS into ffmpeg, and after doing that, I needed to hard code an output rate for FPS at 29.97 or else ffmpeg would complain. Duration does not quite work right as I can record 5 minutes of video on the netcam and it shows up on the Tivo as a partial recording in the 3-4 minute range.
From an experiment standpoint, I was able to complete what I set out to do. I can play "live" data from my network camera on my Tivo, however I don't think I'm going to use the netcam plugin much. I say "live" because there is an inherent delay in getting images from the network camera to the tivo. Also, the slower framerate from the network camera makes the TiVo pause when it catches up to the network camera, so constantly hitting play gets old quick.
I don't plan to continue development or enhance the network camera plugin any further. I just wanted to see if I could do it. I do plan to leave one netcam .conf around with a 2 minute configuration if I want to pop over and view the network camera "live". What is a better solution for me is to run the ipcam.py program with motion detection enabled from a scheduler to create daily mpg files that I can download via pytivo and view on my Tivo. I've included a batch file, daily.bat, which is what I run daily from the scheduler. It uses a program called forfiles that I found on the net, which I use to delete recordings older than two weeks old. The batch file also launches ipcam.py and pipes the output to ffmpeg.
ipcam.conf.dist is a sample configuration .conf file with comments about each of the supported parameters.