tags:

views:

1664

answers:

1

Hi,

I need to play SWF files in my project. These SWF files have background music in them. The which Sound Sync Options of this music in Flash is set to "stream". This is done so that if you pause the Flash movie, the music will pause as well.

Now I have a problem when I am loading these SWF files. For this I am using an SWFLoader.

When I load it, the audio of the SWF starts playing already, but no visuals of the movie are shown for a certain time. The slower your connection is, the longer it takes before visuals of the movie is shown. The audio and visuals are in sync, that is good, however, the first frames of the flash movie are simply not displayed.

I tried to solve this by adding an eventListener to make sure that the movie is fully loaded before it starts to play. However, when I do this (code below), for a fraction of a second the music plays, then stops, and restarts when the movie is fully loaded.

What is the best way to solve this problem? Am I on the right track with the ProgressEvent.PROGRESS eventlistener?

Some code:

private function loadSWF():void
{
    swfLoader.source = source;
    swfLoader.addEventListener(ProgressEvent.PROGRESS, loadProgress);
    swfLoader.addEventListener(Event.COMPLETE, startSWF);
    swfLoader.load();
    var soundTransform:SoundTransform = new SoundTransform(0);
    swfLoader.soundTransform = soundTransform;
}

private function loadProgress(event:ProgressEvent):void
{
    applicationModel.addToConsoleOutput("SWFPlayer.loadProgress(): " + event.bytesLoaded + " of " + event.bytesTotal + "bytes loaded");
    if (MovieClip(swfLoader.content) && event.bytesLoaded < event.bytesTotal)
    {
        MovieClip(swfLoader.content).gotoAndStop(0);
        var soundTransform:SoundTransform = new SoundTransform(0);
        swfLoader.soundTransform = soundTransform;
    }
}

private function startSWF(event:Event):void
{
    swfLoader.removeEventListener(ProgressEvent.PROGRESS, loadProgress);
    swfLoader.removeEventListener(Event.COMPLETE, startSWF);
    dispatchEvent(new Event("loadComplete", true));

    var soundTransform:SoundTransform = new SoundTransform(volume);
    swfLoader.soundTransform = soundTransform;

    cardMovieClip = MovieClip(swfLoader.content);
    cardMovieClip.addEventListener(Event.ENTER_FRAME, endSWFHandler);
    cardMovieClip.gotoAndPlay(0);
}
+3  A: 

SWF file are streamed so they can start playing without having to load the full file.

1) You can add in your loaded source file a stop() on the first frame to avoid the playing, and then in your main loader when the load is complete add a call to gotoAndPlay on the movie loaded to the frame you want your movie start from.

2) You can try to delegate the load to an URLLoader and then use a Loader.loadBytes when the first one is complete.

This is pure AS3, but you can adapt for FLEX Framework where you are using a SWFLoader:

// child who hold the stuff to be loaded
var holder:MovieClip=new MovieClip();
addChild(holder);

// the loader used to load byte within the holder
var holderLdr:Loader=new Loader();
holder.addChild(holderLdr);


function load(url:String):void {
 var ldr:URLLoader=new URLLoader();
 ldr.dataFormat=URLLoaderDataFormat.BINARY;
 ldr.addEventListener(Event.COMPLETE, onComplete);
 ldr.load(new URLRequest(url));
}

function onComplete(e:Event):void {
    var ldr:URLLoader=URLLoader(e.target);

    ldr.removeEventListener(e.type, onComplete);

    if (holderLdr.hasOwnProperty("unloadAndStop")){
     holderLdr["unloadAndStop"]();
    } else {
     holderLdr.unload();
    }
    holderLdr.loadBytes(ldr.data);
    ldr.data=null;
}

load("mySWF.swf");
Patrick
Ok, that seems to work OK and is a good workaround.Thanks for that, I will implement that in the FLAs I have so far.However, most of the SWF content gets provided by several different content providers. So if it is possible I would rather handle it in the Flex application completely, rather than having the providers to put this in the code as I will than have less control over it. So if there is a Flex solution, please help ;)
Mad Oxyn
I have modify my answer with another way to proceed
Patrick
Hi Patrick,I have implemented the URLLoader and loadBytes() as you suggested above, however now I cannot call any functions inside the MovieClip that was loaded, nor I can set the height and width of the MovieClip. Do you know if I can still do that and how?
Mad Oxyn
You have to check security policy, if the swf don't come from your domain or not from a domain with a cross domain policy you will not be abble to full control them. If the content is trusted you can load it into your own application sand box using the LoaderContext parameter. var context:LoaderContext = new LoaderContext(); context.applicationDomain = ApplicationDomain.currentDomain;context.applicationDomain = new ApplicationDomain();ldr.load(new URLRequest(url), context)`
Patrick