A Runtime Error

Perhaps you’re familiar with this image. How embarassing to launch an app only to find that it’s throwing up large, intrusive error windows!

What’s to be done? Well, you have two options:
  1. Write perfect code.
  2. Use Runtime Error Handling

Some day I’ll elaborate on the secrets of the first option(1, 2), but for the time being I’d like to talk about Runtime Error Correction and Handling.

Let me begin by explaining what a runtime error is. As compared to a Compile Error, which is caught on compilation, or a Logical Error, which is due to fuzzy logic on the part of the programmer, a Runtime Error is an error that occurrs in your code while it is executing.

Flash has several types of Runtime errors that are thrown at different times depending on the type of error that occurrs. As somebody who works with Flash every day, I can say with some confidence that the most important and common ones for you to worry about are TypeErrors, ReferenceErrors, and RangeErrors. You may also find yourself occasionally encountering SecurityErrors and SyntaxErrors, but for now we’ll just worry about the first three.

How do these errors occur? Let’s break it down one by one.

TypeErrors

Type errors generally occur when you improperly coerce the value of one variable to the type of some incompatible “other” variable. What does this mean? Here’s an example:

var mov = getChildByName("myMovieClip");
mov.gotoAndPlay(2);

The code above will throw an error because you’re implicitly (rather than explicitly) trying to coerce a DisplayObject into behaving like a MovieClip. What the hell am I talking about? Well, if you check the documentation for the “getChildByName” method on the MovieClip class, you’ll see that it returns a DisplayObject. What this means is that whenever you call this method without explicitly casting its return object, Flash is going to assume you’re just talking about a vanilla, plain-jane DisplayObject.

Here are two solutions:

var mov = getChildByName("myMovieClip") as MovieClip;

…or…

var mov = MovieClip(getChildByName("myMovieClip"));

Both lines of code do the same thing. For the sake of readability, I prefer the first method.

ReferenceErrors

Reference Errors occur when you try to access or set a property that doesn’t exist on a non-dynamic class. For people who are new to object oriented programming in AS3, this will happen for a while until you really appreciate the difference between a dynamic and a non-dynamic class. Let’s look at an example.

package {
     public class Foo() {
          public function Foo() {
               trace(this.bar);
          }
     }
}

The example above will throw a Reference Error because the class Foo doesn’t have a property named “bar.” I have two solutions.


package {
public class Foo() {
     public var bar:*;
          public function Foo() {
               trace(this.bar);
          }
     }
}

In the above example, we just made sure that the public class Foo does have a property named “bar.”

package {
     public dynamic class Foo() {
          public function Foo() {
               trace(this.bar);
          }
     }
}

In this second example, we made the public class Foo into a dynamic class. What this means is that we can refer to any property we want on Foo, and if it doesn’t exist Flash will create it for us automatically. This may sound like a very tempting proposition, but the first approach is most definitely preferred on this one, which is a point I will explain at a later date. For the time being, just take my word for it: Avoid making your classes dynamic if you can.

RangeErrors

A Range Error occurs when you attempt to refer to an index that doesn’t exist in an Array. For example:

var shitty_bands:Array = [ "Slipknot", "Linkin Park", "Insane Clown Posse"];
trace(shitty_bands[3]);

The code above will generate a range error because the shitty_bands array doesn’t have any entries at an index of 3. You’ve literally referred to an entry that is out of the range of the array, making this a pretty easy error to remember. To solve, you could…

var shitty_bands:Array = [ "Slipknot", "Linkin Park", "Insane Clown  Posse"];
trace(shitty_bands[shitty_bands.length-1]);

…use properties of the array to make sure that you don’t refer to entries outside of its range, which also saves you the trouble of actually needing to know the number of entries in the array at any given point (assuming you were just trying to grab the last item in the array), or you could…

var shitty_bands:Array = [ "Slipknot", "Linkin Park", "Insane Clown  Posse", "The Black Eyed Peas"];
trace(shitty_bands[3]);

…just add another shitty band to the array.

Admittedly, these are stop-gap solutions that all depend on what you’re actually trying to accomplish with your program. There is one final solution.

Explicit Error Handling

What do I mean by Explicit Error Handling? I mean that you anticipate when portions of your code may throw errors, and set up appropriate control structures to deal with them when they happen. There are two ways to do this, and the method you choose may vary depending on the type of error you anticipate and the amount of code you’re trying to control for. Let’s consider the first method.

Error Event Listeners

Many errors can be taken care of with simple event handlers. Security Errors and IOErrors, for example, have their own event classes that you can listen for.


package {

     import flash.net.*;

     import flash.events.*;

     public class Foo() {

          public function Foo() {

               var loader:URLLoader = new URLLoader();

               loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, _securityErrorHandle, false, 0, true);

               loader.addEventListener(IOErrorEvent.IO_ERROR, _ioErrorHandle, false, 0, true);

               loader.load(new URLRequest("data.xml"));

          }

     }

     private function _securityErrorHandle(e:SecurityErrorEvent):void {

          trace("SecurityError :: ",e.errorID);

     }

     private function _ioErrorHandle(e:IOErrorEvent):void {

          trace("IOError ::",e.errorID);

     }

}

Depending on how large or complex your application is this may be a good solution for you. I know that in some respects I find this easiest to understand as it runs on the existing Event metaphor that I’m accustomed to using for everything else in AS3.

The second method employs a construct which with, if you have done any programming in the past, you are probably familiar.

package {
     public class Foo() {
          public function Foo() {
               try {
                    trace(this.bar);
               } catch (e:ReferenceError {
                    trace("Reference Error!");
               } finally {
                    // do something else
               }
          }
     }
}

The Try…Catch…Finally construct exists in pretty much every programming language known to man. It’s also pretty simple to understand. The application “attempts” to do whatever is within the “try” statement. If an error occurs, it’s handled in the “catch” statement, and whatever was going to take place in the “try” statement just doesn’t happen. After these steps, the application does whatever is indicated in the “finally” statement. It doesn’t get much easier than that. This is also nice because it forces you to deal with errors at the site of their creation, and to be more thoughtful about where and why errors happen.

Categories: Actionscript 3ArticleBest PracticesFlashFlexTipsTutorial
Published: 03.31.10 :: No Comments »


I spent the last week or so developing a kiosk application for a client that had to prevent users from exiting the application using ctrl+alt+delete, alt+f4, or any other such method.

Because I had worked with it in the past for a similar project, I advised the client that we could use Northcode’s SWFStudio to lock the application down and to record registration data without requiring an internet connection. This should have all been very simple. Create the application, load up SWFStudio, and convert my final SWF to an EXE with all the parameters configured.

In practice things weren’t so simple. You wouldn’t know this unless you dug around, but SWFStudio 3.7 doesn’t play nicely with Windows 7, and for the $300 licensing fee you’d hope they would take the trouble to make this point more prominent. To give you an idea of this problem, I’d like to demonstrate the sequence of steps you need to complete to figure out why your perfectly functional kiosk craps out after you push it through SWFStudio.

Step 1

First, you have to go to Northcode’s website. When you get there, click on the “swf studio” link at the top of the page. Don’t click “blog” and whatever you do, don’t click “support.”

Step 2

Once you get to the “swf studio” page, click to continue reading the article on making your applications work with Windows 7. Don’t bother with the “Known Problems” link in the side bar, as even though they thought to post an article about the issue (separate from their blog and their support page no less), it’s not a problem they’re aware of.

Step 3

You’re almost done! You’ve found the document explaining how to fix your problems in Windows 7. Of course, there’s no patch or software update. You have to copy the grayed out text above into a panel in SWF Studio to get everything functioning properly.

What makes me even angrier about this is the text of the article. The summary, shown in step 2, contains the following text:

Windows 7 adds support for a new section in your application manifests called Compatibility and if you want your SWF Studio applications to behave properly on Windows 7 then you’d better pay attention!

They even use an exclamation mark! I’d better pay attention if I expect their $300 application to function correctly. That might even be ok if they displayed the information prominently on their homepage, or in any of the sections you’d expect it to be in. To give you an idea of how poorly placed this content is, as I was sitting down to write this post it took me 15 minutes digging around their site to find the document in question again.

For my own satisfaction, and for the sake of anybody else who runs into problems with this software, I’ve taken the following liberties:

  1. I’m offering this code to you below so there’s a second place to find it if anybody ever needs it.
  2. I’m offering this code for download so you can keep your own copy if need be.
  3. I’m recommending a slight redesign to Northcode’s home page.

The code looks like this.


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<assembly  xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

 <assemblyIdentity  version="1.0.0.0" processorArchitecture="X86" name="stub.exe"  type="win32" />

 <description>stub</description>

 <dependency>
 <dependentAssembly>
 <assemblyIdentity
 type="win32"
 name="Microsoft.Windows.Common-Controls"
 version="6.0.0.0"
 processorArchitecture="X86"
 publicKeyToken="6595b64144ccf1df"
 language="*" />
 </dependentAssembly>
 </dependency>

 <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
 <security>
 <requestedPrivileges>
 <requestedExecutionLevel  level="asInvoker" uiAccess="false"/>
 </requestedPrivileges>
 </security>
 </trustInfo>

 <compatibility  xmlns="urn:schemas-microsoft-com:compatibility.v1">
 <application>
 <!-- the ID below indicates the application supports Windows 7  -->
 <supportedOS  Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
 </application>
 </compatibility>

</assembly>

You can download a file with this information here: SWF Studio Manifest for Windows 7 Projects

And my suggestion for a redesign of Northcode’s homepage is below.

The Corrected Northcode.com!

Categories: ArticleBugsDownloadsSWF Studio
Tags:
Published: 03.27.10 :: 3 Comments »


Recently I spent some time setting up Red5 on my web server. If you’re familiar with the project, and if you’ve attempted to set it up yourself, you’re probably aware that this is no easy feat. The team behind Red5 is notorious, in my mind, for not maintaining their project page very well (at all), so many of the links that should direct you to helpful content don’t actually go anywhere.

Anyway, to make a long story short I did eventually get the bloody thing installed. How do I celebrate? With a demo for you to sink your teeth into?

Not yet.

Instead I spent a few minutes today customizing my Red5 welcome screen and the demos page associated with it. Allow me to present you with a before and after.

Before:

Original Welcome Screen

Original Samples Screen

After:

Welcome!

Welcome to Agitcraft Media Server

Samples

Check out the Sample Apps!

For the most part these are just simple modifications of the pages that are included in Red5 by default. In practice, they’ll only really be seen by me, but the little things count.

Categories: AnnouncementsRed5
Published: 03.26.10 :: No Comments »



Milky Ball

I’m inclined to disagree. So is Prashanth Kamalakanthan. He has a tumblog called “Flash is Dead” in which he highlights several examples of why it clearly is not.

Thanks to Frank for the link.

Categories: Links
Tags:
Published: 03.19.10 :: No Comments »


Big Spaceship labs just posted a great article on a unique problem they encountered while attempting to load content from external domains. They have a rundown of steps they took to solve the problem and the eventual solution they came to.

Check it out here.

Categories: Links
Published: 03.15.10 :: No Comments »



play clothtylophone

Originally uploaded by _syano

Flickr has given me the option of sharing a video I liked by blogging it.

If you can see this now, it’s only because the service really works. Cool stuff.

Oh, and the item depicted in the video is wonderful.

This is breaking my layout though. Hmm….

Categories: LinksVideo
Tags:
Published: :: No Comments »


Gesture Recognition

I’ve spent the last day or two reacquainting myself with what’s been done to achieve reliable gesture recognition in AS3. I have reviews of two different packages I tried, one of which is relatively new and one of which has been around for some time.

One note about all of the gesture recognition classes I’ve looked at is that they are direction-dependent. That is to say that if you’re attempting to capture the gesture corresponding to a vertical line, a stroke from top to bottom is not the same thing as a stroke from bottom to top. Furthermore, neither of those will necessarily be captured in a stroke from top to bottom to top. This all has to do with the algorithms being employed to detect gestures and attempts to make them run as efficiently as possible.

The first package I looked at was offered up by a Mr. Felix at bertiesbraum.de. Felix’s gesture recognizer consists of AS3 implementations of the “$1 Gesture Recognizer” and “ShortStraw Corner Finder” algorithms, which he has the decency to cite and link to (unlike me).

His post does a much better job of explaining basic usage of the classes than I care to at the moment, but what I will say is that I was unable to get the classes to function without false positives. This is likely because, as Felix notes, “The gestures are also rotation, position and scale invariant,” which is to say that a single stroke probably ends up being a single stroke, regardless of which direction it points. With more complex figures I was able, in the sample application Felix provides, to demonstrate direction dependence. In my case I’m trying to detect single strokes in distinct directions, and so it may be that these algorithms are over-engineered for my purposes.

The second package I looked into was posted in a short article at ByteArray.org by Didier Brun. I caught this post when it first came out (almost three years ago) and was very impressed with the concept but didn’t have any real use for it at the time. I toyed with it today and have been pleased with the results.

Initially Mr. Brun’s classes posed the same problem that most gesture recognition algorithms do: it was unable to recognize identical patterns if they proceeded in different directions. Additionally, all of the packages I’ve seen presume that the user will begin their gesture by pressing the mouse button down, and end the gesture by releasing it. I’m trying to detect whether or  not a user is shaking an object they’ve picked up in an up-and-down fashion, so it’s important to me to recognize sub-gestures within a larger “gesture.” If I depend solely on button presses and releases, the gesture that ends up being analyzed consists of tens of motions at the least.

I came up with a solution using Mr. Brun’s classes that allowed me to achieve my ends. Brun’s gesture recognition class offers a custom event that fires when capture begins and ends, when a match is made or not made, and while capture is taking place. The last of those was most important to me. I added a public property to his existing GestureEvent class. The modified class looks like this:

package com.foxaweb.ui.gesture {

	import flash.events.Event;

	public class GestureEvent extends Event {

		// ------------------------------------------------
		//
		// ---o static
		//
		// ------------------------------------------------

		public static const START_CAPTURE:String="startCapture";
		public static const STOP_CAPTURE:String="stopCapture";
		public static const CAPTURING:String="capturing";
		public static const GESTURE_MATCH:String="gestureMatch";
		public static const NO_MATCH:String="noMatch";

		// ------------------------------------------------
		//
		// ---o properties
		//
		// ------------------------------------------------

		public var datas:*;
		public var fiability:uint;
		public var moves:String;

		// ------------------------------------------------
		//
		// ---o constructor
		//
		// ------------------------------------------------

		public function GestureEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false){
			super (type,bubbles,cancelable);
		}

		// ------------------------------------------------
		//
		// ---o methods
		//
		// ------------------------------------------------

		public override function clone():Event{
			return new GestureEvent(type, bubbles, cancelable) as Event;
		}

	}
}

I also made a change to the MouseGesture class to make sure that “moves” were being attached to GestureEvents dispatched during the “CAPTURING” phase. The modified function looks like this:

protected function captureHandler(e:TimerEvent):void{

	// calcul dif
	var msx:int=mouseZone.mouseX;
	var msy:int=mouseZone.mouseY;

	var difx:int=msx-lastPoint.x;
	var dify:int=msy-lastPoint.y;
	var sqDist:Number=difx*difx+dify*dify;
	var sqPrec:Number=DEFAULT_PRECISION*DEFAULT_PRECISION;

	if (sqDist>sqPrec){
		points.push(new Point(msx,msy));
		addMove(difx,dify);
		lastPoint.x=msx;
		lastPoint.y=msy;

		if (msx<rect.minx)rect.minx=msx;
		if (msx>rect.maxx)rect.maxx=msx;
		if (msy<rect.miny)rect.miny=msy;
		if (msy>rect.maxy)rect.maxy=msy;
	}
	// event
	var evt:GestureEvent = new GestureEvent(GestureEvent.CAPTURING);
	evt.moves = moves.join("");
	dispatchEvent(evt);

	//dispatchEvent (new GestureEvent(GestureEvent.CAPTURING));

}

The final step was to deal with the entire set of move data in my application. I configured my instance of the MouseGesture class to handle GestureEvent.CAPTURING events and created the following function to deal with them.

private function _captureHandler(e:GestureEvent):void {
	var reShake:RegExp = /(62|26)/g;
	var shakes:int = e.moves.match(reShake).length;
	field_shakes.text = "Number of Shakes: " + shakes;
	if (shakes >= 12) {
		stage.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_UP));
		field_shakes.text = "Congratulations!";
	}
	trace(e.moves);
}

The important thing to note here is the regular expression being used. The strings “62″ and “26″ correspond to the output that would be expected from a vertical shake gesture in the MouseGesture class (respectively “up->down” and “down->up”). What the function does is scan the entire list of movements and look for instances in which the patterns I’m trying to match have occurred in sequence. For each occurrence of either pairing, we know that the user has successfully “shaken” the can. A single call fired to the “_captureHandler” function might have a “moves” list that looks like this…

0666662255222666666222566222266222266672226666122561

…in which each digit corresponds to one of 8 possible directions the user moved his mouse. If you count carefully, you’ll find 8 instances of either the sequence “62″ or the sequence “26.”

Ultimately Mr. Brun’s class ended up being more useful for the project that I’m working on, but I hope to see other implementations in the future that will allow for more complex gestures to be recognized.

Published: 03.11.10 :: No Comments »


Apparently the developers working on Adobe’s OSMF have just released Sprint 10. So much for my Sprint 9 based video player. I’m going to get to work on updating it to use the latest release.

Categories: AnnouncementsFrameworksOSMFSprint 10
Tags:
Published: 03.10.10 :: No Comments »


I’ve been working, over the last few weeks, with Adobe’s Open Source Media Framework. The OSMF is Adobe’s initiative to provide a standard set of tools and interfaces for deploying video content on the Flash Platform.

The framework is built loosely according to a MVC pattern, in which the Model consists of various MediaElements, the View consists of a MediaContainer, and the Controller consists of a non-displayable MediaPlayer class. As of its current release (Sprint 9), methods of implementation are so varied that it’s hard to find reliable documentation or concrete examples of how to use many of the components of the framework. This makes it difficult to work with so far, but the capabilities being planned and exposed for the project make it very exciting to jump in and start coding.

Today I connected to the project SVN, updated to the latest revision, and jumped back into developing a wrapper that I originally began planning for Sprint 8. I’ve implemented a very simple class based on the latest revision of Sprint 9 which I’m offering you today. I’m calling the project Vidiot to reflect my hope that it will be so easy to use, even an idiot will be able to display video in Flash.

The demo above uses the Vidiot class to play a sample streaming video hosted by Akamai. Layout and playback controls are separate from the Vidiot class. The simplest use case for Vidiot looks like this:

var vidiot:Vidiot = new Vidiot();
addChild(vidiot);
vidiot.load("video path");

At this stage, it doesn’t really get any more complicated than that. You can use Vidiot to play either progressive or streaming video (though thus far I’ve been unable to stream from Edgecast. Hmm….), and in theory this thing is also set up to play audio or still images as well, though I’ll have to test that out and probably update some of the code.

I hope to continue to release new versions of Vidiot and keep it up to date with the latest builds of OSMF. If all goes well you’ll see more posts about this in the future.

Download sample video player and Vidiot source code

UPDATE: Vidiot has been updated. Check out the most recent post.

Categories: APIDownloadsFlashOSMFVideoVidiot
Tags:
Published: 03.06.10 :: 3 Comments »


If you’ve been reading things around here recently, you may recall that I posted an entry filled with glowing praise for RichFLV. I had been aware of the application for some time (it was one of the first AIR apps I saw receiving significant praise/attention), but had only started using it several weeks prior in my own development efforts.

In the time since then, my company began making heavy use of RichFLV for a large project I’ve been developing. The project required tons of external video and animation, and I had decided that the best way to synchronize the two was to use FLV embedded cuepoints as controllers for external SWF content (FLV, SWF, cuepoint -> frame label). Because of the volume of video we’ve been dealing with (around 2gb), the idea of being able to dynamically modify cuepoints without having to rebuild video seemed like an obvious win for us.

To say the least, there have been complications. I have three complaints with RichFLV at this point. One of them is a minor inconvenience and the other two are potential deal breakers.


Really? No Native Drag and Drop?



The first problem is quite simple and amounts to more of an inattention to detail than anything. RichFLV doesn’t support native drag and drop for playing video files. It may sound like I’m nitpicking, but when you’re dealing with several hundred video files buried in a complex folder structure, having to go to the “file -> open” dialogue to change files becomes a quick annoyance.


Cuepoint Confusion?



The second problem is that, once in a while, RichFLV completely screws up your cuepoints. On the one hand, it will often duplicate cuepoints at incorrect time codes (see cue12, appearing twice, the first of which has the same timecode as cue 11), and on the other hand it frequently refuses to designate cuepoints correctly as event or navigation points (see the final cue12). Generally we give our cuepoints distinct, meaningful names so that when they fire we can respond to them intelligently. It’s easy to see how the problems highlighted above prevent that.


Funky Metadata?



The final problem has to do with the metadata that RichFLV generates. There’s a little bit of backstory required for this one.

At the same time that this project was starting, I and my colleagues had taken an interest in the Open Source Media Framework and had planned to build a new video player around it to use with projects in the future. The inclusion, specifically, of Parallel and Serial media elements built into OSMF seemed like a great fit for the needs of this project. We decided to proceed with development of our video player and to deploy it in this project as it reached a usable state.

It didn’t take long before we were having major problems (with our Video Player!). We were consistently unable to get the OSMF to play videos with embedded cuepoints, even though we’d seen plenty of examples of it doing just that. The specific error we were receiving was as follows:

Error #2044: Unhandled AsyncErrorEvent:. text=Error #2095: org.osmf.net.dynamicstreaming.DynamicNetStream was unable to invoke callback onMetaData. error=TypeError: Error #1034: Type Coercion failed: cannot convert Object@3ca86769 to Array.

You’ll notice that the framework was unable to correctly invoke it’s “onMetaData” handler. Generally when you deploy video in Flash, you first wait for metadata to be made available so you can scan it for important information about the file, and for information about cuepoints. When attempting to playback FLV files in which cuepoints had been embedded with RichFLV, we received this error every single time. In fact, it didn’t even matter if we went back and stripped all of the cuepoints from the video. Once RichFLV touched the metadata, the video was effectively “broken.” We struggled with this error for days before eventually dropping the idea of moving forward with OSMF. Instead we had to fall back on another (self-created but very outdated) video player to complete the project.

Now, I have little (if any) experience with generating or encoding video, but I was so frustrated by all of this that I spent some time today digging  through the flv file format specification. The first thing I noticed was that RichFLV was providing incorrect values for the CodecID property of the FLV file format (specifically 4 for On2 VP6 rather than 5 for On2VP6 with alpha). Furthermore, I discovered that if I reencoded my FLVs using Adobe Media Encoder (which should understand the FLV format) rather than RichFLV, all of my problems disappeared. Go figure.

None of the above is necessarily meant to dissuade you from using RichFLV if you find it useful. As far as I can tell, the original developer hasn’t released a new version of it in well over a year, and this thing has been around since AIR was still called Apollo. Hopefully these bugs will get more public attention and the developer will be prompted to update the app or disseminate the source code so somebody else can pick up development on what otherwise has been a great and useful application.

Categories: ArticleBugsFLVTipsVideo
Tags:
Published: 03.01.10 :: 4 Comments »