Copy link to clipboard
Copied
Hi guys,
I've made an app that uses a lot of sound and image files and i've set up a function to preload these files before running the program to ensure smooth running on my program. There is about 10mb of image and sound clips
When running the app locally obviously everything preloads very quickly (around 10 seconds), however when i've uploaded it to a server it takes about a minute or so to preload 10mb of files. Sure this can't be right?
Here's my code:
function preLoaderSound():void
{
snd1 = new Sound(new URLRequest(this["array"+k][0]
snd1.addEventListener(Event.COMPLETE, preLoadComplete);
}
function preLoaderImages():void
{
image1.url = this["array" + k]
imageLoader1.load(image1);
imageLoader1.contentLoaderInfo.addEventListener(Event.COMPLETE, preLoadComplete);
}
preLoadComplete increments k, l and m and keeps track of how many files have been loaded
Can anyone help?
Cheers
Chris
Taking into consideration your data structure and not getting into the topic of it needs improvements, here is a blueprint of bulk loading based on your arrays.
Please note, this code assumes that the only objective is to preload all assets in the beginning and then use them from cache. If you want to make you application more efficient - you may want to store loaded assets elsewhere and access them as needed. But this is a different topic.
I tried to comment code as much as possible.
...import flash.
Copy link to clipboard
Copied
what's your download speed?
and you need to show how you're incrementing k,l,m.
Copy link to clipboard
Copied
My download speed is 30mbps
In this function there are arrays 1 to 6 (named array1, array2...etc) with sound stored in array1[0] and images stored in array1[1-4]. The letters used to increment correlate to: arrayk
function preLoadComplete(e:Event):void
{
if(e.currentTarget == snd1)
{
sndCount++;
trace("sndCount " + sndCount);
check.text = sndCount.toString();
if(m < (this["array" + k]
{
m++;
preLoaderSound();
}
else
{
m = 1;
if(k < 6)
{
k++;
preLoaderSound();
}
else
{
m = 1;
k = 1;
l = 1;
preLoaderImages();
return;
}
}
}
else
{
imgCount++;
trace("imgCount " + imgCount);
check.text = imgCount.toString();
if(m < (this["array" + k]
{
m++;
preLoaderImages();
}
else
{
m = 1;
if(l<4)
{
l++;
preLoaderImages();
}
else
{
l = 1;
if(k < 6)
{
k++;
preLoaderImages();
}
else
{
imageLoader1.contentLoaderInfo.removeEventListener(Event.COMPLETE, preLoadComplete);
choose();
return;
}
}
}
}
Copy link to clipboard
Copied
Looks like you load assets sequentially.
I suggest you loads them in a single burst - all at once. The thing is that you can send several http request simultaneously (depending on a platform there is limit to how many simultaneous http requests can be processed at the same time - but this is not important because extra requests will be queued).
The point is that sending several simultaneous requests improves load time dramatically.
Copy link to clipboard
Copied
Yeah they are loaded sequentially
To load them all at once would that involve having a loader and url variable for each image and a sound variable for each sound?
Copy link to clipboard
Copied
Yes, you will need separate loader instances but you can deal with them in a dynamic manner.
Give me an example of your sound and image arrays and I will try to show how to deal with bulk loading conceptually.
Copy link to clipboard
Copied
This is an example of one of the 2D array, there are many of these 2D arrays
var array1:Array = new Array();
array1[0] = ["","GuitarMicArray/Center.mp3","GuitarMicArray/15.mp3",
"GuitarMicArray/45.mp3", "GuitarMicArray/60.mp3",
"GuitarMicArray/90.mp3"];
array1[1] = ["", "MicPics/SM57.jpg", "MicPics/SM57.jpg",
"MicPics/SM57.jpg", "MicPics/SM57.jpg",
"MicPics/SM57.jpg"];
array1[2] = ["", "MicPosPics/Center.jpg", "MicPosPics/15.jpg", "MicPosPics/45.jpg",
"MicPosPics/60.jpg", "MicPosPics/90.jpg"];
array1[3] = ["", "GuitarPic/LesPaul.jpg", "GuitarPic/LesPaul.jpg", "GuitarPic/LesPaul.jpg",
"GuitarPic/LesPaul.jpg", "GuitarPic/LesPaul.jpg",];
array1[4] = ["", "AmpPics/Marshall.jpg", "AmpPics/Marshall.jpg", "AmpPics/Marshall.jpg",
"AmpPics/Marshall.jpg", "AmpPics/Marshall.jpg",];
Copy link to clipboard
Copied
A couple of more questions.
What is the connection between images and sounds if any? If there is connection - what are the consequences of loading process in the context of this coupling of sounds and images?
Also, do you populate these arrays manually?
Copy link to clipboard
Copied
The connection is when I play a sound 4 images get displayed with the sound. I.e. If the sound is array1[0][1] then images array1[1-4][1] would also load
And yes it is all declared manually in my program (I guess i could also have done it in XML?)
Copy link to clipboard
Copied
Also, what is this coma as the first element of the array? What is it's meaning?
Copy link to clipboard
Copied
Opps, I meant empty string as the first element of each array.
Copy link to clipboard
Copied
You know what, I think thats a mistake that i've copied through
Copy link to clipboard
Copied
Hold on. I will show you something in a few minutes.
Copy link to clipboard
Copied
Taking into consideration your data structure and not getting into the topic of it needs improvements, here is a blueprint of bulk loading based on your arrays.
Please note, this code assumes that the only objective is to preload all assets in the beginning and then use them from cache. If you want to make you application more efficient - you may want to store loaded assets elsewhere and access them as needed. But this is a different topic.
I tried to comment code as much as possible.
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.media.Sound;
import flash.net.URLRequest;
var array1:Array;
var array2:Array;
/**
* Number of arrays with convention array<int> in the scope
*/
var numArrays:int = 2;
/**
* Total umber of assets to load
*/
var numAssets:int = 0;
init();
function init():void
{
array1 = new Array();
array2 = new Array();
array1[0] = ["", "GuitarMicArray/Center.mp3", "GuitarMicArray/15.mp3", "GuitarMicArray/45.mp3", "GuitarMicArray/60.mp3", "GuitarMicArray/90.mp3"];
array1[1] = ["", "MicPics/SM57.jpg", "MicPics/SM57.jpg", "MicPics/SM57.jpg", "MicPics/SM57.jpg", "MicPics/SM57.jpg"];
array1[2] = ["", "MicPosPics/Center.jpg", "MicPosPics/15.jpg", "MicPosPics/45.jpg", "MicPosPics/60.jpg", "MicPosPics/90.jpg"];
array1[3] = ["", "GuitarPic/LesPaul.jpg", "GuitarPic/LesPaul.jpg", "GuitarPic/LesPaul.jpg", "GuitarPic/LesPaul.jpg", "GuitarPic/LesPaul.jpg"];
array1[4] = ["", "AmpPics/Marshall.jpg", "AmpPics/Marshall.jpg", "AmpPics/Marshall.jpg", "AmpPics/Marshall.jpg", "AmpPics/Marshall.jpg"];
array2[0] = ["", "GuitarMicArray/Center.mp3", "GuitarMicArray/15.mp3", "GuitarMicArray/45.mp3", "GuitarMicArray/60.mp3", "GuitarMicArray/90.mp3"];
array2[1] = ["", "MicPics/SM57.jpg", "MicPics/SM57.jpg", "MicPics/SM57.jpg", "MicPics/SM57.jpg", "MicPics/SM57.jpg"];
array2[2] = ["", "MicPosPics/Center.jpg", "MicPosPics/15.jpg", "MicPosPics/45.jpg", "MicPosPics/60.jpg", "MicPosPics/90.jpg"];
array2[3] = ["", "GuitarPic/LesPaul.jpg", "GuitarPic/LesPaul.jpg", "GuitarPic/LesPaul.jpg", "GuitarPic/LesPaul.jpg", "GuitarPic/LesPaul.jpg"];
array2[4] = ["", "AmpPics/Marshall.jpg", "AmpPics/Marshall.jpg", "AmpPics/Marshall.jpg", "AmpPics/Marshall.jpg", "AmpPics/Marshall.jpg"];
preloadAssets();
}
function preloadAssets():void
{
/**
* 1. Since mime types are mixed up in the same data provider - we should separate mime types into different more logical entites
* 3. Since array contain redundant assets - we shoul avoid loading assets more than once
* 2. We should define how many assets to be loaded
*/
var sounds:Array = [];
var images:Array = [];
for (var i:int = 1; i <= numArrays; i++)
{
// gain reference to array
var array:Array = this["array" + 1];
// loop through second dimensions
for each (var subArray:Array in array)
{
// loop through elements in the seond dimension
for each (var url:String in subArray)
{
/**
* We need additional validation
* 1. Make shure that current element is not an empty string
* 2. Identify mime type base on file extension
*/
// only if it is not an empty string - proceed
if (url != "")
{
// increment number of assets that must be loaded
numAssets++;
// populate either sounds or image array
// url.match(/(\w+)$/gi) extracts file extension
switch (url.match(/(\w+)$/gi)[0])
{
case "jpg":
// push image url into array of images urls
// if url is not present - push it
if (images.indexOf(url) == -1)
{
images.push(url);
}
break;
case "mp3":
// puch sound url into the array of aounds urls
// add only if url does not exist int ht e array
if (sounds.indexOf(url) == -1)
{
sounds.push(url);
}
break;
}
}
}
}
}
// at this point we are ready to load all assets
// invoke images loading
for each (url in images)
{
trace("image", url);
var loader:Loader = new Loader();
addListeners(loader.contentLoaderInfo);
loader.load(new URLRequest(url));
}
// invoke sounds loading
for each (url in sounds)
{
trace("sound", url);
var sound:Sound = new Sound();
addListeners(sound);
sound.load(new URLRequest(url));
}
}
function onError(e:IOErrorEvent):void
{
trace("error", e.target);
removeListeners(e.target as EventDispatcher);
}
/**
* Adds loading related listeners
* @param ed
*/
function addListeners(ed:EventDispatcher):void
{
ed.addEventListener(Event.COMPLETE, onLoadComplete);
ed.addEventListener(IOErrorEvent.IO_ERROR, onError);
}
/**
* Removes loading related listeners
* @param ed
*/
function removeListeners(ed:EventDispatcher):void
{
ed.removeEventListener(Event.COMPLETE, onLoadComplete);
ed.removeEventListener(IOErrorEvent.IO_ERROR, onError);
}
function onLoadComplete(e:Event):void
{
// remove listeners
removeListeners(e.target as EventDispatcher);
// decrement numAssets
numAssets--;
// when all assets are loaded - numAssets is zero
if (numAssets == 0)
{
// all assets are loaded and we can go ahead with the rest of application
}
}
Message was edited by: Andrei1
Copy link to clipboard
Copied
I made additional changes - forgot to tender to redundant urls the first time I posted the code.
Copy link to clipboard
Copied
Ah that's brilliant, and makes sense too!
One question, how would you have done my data structure for this program?
Copy link to clipboard
Copied
I know little about your program but based on your description of how sounds relate to images there is a simple one-to-many relationship.
As you said, XML would be a better choice because
a. it is a structure
b. it is more readable than arrays and objects
c. as a consequence of (b) - it is easier editable
d. it is scalable
e. as an extension of (d) - it is suitable for being written internally in the program or loaded at runtime. In both cases data consuming/processing mechanism remains the same.
But there is nothing wrong with using AS3 objects.
Your data may look like this - it is less ambiguous and more readable/editable. At least it reflects one-to-many relationships.
var tracks:Array = [];
tracks[0] = {sound: "GuitarMicArray/Center.mp3", images: ["MicPics/SM57.jpg", "MicPosPics/Center.jpg", "GuitarPic/LesPaul.jpg", "AmpPics/Marshall.jpg"]};
tracks[1] = {sound: "GuitarMicArray/15.mp3", images: ["MicPics/SM57.jpg", "MicPosPics/15.jpg", "GuitarPic/LesPaul.jpg", "AmpPics/Marshall.jpg"]};
tracks[2] = {sound: "GuitarMicArray/45.mp3", images: ["MicPics/SM57.jpg", "MicPosPics/45.jpg", "GuitarPic/LesPaul.jpg", "AmpPics/Marshall.jpg"]};
tracks[3] = {sound: "GuitarMicArray/60.mp3", images: ["MicPics/SM57.jpg", "MicPosPics/60.jpg", "GuitarPic/LesPaul.jpg", "AmpPics/Marshall.jpg"]};
tracks[4] = {sound: "GuitarMicArray/90.mp3", images: ["MicPics/SM57.jpg", "MicPosPics/90.jpg", "GuitarPic/LesPaul.jpg", "AmpPics/Marshall.jpg"]};
Also, I don't know if there is any special meaning behind image url position in the array of images. If position is an instruction to, say, display it in some particular way - you may be better off going beyond reliance on array element index.
Copy link to clipboard
Copied
Also, I have noticed that in your example three images are shared by all sounds. If these three images are shared by all sounds in all arrays - perhaps it is worth moving them elsewhere?
In addition, here is how XML may look like:
<?xml version="1.0" encoding="utf-8" ?>
<data>
<tracks>
<track>
<sound><![CDATA[/Center.mp3]]></sound>
<images>
<image index="0"><![CDATA[MicPics/SM57.jpg]]></image>
<image index="1"><![CDATA[MicPosPics/Center.jpg]]></image>
<image index="2"><![CDATA[GuitarPic/LesPaul.jpg]]></image>
<image index="3"><![CDATA[AmpPics/Marshall.jpg]]></image>
</images>
</track>
<track>
<sound><![CDATA[GuitarMicArray/15.mp3]]></sound>
<images>
<image index="0"><![CDATA[MicPics/15.jpg]]></image>
<image index="1"><![CDATA[MicPosPics/Center.jpg]]></image>
<image index="2"><![CDATA[GuitarPic/LesPaul.jpg]]></image>
<image index="3"><![CDATA[AmpPics/Marshall.jpg]]></image>
</images>
</track>
<track>
<sound><![CDATA[GuitarMicArray/45.mp3]]></sound>
<images>
<image index="0"><![CDATA[MicPics/45.jpg]]></image>
<image index="1"><![CDATA[MicPosPics/Center.jpg]]></image>
<image index="2"><![CDATA[GuitarPic/LesPaul.jpg]]></image>
<image index="3"><![CDATA[AmpPics/Marshall.jpg]]></image>
</images>
</track>
<track>
<sound><![CDATA[GuitarMicArray/60.mp3]]></sound>
<images>
<image index="0"><![CDATA[MicPics/60.jpg]]></image>
<image index="1"><![CDATA[MicPosPics/Center.jpg]]></image>
<image index="2"><![CDATA[GuitarPic/LesPaul.jpg]]></image>
<image index="3"><![CDATA[AmpPics/Marshall.jpg]]></image>
</images>
</track>
<track>
<sound><![CDATA[GuitarMicArray/90.mp3]]></sound>
<images>
<image index="0"><![CDATA[MicPics/90.jpg]]></image>
<image index="1"><![CDATA[MicPosPics/Center.jpg]]></image>
<image index="2"><![CDATA[GuitarPic/LesPaul.jpg]]></image>
<image index="3"><![CDATA[AmpPics/Marshall.jpg]]></image>
</images>
</track>
</tracks>
</data>
Edited: you will need CDATA enclosure in node values.
Copy link to clipboard
Copied
Yeha next time I shall use XML, would make a lot more sense
Thanks for your help though!
Cheers
Chris
Find more inspiration, events, and resources on the new Adobe Community
Explore Now