Sep

24

Has the compiler been updated in Flash CS4?

By scott

The majority of the time I use MXMLC and COMPC to compile my work via ANT tasks. Most of my work is Actionscript only projects so I rarely use the Flash IDE compiler. 

Once in a while I find myself in the Flash IDE, mainly because I am working with an artists files, or I need to set up something on the timeline with document classes, or templated swfs that designers can base their work on. What I hate is the lack of compiler options in the IDE. Why can’t some of the command line compile options be available in the IDE?. Simple options like -load-externs, -link-report, externs, -external-library-path, -include-libraries, -includes, -library-path, -runtime-shared-libraries, and -source-path (to name a few).

With CS3 you can place a swc in the same directory as the FLA and use that for compile time checking and excluding classes in the compiled swf but this doesn’t work in most workflows. Why can’t I point at a shared swc outside of my project? A lot of our work runs in a global framework and for the most part designers don’t care about the framework or when it changes. If the designers could point at a swc on the server that can be updated at any time or in one common directory pulled out of source control they would recieve the updates and compile time checking without even knowing. You should be able to point to any swc or even a swc directory (again, like in Flex Builder).

Flash 8 had exclude.xml at least, even that would be a nice touch if that was offered again. I haven’t been able to find if any of this has been added to CS4, most of the discussion is around the visual tools. I’m ok with that, the designers deserve the love, the last release was all about the developer, AS3. Just curious if anyone knows if the compilation and workflow in the IDE is any better? I know about XFL, and I am excited to start playing with that. I already have a few ideas for workflow improvements.

 Also, Adobe if you’re reading this, can you please add an omit trace statements option in the command line compilers. I know it can be done with ANT and some RegEx trickery but it shouldn’t be that difficult. </endOfRant>

Apr

22

New URL, same content, www.flashmorgan.com.

By scott

While flying back from Toronto the other day I thought of a new URL - flashmorgan.com. I visited a comic book store in Toronto, maybe it inspired the new domain name, it is somewhat super hero-ish. It’s a little more exciting then scottgmorgan.com. I don’t know how many complaints I have received from people who can’t find my site because they forgot the g in scottGmorgan.com. The new domain is much easier and shouldn’t cause any problems.

There is no need to update your bookmarks (unless you want to of course), I am not getting rid of the old scottgmorgan.com domain anytime soon.

Feb

14

Now this is funny, Microsoft wants to hire me as a Flash Developer, what about Silverlight???

By scott

I recieved an email yesterday from a Microsoft technical recruiter wanting to hire me as a Flash Developer, or as they called it, a Media Author. After I laughed out loud, sent it to a few colleagues who also laughed out loud, I thought about this for a second. Not about taking the job, I would rather be probed by aliens than work for Microsoft. I thought who in their right mind would take a Flash job at Microsoft? It would be like sitting on death row. Talk about a dead end job!

It is obvious Microsoft is trying to kill Flash, it will never happen, but when they do start to push hard, and Silverlight penetration reaches, I don’t know, double digits, why would they employ anyone using a competing technology. Probably because they know Flash is superior and it is going to be a severe uphill battle to even compete. Maybe they would hire me and brainwash me to be a Silverlight developer, then slowly hire every flash developer out there and “convert” them. Ok, maybe a bit far fetched, but would you put anything past Microsoft? I also find it humorous that they don’t even use the word Flash in the job title.

With that said, here is the recruiters email to me. My favorite line is “I am sure you would be interested in working in the Microsoft campus on exciting, challenging projects.” They couldn’t be more wrong.

Hello,

This is [name removed to protect the innocent] , Technical Recruiter with [name removed to protect the innocent], Seattle and a preferred vendor for Microsoft, Redmond in Seattle for contract and some full time positions.

I came across your resume online and as I was going through it, I would like to know more about what kind of roles you are looking for, what skills, areas you would like to work on, what you are passionate about and try to find suitable challenging positions for you . We do long term contracts which are generally extendable beyond a year, we do full time positions, we do contract to hire positions too. Depending on what you are comfortable with and what you are looking for, we will look, and help you find the right positions. I am sure you would be interested in working in the Microsoft campus on exciting, challenging projects.

Currently I have a long term contract position with the MSN Media Solutions Team at Microsoft, Redmond and they are looking for Flash developers.

1. Position: Media Author (Flash Developer)

Requirements:

Experience developing Flash site, components, and/or games. Proficiency in Flash, Photoshop, ImageReady or Illustrator.

Experience with Flash ActionScript

Some JavaScript experience, working knowledge of html, and web based design experience.

Experience in driving work through the software development process.

Experience in audio and video encoding and editing is a plus.

Do let me know if you would be interested and send your latest resume ASAP

Thanks and Regards,

[name removed to protect the innocent]

Does anyone else find this as funny as I do?

Jan

30

Yahoo releases Astra v1.1.

By scott

My former peeps over at Yahoo just released 10 more components, 3 Flash and 5 Flex components. The also fixed some of the bugs that the community reported in the existing components.

For the Flash world Astra now contains an AlertManager, an AudioPlayback component, and a MenuBar component that works with the existing Menu component released in Astra 1.0.

For the Flex folk the kind gents on the Yahoo Flash Platform team have created an AutoCompleteManager, a few different ColorPickers, an IPV4AddressInput, a TimeInput component, and a TimeStepper component.

Nice work guys, and now that I am not part of the team and a user of Astra I say thank you for all your hard work.

Jan

23

Why is my progressive H.264 video not playing until the entire file is downloaded.

By scott

Now that H.264 video is supported in Flash Player 9.0.115 and FMS 3 is on the horizon we are getting ready to flip on the HD switch in our video player. We have been lucky enough to try out a few beta releases of FMS 3 and have had great success with streaming H.264 video without too many changes to our core video player component (both AS2 and AS3). However, I ran into an issue yesterday with progressively downloaded H.264 video. The video would play but it was not progressively downloading, it would download the entire file before it began playing. Not the user experience we were looking for. The files played fine in Quicktime, and they played fine in Flash when streamed from FMS 3, just not progressively.

Time to hit Google. I found a few postings, not many, probably not too many people using H.264 yet (so I thought). Turns out the problem lies within the encoding of the file and where the “moov atom” is stored. The moov atom is essentially the header information of the file. To progressively play a file this data is needed before the first frame of video can play. This data contains the appropriate meta data the NetStream class looks at when determining the length, size, etc of the video. The moov data in my .mov files were stored at the end of my videos and that is why the video wouldn’t play until the entire file was downloaded. The moov data needs to be at the beginning of the file in order to progressively stream video.

I figured others must have run into this issue and someone must have wrote a utility to move the header bytes from the end of the file to the beginning. Byte manipulation isn’t rocket science, close, but not quite. While searching I found an interesting tech note on the Adobe site and it turns out Adobe’s own video editing software is to blame for this. The quote below is pulled directly from the tech note explains the issue.

One important thing about playing an H.264 video file as progressive download is that the moov atom needs to be located at the beginning of the file, or else the entire file will have to be downloaded before it begins playing. The moov atom is a part of the file that holds index information for the whole file. Unfortunately, tools such as Adobe Premiere and After Effects place this information at the end of the file, but Adobe is working to fix this in a future update to the CS3 video production tools. This isn’t an issue for streaming the H.264 video files, however, so Flash Media Server users can breathe easy.

Why didn’t Adobe address this issue? Obviously they rushed this feature to market, Silverlight supported H.264 video and everyone was raving about it. I don’t know if Silverlight progressively streams H.264 video when the moov atom is at the end of the file or not. Can anyone confirm? Or maybe this was some sick marketers ploy to entice users to buy FMS 3, i doubt that but conspiracy theories are so much fun.

Scouring the web I did find a utility that moves the moov atom to the start of the file. Renaun Erickson ported a C app to AIR that moves the moov atom and resaves the file. Very impressive! Unfortunately it didn’t fix my issues, Renaun’s app only works with .mp4 files and the files I was working with are .mov files. Using Quicktime Pro I exported one of the .mov files to a .mp4 to see if Renaun’s app would then move the moov atom. Still no luck. As a last resort I tried a simple Save As from Quicktime to see if it would restructure the bytes so the moov atom was at the beginning of the file. Guess what, it worked! My progressive downloads now worked. I created a simple batch and saved out all my progressive videos using Quicktime.

It baffles me that Adobe would not have put more thought into this problem especially when their own software is the culprit. They talk about CS3 suite integration and this is the furthest thing from that. Adobe mentions that they will be releasing a CS3 update to address the issue, hopefully sooner than later, unfortunately this does not help people (like me/us) who already have hundreds of H.264 assets with the moov atom at the end of the file. Re-encoding the video would be a huge process, we are already using the video assets for other streaming services, now that Flash supports H.264 we were hoping for an easy switch to our Flash video player. Most of our video is streamed, and that works great, unfortunately the progressively downloaded video wasn’t an easy switch.

In the end, the video looks great! Watching 1.2mb and 3mb fullscreen video in Flash is unreal. Now if we could just get support for variable bitrates!!

Nov

18

AS3 Garbage Collection, the reason your tweens are ending early.

By scott

Josh Tynjala and I were speaking today, well actually typing over IM. We were discussing a problem we both ran into recently, the fl.transitions.Tween class was not dispatching events consistently. Sometimes the TweenEvent.MOTION_FINISH event would be broadcasted, other times it would not. Sometimes our programmatic tweens were visually completing, other times they would not, in a few cases they wouldn’t even start. After a little debugging we realized that the AS3 Garbage Collection was killing the tweens. You may be asking why would the garbage collection be doing this? Let’s start out by looking at some example code.

var len:int = _model.getNumberOfItems();
for (var i:int = 0;i<len;i++)>
     var clip:MovieClip = _scope.getChildByName('button'+i);
     var myTween:Tween = new Tween(clip, 'alpha', Regular.easeOut, 0, 1, 0.5, true);
     myTween.addEventListener(TweenEvent.MOTION_FINISH, buttonAnimationComplete);
}

Pretty simple code, in my AS2 days I used code similar to this a million times and never had a problem. All I am doing is looping through a set number of MovieClips and fading them up from 0 to 100%. Most times this worked fine, but a few times the tweens never completed and buttonAnimationComplete was not called. This is because the AS3 Garbage Collection was deleting the Tweens just like it should be. What? The tweens should be deleted? Yes.

Notice that I am storing the reference to my tween in a local variable that gets overridden in every iteration of the loop. This means there is no real reference to the object and when there is no reference to an object it is flagged for removal by the garbage collector. Since there is no real way to know when the garbage collection cycle is going to run the tweens were completing some of the time and other times were being thrown into the back of the big garbage truck that slowly creeps around your code.

The best way to ensure that this doesn’t happen is to store your reference in a class level member. I ended up storing all of my tween references in a class level array. Once all of the tweens were complete I cleared the array. Here is the updated code that I used, the entire class is not shown here, trust me your scroller will thank me.

private var _buttonTweens:Array = new Array();
private var _buttonTweenCompleteCount:int;

private function animateButtons():void {
     var len:int = _model.getNumberOfItems();
     for (var i:int = 0;i<len;i++)>
          _buttonTweens.push(new Tween(clip, 'alpha', Regular.easeOut, 0, 1, 0.5, true));
          _buttonTweens[_buttonTweens.length - 1].addEventListener(TweenEvent.MOTION_FINISH, buttonAnimationComplete);
     }
}

private function buttonAnimationComplete(e:TweenEvent):void {
     buttonTweenCompleteCount++
     if (buttonTweenCompleteCount == _model.getNumberOfItems()) {
          _buttonTweens = [];
          dispatchEvent(new Event('buttonsReady'));
     }
}

I am just using Tweens as an example, but you can run into this same issue with any object that has local references that are overridden. For example, I had a Timer event set to iterate every 100 milliseconds and it called loadAsset(), a method that did just what it says, it loaded an asset.

private function loadAsset():void {
     _currentItemToLoad++;
     var myLoader:Loader = new Loader();
     myLoader.addEventListener(Event.COMPLETE, assetLoaded);
     myLoader.load(new URLRequest('images/galleryImage' + currentItemToLoad + '.jpg'));
}
private function assetLoaded(e:Event):void {
     var holder:Sprite = new Sprite();
     holder.visible = false;
     holder.addChild(e.target.content);
     _scope.addChild(holder);

     e.target.removeEventListener(Event.COMPLETE, assetLoaded);
}

Just like the Tween example above my Event.COMPLETE event was not firing all the time. This is because I was storing the reference to the Loader in a local variable that was overridden each time the loadAsset method was called. To get around this I stored all my references in a class level member (an object or an array work nicely).

Hopefully this helps you figure out why you are not seeing certain events in your code, it had me stumped for a bit. Now you know, and as G.I. Joe said “knowing is half the battle”.

Nov

11

Accessing document class of an externally loaded swf with AS3

By scott

I have seen a lot of posts lately with people asking how they can access variables and methods in an external swf that is loaded at runtime using AS3. This isn’t a difficult task, but it is much different than AS2/AS1 where you could just call directly into the loaded swf using the instance chain if you were in the same security sandbox.

First off, lets create our swf that wil be loaded in at runtime. Open up your favourite actionscript editor and create a new class with the following code.

package com.scottgmorgan {
     import flash.external.ExternalInterface;
     import flash.display.Sprite;
     public class ExternalMovie extends Sprite {
          public function ExternalMovie():void {
               //nothing in our constructor right now.
          }
          public function alert(msg:String):void {
               trace(msg);
               ExternalInterface.call('alert', msg);
          }
     }
}

Now create a new FLA and set the above class as the document class. If you are not sure how to do this simply enter the class path (com.scottgmorgan.ExternalMovie) into the document class textfield found in the property panel. Lather, rinse, repeat, compile.

Next we will create the swf that will load our ExternalMovie swf we just created. Let’s jump back to our favourite actionscript editor and create a new class with the following code.

package com.scottgmorgan {
     import flash.display.Loader;
     import flash.net.URLRequest;
     import flash.events.Event;
     import flash.display.LoaderInfo;
     import flash.display.Sprite;
     public class SourceMovie extends Sprite {
          public function SourceMovie():void {
               var loader:Loader = new Loader();
               loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete);
               loader.load(new URLRequest('ExternalMovie.swf'));
          }
          private function onLoadComplete(e:Event):void {
               var loaderInfo:LoaderInfo = e.target as LoaderInfo;
               addChild(e.target.content);
               var swf:Object = loaderInfo.content;
               swf.alert('Hello World');
          }
     }
}

That’s it, LoaderInfo saves the day. LoaderInfo.content connects you with the document class of the externally loaded swf. Lets create a new FLA, assign the SourceMovie class as the document class and compile. Make sure the SourceMovie.swf and ExternalMovie.swf are in the same directory. The as files should be in /com/scottgmorgan/. Let’s compile the SourceMovie and you should see “Hello World” in the output window if you run the swf inside the IDE, if you run it from a browser you should see an alert dialog with “Hello World”.

Another option you have is to use the ApplicationDomain class. Using the ApplicationDomain class you can add the classes from the ExternalMovie to the SourceMovie’s ApplicationDomain. This is a great way to load in code libraries at runtime.

Lets pretend we have a large application with multiple levels of security, maybe we are creating a content management system and we need multiple permission levels. User A can only update content, User B can update content and update the site map, User C is an administrator and can do everything User A and B can do but can also access tracking information, edit user profiles, update permissions, etc. When User B logs in the application loads the site map code library (sitemapadmin.swf) and adds its classes to the main ApplicationDomain. When User C logs in the sitemapadmin.swf classes would be added to the main ApplicationDomain, for this user the application would also load the trackingadmin.swf, and useradmin.swf code libraries and add all the included classes to the main ApplicationDomain.

Let’s update our SourceMovie.as file and add the ExternalMovie class to SourceMovie’s ApplicationDomain.

package com.scottgmorgan {
     import flash.display.Loader;
     import flash.net.URLRequest;
     import flash.events.Event;
     import flash.display.LoaderInfo;
     import flash.display.Sprite;
     import flash.system.ApplicationDomain;
     public class SourceMovie extends Sprite {
          public function SourceMovie():void {
               var loader:Loader = new Loader();
               loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete);
               loader.load(new URLRequest('ExternalMovie.swf'));
          }
          private function onLoadComplete(e:Event):void {
               ApplicationDomain.currentDomain.getDefinition("com.scottgmorgan.ExternalMovie");
               var myExternalMovie:ExternalMovie = ExternalMovie(e.target.content);
               myExternalMovie.alert('Hello World');
          }
     }
}

There you have it. One thing you will notice is you don’t have to add the loaded swf to the display list to access its classes. Hopefully you will be able to use these techniques in future projects.

Oct

28

Flash multi-uploads do not work in Leopard

By scott

Yay Leopard arrived on store shelves on Friday!! The upgrade takes forever but in true apple style they have created a very nice update to OSX. However, if you visit a site that is using Flash and the FileReference.upload() in any browser running in Leopard you will not be happy. Not sure if Apple will need to push out an update or if Adobe will. Let’s hope it is Apple, we all know how much fun it is detecting plug-in minor versions and an OS version just to circumvent certain functionality. As it stands the multi-uploader on Flickr isn’t working any more (more here). I found a few others discussing this issue too. And then there is this thread discussing all the bugs found in Leopard, don’t these people have anything better to do with their weekends ;)

Oct

22

Say hello to my little friend - describeType()

By scott

It amazes me that people don’t know about describeType(). If you’re lazy, or as some developers call it, efficient, you always don’t have time, or really don’t feel like digging through half assed completed documentation to see what parameters a classes constructor accepts. Sounds like the perfect time to combine forces, trace() meet flash.utils.describeType(). The describeType() method returns an xml dump that contains all the details you’d ever need to know about any object that is passed in as a parameter.For example, let’s pretend this is our first time working with Flash (of course you could be working in Flex too), lucky us, we never had to use AS2 or AS1, we only heard our cubicle neighbors groaning about spaghetti code, and hidden code attached to buttons. Since this is our first time using Flash we don’t even know what a MovieClip is or what methods are available to us. One simple line of code will solve our ignorance.

trace(flash.utils.describeType(flash.display.MovieClip));

This one little line of code returns this to us in our output window (shortened for your scroll wheels sake):

<type name="flash.display::MovieClip" base="Class" isDynamic="true" isFinal="true" isStatic="true">  <extendsClass type="Class"/>  <extendsClass type="Object"/>  <accessor name="prototype" access="readonly" type="*" declaredBy="Class"/>  <factory type="flash.display::MovieClip">    <extendsClass type="flash.display::Sprite"/>    <extendsClass type="flash.display<::DisplayObjectContainer"/>    <extendsClass type="flash.display::InteractiveObject"/>    <extendsClass type="flash.display::DisplayObject"/>    <extendsClass type="flash.events::EventDispatcher"/>    <extendsClass type="Object"/>    <implementsInterface type="flash.display::IBitmapDrawable"/>    <implementsInterface type="flash.events::IEventDispatcher"/>    <accessor name="scenes" access="readonly" type="Array" declaredBy="flash.display::MovieClip"/>    <method name="stop" declaredBy="flash.display::MovieClip" returnType="void"/>    <method name="nextScene" declaredBy="flash.display::MovieClip" returnType="void"/>    <method name="play" declaredBy="flash.display::MovieClip" returnType="void"/>    <accessor name="currentScene" access="readonly" type="flash.display::Scene" declaredBy="flash.display::MovieClip"/>    <accessor name="currentFrame" access="readonly" type="int" declaredBy="flash.display::MovieClip"/>    <accessor name="trackAsMenu" access="readwrite" type="Boolean" declaredBy="flash.display::MovieClip"/>    <method name="gotoAndStop" declaredBy="flash.display::MovieClip" returnType="void">      <parameter index="1" type="Object" optional="false"/>      <parameter index="2" type="String" optional="true"/>    </method>    <accessor name="currentLabels" access="readonly" type="Array" declaredBy="flash.display::MovieClip"/>    <method name="willTrigger" declaredBy="flash.events::EventDispatcher" returnType="Boolean">      <parameter index="1" type="String" optional="false"/>    </method>  </factory></type>

The output window never looked so good. Methods, paramaters, superclasses, accessors, the amount of information that is returned is beautiful. I don’t know how many for in loops I wrote in AS2 just to try and figure out what methods were available in a custom class.One thing to note is that describeType() only shows public properties and methods, and will not show properties and methods that are private, package internal or in custom namespaces.If you have never looked at the flash.utils.* package, I suggest you do, there are some handy little utilities in there.

Oct

19

New Job, New City, New House, and a New Blog

By scott

After 6 years with the same design it was time to retire my old website. Like any busy developer or company for that matter personal projects always get pushed a side. I figured since I am starting new in L.A. that I should finally get around to updating my Blog. And here it is. I rolled my own CMS for my previous site and blog, it worked great, but it was dated. So now, like many, I have switched to WordPress.

I will soon have my portfolio back up, this time I am going to try and do something a little bit cooler with it, and since I am a Flash/Flex developer I will probably do something using the aforementioned technologies. For those who can’t wait to see what I’ve worked on the old portfolio can be viewed here. Stay tuned and let me know what you think of the new site.

Props to the designers of this theme N.Design Studio and MangoOrange™, I haven’t set up all the 301s for the old content, so if you have bookmarks you may see the old design rearing it’s ugly <head>.