I can't Believe How Half-Baked AS3 is

Illustration of AS3's state
Something is missing

Now and Then

ActionScript was introduced with the release of Flash 4 back in 1999. In my never-ending naïveté I assumed it should be pretty mature by now. Almost a decade should be enough for that, shouldn't it? Obviously that isn't the case - otherwise there wouldn't anything to rant about. ;)

I started with ActionScript3 (Flash9+) a few weeks ago. It's supposed to be so much better than ActionScript2. There wasn't much of a reason to not use the latest version; given that about 90% of the users use the latest version of Flash. The remaining 10% quickly fade away if you consider things like the lifespan of small web games (a couple of years easily) and the time it takes to get things rolling for real. A quick look at AS2 was actually enough to discard it completely; it's ugly.

In the past I always wondered how they managed to get the Flash VM this small. Well, now I know. They only cover absolutely basic functionality, which wasn't much of a surprise to be honest. Given the limited scope of Flash applets this isn't really a problem. However, if you take a close look at those things they did implement, you'll be able to see what makes it this lightweight: half the functionality is missing.

An Example - (HE-)AAC is superior to MP3

Adobe recently added support for H.264 (a video format), (HE-)AAC (an audio format), and MP4/3GP/MOV/etc. (container formats) to their Flash runtime. (HE)-AAC is somewhat similar to Ogg Vorbis; at low bitrates the sound gets "washed out" without introducing those painful artifacts everyone knows from low-bitrate MP3s. Hi-hats in particular are as pleasant as a million rusty nails scratching across a blackboard. With better lossy psychoacoustic audio formats the sound only gets "thinner". For a more visual example compare JPG with wavelet-based formats such as JP2 (JPEG2000). At high compression rates JPG produces heavy block artifacts whereas JP2 only looses details, which is a lot more pleasant to the eye since no noise is added.

Since you don't get those artifacts with (HE-)AAC you can go really low with the bitrate. In my tests I could get as low as ~25kbits with HE-AAC (AAC SBR+PS). To put things into perspective: that's 73kb for a 22s background music loop. An MP3 loop with similar quality requires 64kbits if you convert it to mono or 96kbits if you use joint stereo (for "real" stereo i.e. 2 channel audio you should at least use 256kbits). That's 177kb (+142%) respective 265kb (+263%). While the MP3 sounds a bit "fuller", the AAC track is more pleasant to listen to.

This difference is huge - especially if you consider that you need a million downloads per month for a mere $1000 (the eCPM is typically at about 1$ with those popular ad-wrapper networks). Let's say you got three 22s tracks (or 1 minute and 6 seconds of audio) and you actually manage to get a million downloads. Then you'll have an overhead of 312kb per download (with 64kbits that is), which means you'll waste 312gb of traffic. Of course you'll also make your visitors wait longer than necessary.

Futile workarounds

As if all of that wouldn't be enough to despise MP3, there is yet another issue: MP3 isn't suitable for looping. By design the format adds leading and trailing silence. There are tools which are supposed to work around this, but they don't work very well.

One might be inclined to try to fix it with some code like this one (don't bother trying it - it doesn't work!):

[Embed(source = 'loop.mp3')]
private var musicClass:Class;
private var music:Sound = new musicClass();
private var soundChannel:SoundChannel=null;
public function Main():void {
    [...]
    var musicTimer:Timer = new Timer(1);
    musicTimer.addEventListener(TimerEvent.TIMER, reloopMusic);
    musicTimer.start();
}
private function reloopMusic(evt:TimerEvent):void {
    if (soundChannel == null){
        soundChannel = music.play(42);
        return;
    }
    if (soundChannel.position >= music.length - 18){
        soundChannel.stop();
        soundChannel = music.play(42);
    }
}

42 is the length of the leading silence and 18 is the length of the trailing silence (both in msecs). Looks like it could work, right? Well, it doesn't work. There are two reasons why it doesn't work as expected:

  1. The minimum interval of Timer depends on the SWF file's framerate and the used browser (IE 16msec, Opera 8msec, Firefox 1msec - may vary with versions and operating systems) and
  2. SoundChannel.position is broken. The reported position isn't even remotely accurate.

If the Flash IDE is used you can add WAV files, enable MP3 compression, and then some magical voodoo fixes the loop problem for you. But that doesn't help much if you're using the SDK directly, does it?

(HE-)AAC to the rescue! (Or not)

Subjectively improved quality, smaller download sizes, and no looping issues. What could go possibly wrong with so much awesomeness at one spot? Well, the incomplete Flash API does.

flash.media.Sound is only capable of playing MP3 audio files

Being able to use Sound would be really nice. Like Bitmap takes JPG, GIF, and PNG; Sound should take MP3, AAC, or whatever else they decide to add in the future. Blatantly obvious, isn't it?

flash.media.Video requires a flash.net.NetStream

This means you cannot load embedded videos - or what I'm trying in this case - embedded MP4s which only contain an HE-AAC audio stream.

mxmlc isn't aware of the "video/mp4" mime type

[Embed(source = 'music/mp1.mp4', mimeType = "video/mp4")] //correct mime - doesn't work
[Embed(source = 'music/mp1.mp4', mimeType = "application/octet-stream")] //gotta use this

In a sane world...

Sound should of course be able to load audio streams from MP4 containers, Video would take an InputStream, there would be also utility streams like ByteArrayInputStream, and Embed would know about those containers and their mime types.

The functionality is there. Of course I want to use it. It's truly mind-boggling that Adobe failed to predict that. There are a lot of hobbyist APIs which are more feature complete than that. It's the sparkling new killer feature; expose it!

They also should have done something about that looping issue. E.g. optional auto trimming which defaults to on. Or even better yet a different audio format. If you look a bit around at various Flash forums you can find thousands of threads about this very topic. This single issue must have wasted massive amounts of time, energy, and money. I don't know how something like that could happen with a supposedly media centric solution like Flash. It can't get any more basic than audio loops, can it?

Needless to say that I'm very disappointed with Flash9. It should get at least the overly obvious things right.

Comments

Wrong analysis

This has nothing to do with actionscript3, this is related to what technologies the flash player offer you (its a proprietary software, u choose to support&develop for it, now accept it or move out), that they are exposed in as1/as2/as3 ... that's another plate on table.

The complaint about the mimeType ... so what, they missed that in FLEX API (not in as3), things like these do happen in development u know.

If you really want to make complaints ... the do it relating to how complex AS became with its 3rd iteration not with your shallow reasons.

re: Wrong analysis

>This has nothing to do with actionscript3 [...]

It's an API issue. The native stuff is there, they just "forgot" to wire it up.

>The complaint about the mimeType [...]

The addition of those container formats and codecs is their latest killer feature. It's only sensible to ensure that that stuff works. Having the mime types there wouldn't change anything though. It's just surprising that they didn't even took care of that.

>[...] how complex AS became [...]

It doesn't look all that complex to me. It's just incomplete.

AS3 is language

> > This has nothing to do with actionscript3
> It's an API issue.

But ActionScript is just a programming language, which could be bundled with different APIs. And that API could be exposed to different languages.

I know it's always popular to think of a language, a library, sometimes an implementation, and even sometimes an IDE, as one inseparable entity, but they are actually separable distinct concepts which can be discussed individually.

Really?

You pose one argument to support your claim that an entire language is "half baked"? How ridiculous is that? And of all things, its about AAC audio?

Seriously, come up with some good arguments and post those. If the language is truly half baked, like you claim, you shouldn't have any trouble coming up with some more examples.

re: AS3 is language

>But ActionScript is just a programming language[...]

Yes, I'm aware of the differences. However, in AS3's case everything is synonymous. The language, the platform, the API... none of that is interchangeable. Well, there are open source Flash players, but they can't do anything differently - or more accurately - they shouldn't do anything differently. You can also swap AS3 with haXe for example, but that won't change anything.

re: Really?

>You pose one argument to support your claim that an entire language is "half baked"?

I wrote so much about this single issue, because I wanted to outline the usual train of thought. Wanting to use HE-AAC for BGM loops is just logical, which in turn makes Adobe's oversight somewhat worse.

Another issue is i18n. They thought it would be a good idea to use the language of the operating system instead of the usual far more logical thing: the locale. Surprisingly Flash Light is supposed to get this right.

There are probably other fundamental flaws, but as I said I just recently started with Flash. Well, my motivation to rant about this was rather simple: this kind of shortsightedness annoys me to no end. Essential things should work and they should be also easy to do. Especially if these things are strongly linked to its raison d'être. Like a car should be able to move or food should be editable. It should fulfill its purpose. Well, I guess you can catch my drift.

Misguided

Maybe you should be congratulating the team for adding AAC/H.264 support instead? The API and Flash Player features were in sync when Flash CS3 was released but since then the FP team have been adding some great features in incremental releases of the FP9. It's much more disruptive to the thousands of Flash developers to change the API than to add in some new features every now and again to tinker with. They didn't forget to wire anything up - the API just doesn't support features of the FP that didn't exist at the time of release of Flash CS3. This is not a language issue (AS3), this is an issue with Flash's libraries/API.

I guess what you are saying is that you would prefer that Adobe rewrite all relevant libraries and update the API before any new feature is added to the Flash Player? I disagree - the features are useful, let's have them, and the API will be updated when Flash CS4 is released. Maybe you would be happier just pretending that those particular features don't exist?

re: Misguided

>Maybe you should be congratulating the team for adding AAC/H.264 support instead?

I already did that. And I also explored some new possibilities.

>I guess what you are saying is that you would prefer that Adobe rewrite all relevant
>libraries and update the API before any new feature is added to the Flash Player?

If they would have thought that through beforehand it wouldn't be necessary to change the API. You hand over some file and if the current runtime has a matching reader, everything will be fine. With Java for example it's just like that. E.g. if you write a simple audio player or image viewer it will be automatically capable of handling new file types as soon as they are added to the JRE.

Video in Flash is just like that. It doesn't care about mime types/file extensions. And video players which were written before 9.0 r115 (9,0,0,115) are capable of playing MP4, MOV or 3GP files right away - as long as they didn't check the file extensions.

Sound could also sniff the file type (by reading the header) and the embedding issue could have also been addressed beforehand (e.g. with streams). It's very simple stuff and it has been done a zillion times before. Adobe itself also did that stuff before. So, why didn't they do it in this case? Apparently it would have been a good idea.

Well said but ...

You present a single example and corectly some people say that the title is somewhat overkill.
You fail to point out how this situation is the norm in AS3..

... which by the way it is!
Come on people, everybody know that flash is broken.
It's hard to accept it when you make a living out from it and can't learn new tricks.

re: Well said but ...

Other "funny" things are the lack of a seedable PRNG and completely broken i18n capabilities. Flash doesn't use the locale (user-changeable language setting) instead it uses the language of the operating system (hardcoded).

Stuff like that makes me really angry. It's completely retarded and there are no excuses.

Wow...

There are quite a few things to actually complain about regarding AS3, but instead you just wrote an article about AS3 that only talked about the flash player, which as apparently you don't realize are two very different things.

We already have enough misinformation out there, when you want to write an article to post on the web without coming off as a complete jackass you might wan't to do a little research (http://www.google.com/search?q=as3+limitations).

Some of my biggest pet peeves are its lack of overloading, especially with regard to operator overloading, lack of Enum, restriction to public constructors, lack of nested classes, bugs regarding invisible buttons when tweening alphas, all kinds of text bugs especially when dealing with masking and fading. Yes AS3 definitely has it's quicks, and bugs, your welcome to develop that cool new thing your working on in whatever else u like. I however, will be delivering a vastly superior product because I know AS3 inside out, and it's beautiful when u reach the top. Deal.

*shrug*

I was just a tad annoyed. That's all. It's not like everything is wrong with AS3. The documentation for example is pretty good - especially if you compare it with Python's.

I also do know now how MP3s can be looped in the Flash9 player. But so far I didn't get around writing the code for that. In case you're wondering... it can be done with dynamic SWF generation. It's pretty fiddly but doable.

as was stated above

Everything about AS3 is a step in the right direction, in regards to having changed from AS2.

The strict compiling rules (percieved as 'complexity') promote well-structured, stable code, which has become an increasingly large concern due to the ease of use of AS2 and subsequently the large influx of amateur coders. Adobe wants flash to continue to grow in features and functionality, and to do that it needs to cater to the people willing to step up the quality and standards compliance of their work.

AVM2 is worlds faster than AVM1, which alone is reason enough to use as3.

I could keep going, but if you want to deter all this opposition to your article, you should consider changing the title to something more coherent to the issues addressed within. Those are not issues that have anything to do with as3 as a programming language.

re: as was stated above

>[...] you should consider changing the title [...]

I won't change a title this late (unless there is a typo). If you skim over the article it's pretty clear that I wasn't all that happy working with AS3 (targeting Flash9+) and that all my unhappiness stems from the incomplete API. That's all there is to it.

But it works if code it right

Thou shall not use

sound.play(45);

if you wanna loop, instead try for example

sound.start(45);

and your worries are far away

the@welho

re: But it works if code it right

There is no start() method and even if there were one, it would only take care of the leading silence.

(There is a proper way to do it, but it's something entirely different.)

as looping sound, why not

as looping sound, why not just listen to it when it is completed via its soundchannel and once complete play it again. :) piece of cake. :)

re: as looping sound, why not

Yea, great idea. Except that it won't work this way (as I already mentioned). Even if the reported position would be any accurate (it isn't) this wouldn't work, since the MP3 format isn't really suited for looping. It always contains some leading and trailing silence, which ruins the loop unless you skip it.

There are only 3 ways: a) use the authoring tool, b) create an event sound (which specifies the cue-in and cue-out points) on the fly or c) write a custom tool similar to swfmill, which bakes the MP3s into your SWF (with cue-in and cue-out points).

Well, there is also a fourth way: Don't use MP3 in first place. WAV would be pretty silly (unless it's rendered from a tracker module for example - looping works just fine there by the way), but Ogg/Vorbis would be theoretically an option with Flash 10. While Flash 10 doesn't support it natively, it does support dynamic sound stuff.

Nice writeup!

Well, jh, I don't know why people complain about you pointing out things that don't work as expected. Of course it's a nice thing that the folks at Adobe integrated aac support... but if it's not working in all ways the developer thinks it should work in I guess it's just reasonable to let somebody know about that.

I know a lot of people who get pissed because something "just doesn't work". Then they yell at the computer screen and move on. Since that doesn't really help to improve the software, I'm always pleased to see people making glitches public. That way they eventually get noticed / verified / ironed out.

disappointed with flash 9?

Dude, we're on Flash 10 and we STILL CAN'T hook up a NetStream to a sound filter. Someone should have his knees broken for this.

agree

Almost everything about AS3 is half baked. The naysayers on here are numbskull hobbyists.

Adobe = Flash = disgusting

I've been programming in ActionScript for 8 years and I still think it's terrible. I agree that everything is half baked. Amongst many other issues, in AS1 there were graphical issues when scaling vectors or importing bitmap images, they would offset by .3 of a pixel or leave broken redraw regions. In AS2 it was the horrible event system which had been hacked onto AS1 for backward compatability. In AS3 the sound classes suck and suffer from bugs there are memory leak issues to contend with (ActionScript lost compatability with it's foundation language structure)

I totally agree with the writer here, c'mon guys, many plugin tools supported these basic things years and years ago.. the video stuff is pretty good but it's not like the tech didn't exist for videos, this isn't my primary concern!? It's the basics like images and sounds, very very core stuff that should be 100% right after the many itterations of ActionScript. I'm so bored of it as a language and the IDE tools have been terrible in the past for coders, I mean, look at the ActionScript window. What the hell is that? CS4 crashed so much I had to revert back to CS3 for building components, I stayed away from it as an IDE. The help & documentation systems in all of these products are terrible. People have created better free tools to do this stuff, FREE and then now Adobe have integrated Flex (which is just a Flash binding system) into a free open source IDE and sell it as Flash Builder, but you can't build components in it so you need to buy Flash (Just for that)... They should be the same bloody product. What the hell is the point of a piece of software that links a compiler to an Open Source IDE and charges a fortune for the privaledge and then sell you yet another tool to make the things you need to build your actual product.

Come on guys, if you don't think everything about this is half baked then you need to work on your expectations. The entire 8 years of working with Flash has been pretty cool because of the people involved with Flash and bringing a few great RIAs and games to the web but seriously let down by the lack of structure, and consistency and quality found within Flash and AS.

RipX

Sorry to bump

Sorry to bump on my last post but right now...here is a perfect example of what utter nonsence this is:

package com.juiceltd.nadir.view.components {
    import flash.display.Sprite;
    import flash.media.Sound;
    import flash.media.SoundChannel;
    import flash.media.SoundTransform;
    /**
     * ...
     * @author Gary Paluk
     */
    public class AudioPlayer extends Sprite {
        /** , mimeType = 'audio/mpeg' */
        [Embed(source = '../../../../../../../../../Users/Gary/Documents/My Flash Projects/Nadir Beta/lib/audio/NadirTheme.mp3', mimeType = 'audio/mpeg')]
        public var NadirTheme:Class;
        
        private var _nadirTheme: Sound;
        private var _soundChannel: SoundChannel;
        
        public function AudioPlayer() {
            _nadirTheme = new NadirTheme();
            
            _soundChannel = _nadirTheme.play( 0, 99 );
            _soundChannel = _nadirTheme.play( 20000, 99 );
            
            _soundChannel.soundTransform = new SoundTransform( 0.1 );
        }
        
    }

}

This code is what I'm currently working on right now for my game Nadir Online (can find on youtube), now check out the soundtransform... the Sound play() method returns a SoundChannel object, so, the theory as a programmer is that the SoundTransform will simply be applied to the audio track to the channel _soundChannel. No. It doesn't work like that at all, this infact layers together the audio tracks and makes the transform be applied to one of the channels (I think)... What happened to a simple composite interface?? Isn't that the standard?? Adobe.. Standards.... o_O

Adobe if you read this....

_soundChannel.addSoundByName( new NadirTheme(), "NadirTheme1" );
_soundChannel.addSoundByName( new NadirTheme(), "NadirTheme2" );
_soundChannel.volume = 0.5;

_soundChannel.removeAllSounds();
delete _soundChannel;

Now according to Adobe pricing structure... that'll be $1,000,000, please send a cheque Mr.Adobe and if you need any more help I'll make another product called Help Builder for you and you can buy that one to finish off and that'll just link you to the help! Oh...that's another $1,000,000.

RipX

Re: Sorry to bump

// Instance one
_soundChannel = _nadirTheme.play( 0, 99 ); 
// You override your old instance with a new instance
_soundChannel = _nadirTheme.play( 20000, 99 ); 
// You silence only the second instance, so the first sound won't work.
_soundChannel.soundTransform = new SoundTransform( 0.1 ); 

If you want to alter all the sound you need to store each sound channel in a different variable or in an array.

Post new comment

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options