Flash on Linux Using Ming

This page describes how to use ming to build chumby-executable SWF files on Linux. It is intended as a resource for Linux programmers who wish to build their own webcams for Chumby, but who don't necessarily want to learn Flash.

Overview: Terminology
Flash developers talk about FlashDevelop and .fla files and SWF. FlashDevelop is a Windows-only thing. .fla files are some sort of binary format, not ASCII. Perhaps they include embedded images and buttons and other Flash stuff. SWF seems to be a compiled format. It is what Chumby uses.

The base Flash language seems to be called ActionScript. This page describes how to compile ActionScript into a .SWF file.

Grab and build Ming
Left as an exercise for the reader: your Linux distro might already have it, or you can download it from ming.sourceforge.net. You don't need to install it: I don't plan to use Flash often, so I just untar'ed the tarball, ./configure, make, and created a subdirectory right there for my own work.

Get your webcam code
Ming doesn't completely grok the webcam examples posted in other forums. However, the sample source at the bottom of this page works for me.

Compile it using makeswf
The makeswf tool included with ming will convert ActionScript to SWF:

$ pwd /home/.../src/ming/ming-0.4.0.beta5/mypersonalcode $ ../util/makeswf -r 12 -s 320x240 -v 8 mywebcam.as

The options are:

-r 12       frame rate -s 320x240  image width and height -v 8        Flash version

I don't know if all of those are necessary. They work for me, so I'm not interested in fiddling with them.

Send to Chumby
Use the chumby.com upload form, or see Chumby_tricks

Update this page
If anything on this page is wrong or misleading, or important steps are missing, please update this page.

Sample Webcam
////////////////////////////////// // BEGIN user-customizable section // URL of the webcam. Note that Chumby does not handle PNG! url = " http://your.webcam.tld/foo.jpg "; // Refresh delay in microseconds, e.g. 1000 = 1 second. delay = 1000; // character to use for adding form elements to the URL: // //  If URL includes a question mark, set this to '&' (ampersand) // If URL does not include a question mark (typical case), set it to '?' form_join = '?'; // END  user-customizable section ////////////////////////////////// // Create some initial empty images. I think the Flash engine will // loop through these as an animation sequence. createEmptyMovieClip("image0",0); createEmptyMovieClip("image1",1); createEmptyMovieClip("image2",2); // For keeping track of the currently-displayed image? index=0; // Current time (in microseconds), and timestamp of the previous refresh. now = 0; then = 0; // ??? I assume this gets called every time the image switches? // In any case, this is a NOP until the refresh delay has elapsed. this.onEnterFrame = function { var date = new Date; now = date.getTime; // Has our refresh delay elapsed? if (now - then > delay) { // Yes. Fetch a new remote image, and reset the timestamp doLoadImage; then = now; } };  // Fetch new image from remote function doLoadImage { // Starting with current index (0, 1, or 2), get names of image thingies var name0 = 'image'+(index%3); var name1 = 'image'+((index+1)%3); var name2 = 'image'+((index+2)%3); var m0 = eval(name0); var m1 = eval(name1); var m2 = eval(name2); // Some sort of image rotation? m0.swapDepths(0); m1.swapDepths(1); m2.removeMovieClip; // throw away the oldest one createEmptyMovieClip(name2,2); // make a new one m2 = eval(name2); m2.loadMovie(url + form_join + now); // load image into it     index = (index+1)%3; }

Sample Webcam (modified for MTASC/SWFMILL)
Since the webcam example above didn't work for me (especially the "eval" operator seemed to be troublesome), here is an updated version. I used an array for the images to get rid of eval and put it all into a class called "WebCam" which you can either call by adding a "main" method or, if you are using swfmill, setting the XML file accordingly - I created an SWF file following this tutorial).

class WebCam extends MovieClip { var url = " http://url.of.webcam.tld/current_frame.jpg "; var delay = 1000; // For keeping track of the currently-displayed image var index=0; // Current time (in microseconds), and timestamp of the previous refresh. var now = 0; var then = 0; //Array for camera images (i.e. instances of MovieClip) var mc:Array; //Class Constructor/Entry Point function WebCam { mc = new Array; mc[0] = createEmptyMovieClip("cam0",1); mc[1] = createEmptyMovieClip("cam1",2); mc[2] = createEmptyMovieClip("cam2",3); }   // Called on each frame function onEnterFrame { var date = new Date; now = date.getTime; // Has our refresh delay elapsed? if (now - then > delay) { // Yes. Fetch a new remote image, and reset the timestamp doLoadImage; then = now; }   };    // Fetch new image from remote function doLoadImage { mc[(index+1)%3].swapDepths(1); mc[(index+2)%3].swapDepths(2); mc[index].createEmptyMovieClip("cam"+index,3); //The webcam I wrote this for delivers 640x480 images - //scaling it down to 320x240 to make it viewable on the Chumby mc[index]._xscale = 50; mc[index]._yscale = 50; //load image - the url requires some kind of random seed added to it, so I just use the current timestamp mc[index].loadMovie(url + "?rand=" + now); index = (index+1)%3; } }