Flash on Linux Using Ming

From Chumby Wiki
Revision as of 08:28, 19 January 2008 by Wansti (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

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#Mixing_local_widgets_into_a_channel

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;
 
   }
 }