Jump to content
Search Community

Loading Multiple SWFs at once, but playing them sequentially

averagejoe77 test
Moderator Tag

Recommended Posts

I am fairly new to Flash and ActionScript, so go easy on me please... ;)

 

I have a really large FLV file that I have to import into the timeline and add in some custom functionality. I have chopped the FLV into smaller FLV files and imported them into the timeline of several FLAs in an attempt to make several SWFs.

 

I need all the SWFs to load, which LoaderMax does perfectly, but I cannot figure out how to get the SWFs to play in sequence one at a time. Currently, once the SWFs have loaded, they are all placed on the stage one on top of the other, with the last SWF being on top, and they all play at the same time. I am using the Parse_Array class from the Meet LoaderMAx video series to load in the SWFs.

 

I am assuming that I need to change the way the _queueCompleteHandler handles the loaded SWFs, but I am not sure how. If anyone could help out on this it would greatly appreciated.

 

Joe.

Link to comment
Share on other sites

Hmm... this is what I have so far and it seems to play through ok

 

Main.swf (frame 1) looks like this:

 

import com.greensock.*;
import com.greensock.events.LoaderEvent;
import com.greensock.loading.*;
import com.greensock.loading.display.*;
import flash.events.Event;

var queue = new LoaderMax({name:"mainLoader", onProgress:progressHandler, onComplete:completeHandler, onError:errorHandler});
queue.append( new SWFLoader("part1.swf", {name:"part1", estimatedBytes:5542000, container:this, autoPlay:false}) );

LoaderMax.prioritize("part1");

queue.load();

 

I left out all the handler functions for now cause they aren't really doing anything right now.

 

Then I added another call to the SWFLoader on the last frame of each of the SWFs like so:

 

part1.swf (code on the last frame of the timeline)

import com.greensock.loading.SWFLoader;
stop();

if(this.currentFrame == this.totalFrames)
{
var part2Loader = new SWFLoader("part2.swf",{autoPlay:true, container:this, requireWithRoot:this.root});
part2Loader.load();
}

 

Then all the subsequent parts are the same with the number incrementing by 1 for each new part.

 

seems to be working ok so far. Before I upload this to the web I am going to take a stab and say that by using LoaderMax on the first frame of the Min.swf, the subsequent SWFLoader calls will all be handled by it, so calling them again in the last frame of the timeline won't really make a difference because they should already be loaded... right?

Link to comment
Share on other sites

Yeah when the SWFLoader on the last frame of your loaded swf loads it should get the previously loaded version from the browser cache. I'm 99% certain of that.

 

instead of putting unique code on the last frame of every loaded swf in the main swf you could have an ENTER_FRAME handler that checks to see if the swf that is currently playing is on the its last frame... if so increment your swf counter and play the next swf.

 

something like:

 


function checkSWFFrame(e:Event):void{
if(currentLoader.rawContent.currentFrame == currentLoader.rawContent.totalFrames){
swfCount++
currentLoader = LoaderMax.getLoader("part" + swfCount);
}

}

 

the above is incomplete and un-tested just to illustrate the basic idea.

Link to comment
Share on other sites

I have no idea what is wrong here, but apparently my completeHandler is being fired instantly, and nothing is being preloaded at all.

 

Adding the SWFLoader to the end of each SWF is causing the next SWF to not load until that last frame of the SWF before it, needless to say there is a noticeable delay in each SWF as it loads while playing.

 

Also my progressHandler that is supposed to advance the preloader movie clip is not doing anything at all.

 

I am once again confused...

 

Main.swf (code on frame 1)

import com.greensock.*;
import com.greensock.events.LoaderEvent;
import com.greensock.loading.*;
import com.greensock.loading.display.*;
import flash.events.Event;

var queue:LoaderMax = new LoaderMax({name:"mainLoader", onProgress:progressHandler, onComplete:completeHandler, onError:errorHandler});
queue.append( new SWFLoader("part1.swf", {name:"part1", estimatedBytes:5542000, container:this, autoPlay:true}) );

queue.load();

function progressHandler(event:LoaderEvent):void
{
progress_mc.progressBar_mc.scaleX = event.target.progress;
progress_mc.progress_txt.text = event.target.progress;
}

function completeHandler(event:LoaderEvent):void
{
trace("Completed....");
}

function errorHandler(event:LoaderEvent):void
{
trace("Error occured with " + event.target + ": " + event.text);
}

 

When ever I test the Main.swf, I immediately get "Completed..." in the output window, while only 0.01... of the progress is completed. My preloader Movie Clip frame only shows for a fraction of a second then the swf begins to play, and all the subsequent SWFs after that while they load. What am I missing here?

 

edit: removed requiredWithRoot:this.root.

Link to comment
Share on other sites

now I'm getting confused. I was under the impression that you were preloading all the swfs at the beginning but I only see one loader in Main.swf that loads part1.swf.

 

Adding the SWFLoader to the end of each SWF is causing the next SWF to not load until that last frame of the SWF before it, needless to say there is a noticeable delay in each SWF as it loads while playing.

 

where are the swfs getting loaded prior to this last-frame script? I think that is the piece of the puzzle that is missing for me. Previously you stated they are all preloading fine but are playing at the same time.

 

instead of creating new SWFLoaders in the last frame of each loaded swf, you might be able to try LoaderMax.getLoader("part2.swf") and see if you can target the allegedly pre-loaded swf.

 

 

also, why does main.swf have requireWithRoot:this.root? that makes me think that Main.swf is being loaded into another swf, which I haven't seen any prior mention of.

Link to comment
Share on other sites

If I prepload all the SWFs in the first frame of Main.swf, then that is when they all get loaded on top of each other and play at the same time. the work around for that was to move the prerloading of the subsequent SWFs to the last frame of the currently playing SWF. I thought that LoaderMax would seek out any other Loaders in any subloaded SWF files and call them as well, that is why I placed them there, but apparently I misunderstood that because that is not what is happening.

 

I'll try the LoaderMax.getLoader("part2.swf") and see if that has any effect.

 

Thanks for the help. I'll be back tomorrow if it doesn't work.

Link to comment
Share on other sites

Thanks for clarifying, now I understand the progression of your different methods.

 

I thought that LoaderMax would seek out any other Loaders in any subloaded SWF files and call them as well

 

Yeah, it can't do that and now I see why you were trying those things.

 

LoaderMax is very flexible and powerful. When learning it I had a difficult time understanding all the various ways that it works and I'm still learning.

 

Don't worry about not understanding it all at once or misunderstanding some bits. Go tinker with it some more. If I have time this weekend I'll try to whip up a little example of multiple swfs playing in sequence.

 

-c

Link to comment
Share on other sites

ok, I whipped together a little demo that loads 4 swfs and plays them in succession.

http://snorkl.tv/dev/loadPlaySwfs/


when swf 4 is done it loops back to swf 1. there is no code in any of the swfs that get loaded... just timeline animation.

here is the code in the main parent fla:

import com.greensock.*;
import com.greensock.loading.*;
import com.greensock.events.LoaderEvent;
import flash.display.MovieClip;
import flash.events.Event;



var loaderIndex:Number = 0;
var currentLoader:SWFLoader;

var swfs:LoaderMax = new LoaderMax({onComplete:completeHandler,onProgress:progressHandler,onChildComplete:childCompleteHandler});

swfs.append(new SWFLoader("part1.swf", {container:container_mc, autoPlay:false}));
swfs.append(new SWFLoader("part2.swf", {container:container_mc, autoPlay:false}));
swfs.append(new SWFLoader("part3.swf", {container:container_mc, autoPlay:false}));
swfs.append(new SWFLoader("part4.swf", {container:container_mc, autoPlay:false}));

swfs.load();


function progressHandler(e:LoaderEvent):void {
progress_mc.scaleX = e.target.progress;
}




function childCompleteHandler(e:LoaderEvent):void {
trace(e.target + " loaded");
e.target.content.visible = false;

}

function completeHandler(e:LoaderEvent):void {
trace("all swfs loaded");

initCurrentLoader();
addEventListener(Event.ENTER_FRAME, trackSWFPlayback);


}

function initCurrentLoader() {

loaderIndex++;

if (loaderIndex > swfs.numChildren) {
//reset back to 1 if the last swf has already played
loaderIndex = 1;
}

//dynamically reference current loader based on value of loaderIndex

currentLoader = LoaderMax.getLoader( "part" + loaderIndex + ".swf");

//make the content of the current loader visible

currentLoader.content.visible = true;

//tell the current loader's swf to to play

currentLoader.rawContent.gotoAndPlay(1);
}


function trackSWFPlayback(e:Event):void {
//trace(currentLoader.rawContent.currentFrame);

//detect if the loaded swf is on the last frame

if (currentLoader.rawContent.currentFrame == currentLoader.rawContent.totalFrames) {

trace("swf done");

//hide and stop current swf
currentLoader.content.visible = false;

currentLoader.rawContent.stop();


//set up and play the next swf

initCurrentLoader();


}
}


cs4 files attachedloadSWFsPlaySequence.zip
Link to comment
Share on other sites

Sorry it has taken me so long to get back to you. This is very close to what I need, the only problem with it is that my swf's are at least 3MB in size, once all 8 of them have finished downloading, the video in each one plays at the same time, so the are all overlapping each other with their audio, while only the video of the last one to load in the sequence shows on top of the others.

 

I need to load them all, put play them only one at a time in sequential order. I tired to play around with your script to get it to work as I need but I am not that good the AS. Thank you for the help though.

Link to comment
Share on other sites

Hi Carl,

I was wondering whether you could help me with these swfs objects talking to each other?

Thanks for your suggestion over a Snorkl TV about connecting these TimelineMax animations swfs of mine up but I'm a bit confused to how to put your suggestion together.

I understand about having a complete function in the child swfs but I not sure how to connect up to the parent.

So if I have a function such as this one (below) in each of the child swfs, should I set out the code like this? and what sort of reference should I be calling ?

 

function swfComplete(){	
trace("Activity complete");         
///What code can I put in here that I can reference in the parent fla?///

 

Cheers,

Ben

Link to comment
Share on other sites

Hi Ben,

I worked on this a little bit yesterday.

I would suggest not having your loaded swf communicate to the parent as that would entail putting specific code in each of your loaded swfs.
It is better to have the parent detect when the loaded swf's TimelineMax has finished playing

The parent swf would have code like this:

import com.greensock.*;
import com.greensock.events.TweenEvent;
import com.greensock.events.LoaderEvent;
import com.greensock.loading.SWFLoader;



var subSwf:SWFLoader = new SWFLoader("subLoadedTimelineLite.swf", {container:this, onComplete:loadComplete});


subSwf.load();

function loadComplete(e:LoaderEvent):void{

trace("swf loaded");

//reference the TimelineMax in the loaded swf
var loadedTimelineMax:TimelineMax= e.target.rawContent.tl;


trace(loadedTimelineMax);

//track when the loaded TimelineMax is done playing
loadedTimelineMax.addEventListener(TweenEvent.COMPLETE, timelineCompleteMessage);

//tell the loaded TimelineMax to play
loadedTimelineMax.play();




}



function timelineCompleteMessage(e:TweenEvent):void{
trace("the parent has detected that the TimelineMax in the loaded swf is COMPLETE");
}

function timelineStartMessage():void{
trace("the timeline started playing and the child swf told the parent swf to display this message\n");
}



The only requirements in the swf that get's loaded are:
- it uses TimelineMax
- the TimelineMax is named tl



If you still want to have the loaded swf call a function in the parent, I put that in there too.

as3 code in subLoadedTimelineLite.fla:

import com.greensock.*;


var tl:TimelineMax = new TimelineMax({paused:true, onStart:notifyParent})

tl.append(TweenLite.to( ball_mc, 1, {x:500}) );
tl.append(TweenLite.to( ball_mc, 1, {y:200}) );
tl.append(TweenLite.to( ball_mc, 1, {x:50}) );
tl.append(TweenLite.to( ball_mc, 1, {y:50}) );


function notifyParent(){
var parentMovie:MovieClip = this.parent.parent as MovieClip;
parentMovie.timelineStartMessage();
}





files attached loadAndControlSwfWithTimelineLite.zip
Link to comment
Share on other sites

Hi Carl,

I've been able to load one swf successfully and all the animations within it work but I'm getting an output message that I thinks related to the use of TimelineLite in the child swf.

 

swf loaded

TypeError: Error #1034: Type Coercion failed: cannot convert com.greensock::TimelineLite@31c3ea19 to com.greensock.TimelineMax.

at MainSWFLoader_fla::MainTimeline/loadComplete()

at flash.events::EventDispatcher/dispatchEventFunction()

at flash.events::EventDispatcher/dispatchEvent()

at com.greensock.loading.core::LoaderCore/_completeHandler()

at com.greensock.loading::SWFLoader/_completeHandler()

first sound played

correct

one clicked

second sounds for second played

correct

two clicked

Activity complete

Activity complete

Activity complete

Activity complete

Activity complete

Activity complete

 

The swf child uses a number of different TimelineMax and TimelineLite instances so maybe that's where the conflict is?

However, the final variable that completes the action in the child swf is TimelineMax named mainOut which I've changed from tl in your code example. See code below. So I'm a little confused why i get that message above.

 

var loadedTimelineMax:TimelineMax= e.target.rawContent.mainOut;

 

Any suggestions?

Cheers,

Ben

Link to comment
Share on other sites

Hi,

 

 

Just learned about GreenSock a couple of days ago.

 

I was able to create two(2) swfs based on TweenMax and TimelineMax and it's beautiful and I was amazed at how easy it is.

 

However, I need to create a parent swf that will load the two I mentioned above plus four(4) more... sequentially.

 

So the first two is based on TimelineMax while the rest are frame-based animations.

 

I liked the approach done on "loadSWFsPlaySequence", but it tracks the progress based on frame. This doesn't seem to work with the two TimelineMax - based swfs I created.

function trackSWFPlayback(e:Event):void {
  //trace(currentLoader.rawContent.currentFrame);

//detect if the loaded swf is on the last frame
  if (currentLoader.rawContent.currentFrame == currentLoader.rawContent.totalFrames) {

     trace("swf done");

     //hide and stop current swf
     currentLoader.content.visible = false;

     currentLoader.rawContent.stop();


       //set up and play the next swf
     initCurrentLoader();
  }
}

Later on, Carl posted the "loadAndControlSwfWithTimelineLite" which tracks the playing time of a child swf.

 

//reference the TimelineMax in the loaded swf
var loadedTimelineMax:TimelineMax= e.target.rawContent.tl;

trace(loadedTimelineMax);

//track when the loaded TimelineMax is done playing
loadedTimelineMax.addEventListener(TweenEvent.COMPLETE, timelineCompleteMessage);

//tell the loaded TimelineMax to play
loadedTimelineMax.play();

 

I've been messing around with the code and sample files mentioned above, unfortunately I can't make it work. :(

 

Any ideas?

 

Thanks!

Link to comment
Share on other sites

Ok, So I solved the audio issue.

 

The only problem I am having now should be a simple fix. As each new part loads, that part is added to the container_mc movie clip and displayed. So what I end up with is part 1 loading to 100%, then part 2 starts to load and gets displayed at frame 1 on top of part 1, then part 3 at frame 1 on top of part 2, etc. Once part 8 is fully loaded, it starts part 1 back over and plays through like it should one after the other. So if I can solve this "overlapping" issue with maybe a poster image or a black background while it loads, that would be all I need.

 

Not able to get the FLAs under 1MB unfortunately. If you want to see all the files I can give you FTP access in a PM. Just let me know.

 

Thanks for you help on this btw. :)

 

EDIT: And I got it, thanks for everything Carl, you are awesome.

Link to comment
Share on other sites

  • 3 weeks later...

HI all,

Did anyone get their loading to work with LoaderMax and multiple TimelineMax based SWF's?

 

I'm trying to use Carl's very helpful "loadAndControlTimelineLite" example but it doesn't even like the 1 SWF that I'm loading, I get the following error:

VerifyError: Error #1053: Illegal override of insert in com.greensock.TimelineLite.

 

ReferenceError: Error #1065: Variable RolloverButton_29 is not defined.

 

ReferenceError: Error #1065: Variable MainTimeline is not defined.

 

I suspect that the "Variable RolloverButton_29" is because there is a button_mc on the stage that is using the timeline to play an animation, so I removed it from the stage and that ReferenceError went away, but I don't know what the other 2 problems relate to.

 

Anyone got their SWF's loaded and working?

 

Any help appreciated.

 

X10

Link to comment
Share on other sites

Hi X10,

 

I don't know what your errors are about.

 

What are you doing differently than my sample files.

 

The whole setup is built on requiring specific instance names and the timelines being built and ready to be played as soon as the child swfs load.

 

c

Link to comment
Share on other sites

Hi Carl,

Thanks for popping back into an old thread!

 

I tried a bunch of things and spent a couple of hours deleting elements and turning my Child SWF as small as possible and nothing worked. In the end I downloaded the latest Greensock code, re-published the child SWF and it worked.

 

But I wonder why that is?! There is no difference in the AS3 or the stage instances of the published file, only the greensock code of the parent and child are now the same.

 

Anyway, now that I can load a SWF using your second example, I am going to try to see how I can apply that to LoaderMax to load multiple TimelineMax based SWF's and play them in sequence on repeat.

 

X10

Link to comment
Share on other sites

Hi Carl and X10,

 

Sorry X10. I cross posted the last issues I was having on another thread: http://forums.greensock.com/viewtopic.php?f=6&t=3649&start=10

But Carl kindly posted a working example of how to LoadSwfsThatContainTimeLineMax. So please check that out!

 

I have been trying to implement this last example Carl and I'm still trying to sort of the issues. I'm not getting any compiler errors but I'm getting a number of odd behavior. I'll try to explain:

 

1. Scaling problem. The 2 swfs of mine don't size properly when loaded into the container. They are scaled up I would guess twice the size as they should be.

 

2. Swf 2 plays it first sound before it should. When the first swf loads and plays its first sound file so does the swf 2. So it is triggering the sound of the swf child 2.

 

Any ideas?

You might need to see my swf Child files to really see what's happening. Let me know.

Cheers,

Ben

Link to comment
Share on other sites

Hi Ben,

Thanks for pointing me in the right direction, that's great! Thanks also to Carl for posting another really useful example.

 

Ben, I may be able to help with the issues:

 

1) Have you set a height and width on the content display? If so the default scaleMode is stretch, which might be the issue.

If so you just need to set

scaleMode:"none"

in the SWFLoader Vars

 

2) I am wondering if this is to do with controlling the TimelineMax of the Child SWF's.

What I noticed is that Carl's examples both have {paused:true} in the Child SWF TimelineMax constructor. If you don't set this, or use a repeat, then you have overlapping issues.

 

I'm trying to figure out if there's a way to override these settings in the Child SWF's when loading them into the Parent, otherwise I'd have to go back to the Child SWF's code and edit them and re-publish - there seems like there should be a better way to do it.

 

X10

Link to comment
Share on other sites

Hi X10,

Thanks for the reply.

I'm not having much luck.

I haven't set the height and width on the content display but I inserted the scaleMode:"none" code into the SWFLoader Vars but that didn't work, the swfs are still stretching their contents up.

 

Also, I tried setting the first timeline to {paused:true} in the Child SWFs TimelineMax constructors but then the swfs didn't load on stage.

I think the issue of overlapping is a bit more complicated because in my swfs I don't just have one single TimelineMax instance in the swfs. I have one TimelineMax for the assets coming on stage & the another one to control them going off stage when the activity is competed. Whereas Carl's example uses a single TimelineMax instance in each Child swf. But by using the latter TimelineMax that completes the swfs in my situation it does seem to work, I mean once one swf is finshed the next loads.

 

So the issue is around the sound; the first sound file from the 2nd swf plays at the same time as the sound from the 1st swf plays.

And I have {autoPlay:false} in each MP3Loader instance for each sound file so that shouldn't let them play prematurely!

 

So I'm very stumped!

Any more suggestions?

Cheers,

Ben.

Link to comment
Share on other sites

Hi Ben,

Hmm, that is odd, are you setting stage height & width dynamically in your Child SWF's?

 

What happens if you try this in the Parent SWFLoader constructor (replace "MySWF.swf", "x" & "y" with your values.:

 

swfs.append(new SWFLoader("MySWF.swf", {container:container_mc, width: x, height: y,scaleMode:"none"}));

 

As to the sound playing, yes that has stumped me too, perhaps Jack will be able to give a better explanation. It might be easier if you had a simplified version of your problem attached as a zipped fla (cs4) to your next post so we could try it ourselves - it's difficult sometimes to visualise exactly how a piece of code is working.

 

X10

Link to comment
Share on other sites

Ben,

 

If you are still having trouble please start a new thread for each problem (sound, scaling) and provide the simplest files possible to demonstrate the specific problems. For example for the sound issue just provide enough to show that an MP3Loader is playing the sound even though autoPlay is set to false. By creating these small sample files there is a good chance you will discover why you are having a problem in your more complex implementation on your own.

 

Right now this multipage discussion is way too confusing to follow and make any sense of what might be the problem. It happens.

 

Carl

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...