PreloadAssetManager (AS2) – An Intelligent Preloading Queue
- Version: 2.93, Updated 3/31/2008
- Compatibility: AS2, Flash Player 6 and later (version 7 for FLV preloading)
- File size added to compressed SWF: about 3kb
|
|
|
NOTE: PreloadAssetManager has been sunset and is no longer actively enhanced or supported. Feel free to use it if you want, though.
Description
Provides an easy way to invisibly preload SWFs, FLVs, or images and optionally trigger a callback function when preloading has finished. It also provides _width and _height information for all successfully preloaded SWFs or images, and duration information for FLVs (assuming they were encoded properly and have MetaData). By default, it will initially only load enough of each asset to determine the size (bytes) of each asset so that it can accurately report the percentLoaded_num, getBytesLoaded() and getBytesTotal(), then it loops back through from the beginning and finishes all the preloading. If you're not going to use a preloader status bar that polls these methods/properties, you can just set the trackProgress_boolean property to false to skip that initial delay.
Objectives
- Provide an easy way to sequentially preload assets.
- Determine the _width and _height of any preloaded SWFs or image assets as well as the duration of any FLV assets.
- For easy status reporting, provide percentLoaded_num, getBytesLoaded() and getBytesTotal() information for the entire group of assets in any PreloadAssetManager instance.
- Allow for any asset to be prioritized in the loading queue at any time (for example, if the user clicks on something that requires an asset that hasn't loaded yet).
- Allow the entire queue to be paused and resumed at any time (if, for example, you need to perform some other bandwidth-intensive action)
- Build in the ability to call any function when either a particular asset has finished preloading or when a group of assets have finished preloading and allow the developer to pass any number of arguments/parameters to that function.
- If an asset cannot be loaded, implement a timeout procedure so things don't get hung up indefinitely.
Usage
- Description: Constructor. If you pass in an assetUrls_array, it will automatically call the start() function and begin preloading. You can pause() if you want.
- Arguments:
- assetUrls_array: [optional] An array of urls that should be preloaded
- onComplete_func: [optional] A reference to a function that you'd like to call as soon as all of the assets in this PreloadAssetManager instance have been preloaded.
- onCompleteArguments_array: [optional] An array of arguments to pass the onComplete_func function.
- trackProgress_boolean: [optional] true by default. If you're NOT going to use a preloader status bar that polls the precentLoaded_num, getBytesLoaded() or getBytesTotal(), set this value to false to skip that initial delay and speed things up.
- Description: Adds an asset to the PreloadAssetManager's queue.
- Arguments:
- url_str: The url of the asset that needs to be preloaded
- onComplete_func: [optional] A reference to a function that you'd like to call as soon as this asset has been preloaded.
- onCompleteArguments_array: [optional] An array of argument values to pass the onComplete_func function.
- Description: Adds an asset to the PreloadAssetManager's queue.
- Arguments:
- assetUrls_array: An array of URLs that need to be preloaded
- onComplete_func: [optional] A reference to a function that you'd like to call as soon as all of the assets in this PreloadAssetManager have been preloaded.
- onCompleteArguments_array: [optional] An array of argument values to pass the onComplete_func function.
- start_boolean: [optional] false by default. If true, the PreloadAssetManager will be forced to start preloading as soon as these assets have been added.
- Description: Starts preloading the assets (same as resume() if things are paused).
- Description: Resumes all preloading.
- Description: Pauses preloading in ALL PreloadAssetManagers.
- Description: A STATIC method that allows you to prioritize a particular asset (bump it up to the top of the queue). You can also use the non-static prioritizeAsset() method or the PreloadAsset.prioritize() method to perform a similar action.
- Arguments:
- url_str: The URL of the asset that should be prioritized.
- Description: A STATIC method that allows you to find the PreloadAsset instance with a particular URL. This is useful if you want to find the _width or _height or duration of an asset but only know the URL.
- Arguments:
- url_str: The URL of the asset you'd like to find.
Examples
To preload 2 SWFs ("myFile1.swf" and "myFile2.swf") and then call a function named onFinish(), do:
-
import gs.dataTransfer.PreloadAssetManager;
-
var preloader_obj = new PreloadAssetManager(["myFile1.swf","myFile2.swf"], onFinish);
-
function onFinish(pl_obj:PreloadAssetManager):Void {
-
trace("Finished preloading all " + pl_obj.assets_array.length + " assets!");
-
var a = pl_obj.assets_array;
-
for (var i = 0; i <a.length; i++) {
-
if (a[i].fileType_str == "flv") {
-
trace("--Asset: "+a[i].url_str+" had a duration of: "+a[i].duration);
-
} else {
-
trace("--Asset: "+a[i].url_str+" had a width of: "+a[i]._width+", and a height of "+a[i]._height);
-
}
-
}
-
}
Or if you want to have more granular control, you can create add each one to the PreloadAssetManager and then query properties like preloaded_boolean, _width, or _height individually like:
-
import gs.dataTransfer.PreloadAssetManager;
-
import gs.dataTransfer.PreloadAsset;
-
var preloader_obj = new PreloadAssetManager();
-
var pl1_obj = preloader_obj.addAsset("myFile1.swf", onPreload);
-
var pl2_obj = preloader_obj.addAsset("myFile2.swf", onPreload);
-
preloader_obj.start();
-
function onPreload(pl_obj:PreloadAsset):Void {
-
trace("finished preloading: "+pl_obj.url_str+", _width: "+pl_obj._width+", _height: "+pl_obj._height);
-
}
You can query the percentLoaded_num property to find out the status at any time (very useful for building
preloader progress bars) like so:
-
import gs.dataTransfer.PreloadAssetManager;
-
var preloader_obj = new PreloadAssetManager(["myFile1.swf","myFile2.swf"]);
-
this.onEnterFrame = function() {
-
myPreloader_mc.bar_mc._xscale = preloader_obj.percentLoaded_num;
-
if (preloader_obj.percentLoaded_num == 100) {
-
gotoAndPlay("start");
-
}
-
}
Need help?
Feel free to post your question on the forums. You'll increase your chances of getting a prompt answer if you provide a brief explanation and include a simplified FLA file (and any class files) that clearly demonstrates the problem.
Comments (25)

Great Class!
How do I resolve the scope in an onFinish function?
coverMC = target.createEmptyMovieClip(“cover”,target.getNextHighestDepth());
var preload_obj = new PreloadAsset(coverImage, onFinish);
function onFinish(asset_obj:PreloadAsset):Void {
trace(“Finished preloading: “+ asset_obj.url_str+” and its width is: “+asset_obj._width+” and its _height is: “+asset_obj._height);
trace(this);
// here I want to load in coverMC
}
how do I load the preloadAsset into coverMC when onFinish is called?
If you want to control the scope of the onFinish call, I’d recommend using the mx.utils.Delegate class that comes with Flash. Then to load your asset into coverMC, you could use something like loadMovie() So your edited code would be:
import mx.utils.Delegate;
coverMC = target.createEmptyMovieClip(â€coverâ€,target.getNextHighestDepth());
var preload_obj = new PreloadAsset(coverImage, Delegate.create(this, onFinish));
function onFinish(asset_obj:PreloadAsset):Void {
trace(â€Finished preloading: “+ asset_obj.url_str+†and its width is: “+asset_obj._width+†and its _height is: “+asset_obj._height);
trace(this);
coverMC.loadMovie(asset_obj.url_str);
}
Preloading works super fine! Thank you very much for this class.
I am preloading a bunch of FLVs. Once they get at 100%, how do I access them using a NetStream object (or other) ?
(I need to implement something that initates the playback of the first one, when it reaches the end I must start the second one, so on…)
Leolea, this class simply preloads your assets into your browser’s cache; it is not meant to be used to play back and manage your FLVs once they’re preloaded. There’s nothing special that you need to do in order to access the preloaded FLVs – just call them as you normally would either using a NetStream object of your own or an FLVPlayback component or whatever. The user’s browser will be smart enough to used the cached versions instead of going out to the web and downloading them again.
Hmmm. A little customization might be necessary for streaming FLV handling. An ideal FLV preloader might wait until the currently-streaming FLV is fully cached before loading an FLV in the background.
If the user requests a new FLV, it would ideally halt the bg-downloading stream and resume it after the requested FLV was fully cached. That assumes it’s possible to halt (and resume) a stream?
If the user requests the background-loading FLV, it’d need to be swapped into the playback area without re-starting that netstream from the beginning.
Has anyone out there tried something like this?
Gabriel, the issues you bring up are exactly why I built this class. It’s very easy to pause preloading and resume it anytime you want (see the pause() and resume() functions) so that you can manage the user’s bandwidth efficiently. You can also prioritize any asset anytime based on what the user clicks on. So if asset #2 is currently preloading, but the user clicks on something that requires asset #6 (which hasn’t been preloaded yet), you can prioritize it immediately (see the prioritize() function).
I definately like thought of being able to prioritize, pause and resume the loading of assets.
After a little investigating, it seems like Flash can’t resume downloading a half-cached FLV? It just starts the stream over from scratch. This can make pausing and resuming the queue a frustrating experience–if the currently-playing clip ends before the preloading clip is finished, the preloading clip is flushed and then starts loading again from the beginning.
It’s not a flaw in your preloader, so much as it is a difficulty with FLV caching. Ideally, we should be able to pause the video stream itself (pause buffering), then resume it later (resume buffering). If we could drop the currently-preloading clip into the video object without re-starting the stream (allowing it continue buffering from where it is), but still start playing from the beginning, we’d be set.
Hi! This class has made my life much easier… I have a couple of questions, though:
1. Is there a way to get the width/height of the FLV, alongside the duration?
2. Do you anticipate adding an XML option to this class? For example, the ability to load ANY kind of file… images, xml, swfs, flvs, etc.
Thanks, great job!
-nick
Nicolas, I just added the ability for the width, height, videodatarate, framerate, audiodatarate, and basically all of the available meta data in an FLV to be read in when it preloads. The sample is updated too. Keep in mind that not all FLVs have this meta data available – it depends on the software you used to encode the FLV. Sorenson Squeeze seems to do a good job, but several other software packages omit most of the meta data in which case this class obviously won’t be able to grab it.
Enjoy!
Great class.
Implemented it in a project we just did requiring preloading a number of FLVs (user has to disconnect their internet connection in the middle of a set of videos). Worked like a charm.
Thanks.
Is there a way to destroy the PreloadAssetManager object or will simply deleting the var kill any preloads that may currently exist?
Thank you!
Krom, you can call the destroy() method on your PreloadAssetManager instance. Or if you want to pause ALL preloading that’s being handled by any/all PreloadAssetManagers, just call the static PreloadAssetManager.pauseAll() method.
Please keep in mind that PreloadAssetManager is meant to preload assets, not buffer video. So if you have a 10 minute FLV and want to buffer 2 minutes of it before playing it, use a NetStream and its bufferTime property instead of PreloadAssetManager. My class simply leverages the browser’s cache to do its magic, but in order to work properly, it needs to fully download an asset. If you download 20% of an FLV using PreloadAssetManager and then try to play that on the screen, Flash will request the file from the browser which will in turn check its cache and since it’s not fully there, it’ll make the request from the server and start the load over again. Not ideal by any means.
Very useful.
Is there any way to get the percentLoaded_num of an individual asset?
I want to build separate progress bars for each asset.
Mark,
You can check the progress of any asset after you’ve added it to the PreloadAssetManager. For example, to check the status of a file named “myURL.swf”, do something like:
var asset_obj = PreloadAssetManager.getAsset(“myURL.swf”);
var percentLoaded_num = (asset_obj.getBytesLoaded() / asset_obj.getBytesTotal()) * 100;
I’m just now starting to learn some of the more advanced functions of actionscript and I’m pretty sure that I’ve got the hang of this class but I have a question that will hopefully clear some things up for me.
Say I’ve got a movieclip that loads a random jpg from a list as a “background” so, in order to make sure that the background comes up without a hitch, I have to have all of the backgrounds loaded. My question is whether or not I should use loadMovie to get the jpg into the movieclip or some other function now that the jpg has already been preloaded. Also, should I be referring to the PreloadAssetManager’s array_asset for the src of the image now or just stick with the original url?
I may just be missing something but, I’ll preload the backgrounds and when I go to load the image, I notice in the bandwidth profiler that the swf has requested the file again even though the file should be cached.
Whatever help you can provide would be greatly appreciated.
Yes, you’ve got it right, Stephen – you need to use loadMovie() (or its equivalent) to load your background images into place. PreloadAssetManager is ONLY meant to get the assets into your browser’s cache, nothing more. And that also explains why Flash’s bandwidth profiler is requesting the file again. That’s to be expected, and that’s exactly what the browser does too, but since it checks its cache FIRST before hitting the server again, it finds the asset(s) and loads them from there for much snappier performance. Again, PreloadAssetManager leverages the BROWSER’S cache but Flash’s bandwidth profiler doesn’t.
Thank Goodness.
Spent the whole day looking for a sollution. This one works.
YOU ROCK!
awesome, i was starting to implement a simple version of this and happened across yours, does everything i want and does it very well
will be sure to let you know of the project url when it’s done! thank you for saving my time
Hi,
I would like to know if this preloading asset exist for AS3 ?
if it doesn’t, will u think about converting this asset for AS3 ?
Thanks for ur time if you could answer on my email. it would be great.
I’ll probably port this to AS3 when I get a project that requires it. I’m not entirely sure when that’ll be though.
Jack, thanks for the code. I got it to work (took a while because I’m novice and never worked with custom classes before). I’ll be spreading the good word about your blog and generous sharing. Thanks again.
Buddy you are a genius. This is by far the best preloader I’ve come across.
Hi,
RE AS3 integration.
I guess we can use this on a preload page to cache as3 assets.
ie
preload.html
_as2 preload assets (AS3.swfs)
_onComplete ( getURL( “next.html” )
next.html
_AS3 assets
yes?
Thanks i love this class. I train my students to use it in managing their flash frameworks.
Oyster
for some who were looking for a AS3 solution, I just found this
http://code.google.com/p/bulk-loader/
it looks pretty good, I have not dug into it seriously yet.
Hope you do not mind me posting an alternative Jack, but it seemed from your comments that you were not likely to be doing an AS3 solution anytime soon.







