[Brian Theado] - 01Jan04 - After writing the [babbleback machine] program, my daughter begged me daily for more than a month to play. Her interest is finally starting to wane. She still enjoys playing with it if I turn it on. Along the way, I got the idea of making a video camera version of the same program. I have a digital camera with Firewire (aka iLink, aka IEEE1394) connectivity. I searched to no avail for a program or set of programs that would make doing this easy on Microsoft Windows. I turned my search to Linux and hit the jackpot. Linux has a command-line program called dvgrab [http://kino.schirmacher.de] that makes it simple to capture data from a digital video camera. A program called xine [http://xine.sourceforge.net] will playback video files. Tcl is a great language to glue the two applications together. --- Update 16Sep04 My now three-year-old daughter still loves playing with this game. She asks for it on a weekly basis. My first version of this (see bottom of the page) stored the video in avi files. Every period, a new avi file was created and the old one was sent to xine for playback. At the moment of swapping files, there was a slight jump in the playback. Newer versions of dvgrab and xine support streaming raw dv formatted data via stdout and stdin and I rewrote the code to take advantage of these features. With no file switching to deal with, the playback discontinuity has disappeared. In order to insert a delay in data stream, I make use of fifo channels from the [memchan] package. One disadvantage of the new version over the old version is that is uses RAM to buffer the memory instead of files on disk. For me, since I run this in Knoppix which uses a ramdisk for the home directory, it is no change. One advantage of the new version is that only one line of code is specific to using dvgrab/firewire and xine. Change that line of code and the same continuous-playback-with-delay can work for other media streams such as USB webcams. I'd love to see this program work using a cheap webcam or on a Windows platform. If anyone knows how to do this, then please let me know. I'm using dvgrab 1.5 and libxine-1-rc5-1/xine-ui-0.99.1-1 from Knoppix 3.6-2004-08-16 to run this script. ---- '''Version 2''' - stream based # fcopy completion callback proc copyComplete {fd1 fd2 args} { puts "Copy complete: $fd1 $fd2 $args" close $fd2 set ::copyComplete$fd2 1 } # Read data from file1 and buffer it for delay milliseconds and then start copying # to file2 proc bufferingFifoWithDelay {file1 file2 delay} { package require Memchan # Open the in memory fifo channels and the input file set fifos [fifo2] set input [open $file1] foreach f [concat $fifos $input] {fconfigure $f -translation binary} # Initiate asynchronous copying of data from input into one side of the fifo fcopy $input [lindex $fifos 0] -command [list copyComplete $input [lindex $fifos 0]] # Open the output file and after a delay start copying from the other end of # the fifo into the output file set output [open $file2 w] fconfigure $output -translation binary after $delay "fcopy [lindex $fifos 1] $output -command [list [list copyComplete [lindex $fifos 1] $output]]" return [concat $input $fifos $output] } # Default delay is 5000 ms and can be overridden on the command-line if {[llength $argv] == 0} { set delay 5000 } else { set delay [lindex $argv 0] } # The "-" causes dvgrab to not save to an avi file and it automatically # spews rawdv to stdout if someone is reading stdout set fds [bufferingFifoWithDelay "|sudo dvgrab -" "|xine --fullscreen --hide-gui stdin://#demux:rawdv" $delay] # Enter the event loop vwait copyComplete[lindex $fds end] --- '''Version 1''' - file swapping based Note: this code only workds with versions of dvgrab older than 1.3 as the newer versions of dvgrab have a differnt stdout messages format. Here's the sourcecode for the script #!/usr/bin/tclsh proc queueFile dv { # Read the line of output from dvgrab and extract the filename set line [gets $dv] puts $line regexp {(.+):} $line -> file # Queue the file for playback using the existing xine session exec xine -S mrl=$file # Delete the file when it is done playing (hopefully it will be done) variable delay after [expr ($delay * 1000) + 100] [list file delete $file] } # Launch xine set xinePid [exec xine --hide-gui &] # Launch dvgrab. Configure it to split off a new file every $delay seconds set delay 2 set framesPerSecond 30 ;# NTSC format set framesToGrab [expr $delay * $framesPerSecond] set dv [open "|dvgrab --frames $framesToGrab --format dv2 --autosplit cinemaback"] # dvgrab outputs a line with the file name each time it splits off a new file fileevent $dv readable [list queueFile $dv] vwait forever If you don't have Linux installed and you want to try this script out, then check out Knoppix (http://www.knoppix.org). It is a live CD distribution of Linux that will run directly from a CD with no installation necessary. Just download the iso image and burn it to a CD. It comes with firewire drivers, dvgrab, and xine all pre-installed. Knoppix 3.2 from June 2003 comes with a compatible version of dvgrab. To activate the firewire drivers, just execute: sudo insmod ieee1394 sudo insmod ohci1394 sudo insmod raw1394 Camera idiosyncrasies: My camera is a Panasonic PV-DV202 and I found that if it has a tape in it and it isn't recording, then it shuts off after a few minutes. It doesn't seem to recognize that data is being sent across the firewire cable. I work around this by removing the tape.