The following script is a pure python AVI file reader and (almost)writer.
Download here: avi.py and you'll also need wchunk.py to save files.
Currently it only reads (and sort of writes) uncompressed and MS-RLE compressed files but hopefully someone will write some plugins to extend it (see below). The structure of the code has been modelled on the wave.py module that comes with python2.4 but has made extensive use of the chunk and struct modules to tidy the code. The chunk module only has the facility for reading chunks so I've created it's ugly sister, wchunk.py, to allow a tidy avi writing module.
The script avitest.py will load an avi (first argument or default), display it's complete chunk structure and then will attempt to display the image in a pygame window. If this succeeds the image will appear and the user may scroll through the frames using the left and right arrow keys. If the ESC key is pressed, or if pygame is not installed, the image will be loaded through a PIL image and displayed using the Tkinter gui. Obviously both PIL and Tkinter modules must be installed. While PIL and Tkinter seem to be standard on many Linux Python distributions, the ImageTk class in PIL is often missing, so you may need to donwload a later version of PIL. If you need an avi to try, there is a file called clock.avi in the windows directory on XP installations.
The script aviwritetest.py uses pygame to show a short animation and each frame is saved as it is shown to test.avi in the current directory. The resulting avi is then reloaded and shown in a Tkinter view. If a --rle option is used, the resulting avi file will use MSRLE (microsoft Run Length Encoding) compression as used in the clock.avi (previously mentioned). [NOTE: Currently RLE files can be written and reread with the AviRead class, but I have found no other viewer which will work - so obviously I've got something wrong. Files written uncompressed can be read by VirtualDub and Windows Media Player but not by some others.] If no option is used then the avi will be uncompressed. Both forms are lossless, but the RLE option will only work where the avi contains fewer than 256 colours and will acheive little compression for photo type images (similar to GIF in that respect).
Plug-ins for other compressions are possible - see the rle_unpack and rle_pack functions as examples - and are easily registered through avi.register_comp_name(), avi.register_comp_unpack() and avi.register_comp_pack(). I intend to write a special compression system using keyframes (lossy) and uncompressed areas of interest (lossless) for motion analysis where the area(s) of interest are small in comparison to the overall image. This should be useful for tracking insects (or even people in CCTV footage) where archival of footage is required before analysis. Any suggestions here would be most welcome (send to robert dot parker at anu dot edu dot au with AVI included in heading :)
A conversion filter can also be called automatically. For normal use, as seen in avitest.py, a swap_flip_rb filter is required to swap the red and blue bytes in the data so that the image is converted to standard packed RGB data. The conversion filter is not stacked as I believe most users will use this code in conjunction with the python imaging library (PIL) or similar, which have much more advanced filtering systems.
As noted above, the current avi reader leaves images upside down. Inversion is not hard but the python imaging library (PIL) can probably do the job faster. The avitest.py code shows that the avi data can be easily loaded into a PIL library with both the frame inversion and RB swap happening automatically (as coded into the Tile description).
Alternatively, it seemed like a good idea to write a proper PIL plugin to achieve the loading transparently.
At the moment this only works for uncompressed data. If some brave sole would like to extend this to other compression systems - it's all yours - uncompressed is fine for me at the moment.
The pilaviview.py script is an extension of the standard pilview.py script that registers the AviPlugIn. As with pilview, Tkinter is used to display the image, but this time the mouse left and right buttons may be used to step through the animation.
The pilaviwrite.py script loads an existing animation (such as an animated gif - you can use the bird.gif used on this page) and displays it in a Tkinter window. As the image is stepped using the mouse buttons, the image is saved to an uncompressed avi. For some reason, that the numerous GIF experts might appreciate, the GIF example I used (created by my daughter using photoshop animator) doesn't display correctly using the PIL GIF plugin and so the defects are reliably reproduced on the resulting avi.
I'll keep an eye on the PIL mailing list to see if anyone makes some improvements.
Early 2008 -
Users of my Matlab script, DigiLite (a manual digitisation of animal movements program), were having difficulties using this script with the various platforms, operating systems and Matlab versions used. I'd made a small previous attempt at using Java to create a similar program but the java windowing system seems to have irregularities that prevented a mouse position being consistant. This was probably not Java's fault but in the meantime I have discovered Python and have become addicted - not because Python is a better language, for it's loose type encourages some very bad habits - I like Python because it is SO quick to develop with. Porting my program to python, an opensource multiplatform scripting interpreter, seems a obvious solution to my users problems. I wanted to avoid using any compiled code which might create platform or installation problems and loading speed isn't a big issue - we're analysing frame by frame. Googling and looking back in the PIL archives as far back as May 2005 (it would be nice if they had a search routine) and the only likely candidates are pymedia by Fabrice Bellard and pyvideo by Riccardo Trocca. While both are more advanced than my final result, neither fill the pure python requirment.
9th April 2008 -
Began converting wave.py into avi.py using an old avi interpreter I'd written in C++ many years before and I also had a peek in the avidec.c code from pymedia (GPL copyright) by Fabrice Bellard. In about 4 hours I have a working python decoder - it takes another two weeks to cross the I's and dot the T's.
22nd April 2008 -
released version 1.0 on ~rekrap/microde site.
23rd April 2008 -
realised I'd left file choice out of pilaviwrite.py - so version 1.0.1
The aviwrite class produces uncompressed files compatible with VirtualDub and WindowsMediaPlayer but not some other media players. This is not unusual as some media players cant read files produced by VirtualDub either.
The aviwrite class produces RLE compressed files that are only compatible with the aviread class.
I don't know what all of the values in the avih header represent so aviwrite is only taking a stab at the correct values to use.