How to get Flex SWFLoader unloadAndStop to unload sound also? - actionscript-3

public var swfLoader:SWFLoader = new SWFLoader();
[Embed(source="/some/file1.swf")]
public var file1:Class;
[Embed(source="/some/file2.swf")]
public var file2:Class;
then I do:
swfLoader.load(file1);
Later on:
swfLoader.unloadAndStop(true);
which unloads the video, but not the sound! So I add in
SoundMixer.stopAll();
Which is ok, for a while. Later on, I do:
swfLoader.load(file2);
And eventually, while watching file2, file1's audio will start playing in the background over file2's audio, with no way to stop it! What is the proper way to stop the audio of file1? The way I keep seeing is use unloadAndStop() which I am using. Unless I have to create a new swfLoader object each time?
As per Konrad's answer below, I should stop playing the sound in cleanup events, such as REMOVED_FROM_STAGE, however, how can I stop playing the sound on a swf file that is loaded with a SWFLoader? I don't see an obvious way to do that.

Solutions is bit tricky, because problem is with loaded content.
Garbage collector won't remove sound because it is still playing (so its referenced by Flash Player) but you don't have access to its sound channel (because its hidden similar to private variables in classes). That behavior is totally correct.
Solution: In loaded swf code you should stop playing that sound (in REMOVED_FROM_STAGE or other 'cleanup' event handler). Other solutions (like SoundMixer.stopAll) will work in some cases but not in all.
We often forget to clean after ours applications. Its not problem if they exist same as instance of Flash Player (removing it will clean all memory used by our swf). Problems begins when we load and unload swfs. Ignoring cleanups is fast way to memory leaks.

swfLoader.unloadAndStop(true);
Does remove the swf and the sound as well .
Works fine for me .
Even the documentation says :
Unloads an image or SWF file. After this method returns the source property will be null. This is only supported if the host Flash Player is version 10 or greater. If the host Flash Player is less than version 10, then this method will unload the content the same way as if source was set to null. This method attempts to unload SWF files by removing references to EventDispatcher, NetConnection, Timer, Sound, or Video objects of the child SWF file. As a result, the following occurs for the child SWF file and the child SWF file's display list:
Sounds are stopped.
Stage event listeners are removed.
Event listeners for enterFrame, frameConstructed, exitFrame, activate and deactivate are removed.
Timers are stopped.
Camera and Microphone instances are detached
Movie clips are stopped.

Related

Main menu on game

I have created a menu for my game with buttons and whatnot as a separate .fla file named Menu. My actual game is another .fla file called Game.fla. I was wondering what the best way would be of loading this menu before the game plays?
Thanks.
I would suggest that you create a .swc with your Menu.fla, and then just add that .swc to your Game.fla
If you are using CS6, make sure that you are setting linkage for any MovieClips you want to create instances of in your code.
In the actionscript settings on the library path tab, you can add a .swc that will be included into your .swf when compiling.
In your code, you can now create an instance and add to the display list :
// Assuming MainMenu was a movieclip with linkage set in your .swc
var mainMenu:MainMenu = new MainMenu;
addChild(mainMenu);
I should note that this does not load the .swc at runtime, it includes the .swc to your .swf at compile time. I would recommend this method over loading a .swf in most cases. Cases where I might not, is if there was a large amount of content that wasn't needed all at once. That would allow you to minimize the amount of memory you were using and reduce the .swf size of your main .swf so it loads quicker.
Anytime you are loading .swf's in at runtime you are adding another layer of complexity, so I'd not recommend it unless you do have a good reason to do so. From what you have described, this doesn't sound like a situation where I'd load an external .swf at runtime.
Load the swf output from Menu.fla and keep a check on the progressEvent from loader. Don't show the game screen until Menu.swf is completely loaded and initialized.
Some more details wrt comment from OP:
You can you http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Loader.html#load%28%29 to load external swfs. init Event would mark that the swf's actionscript has started executing. OTOH, complete event would tell that all the swf bytes have been loaded.

onLoadComplete not working with AS2 SWF loaded via AS3

So I have run into an issue and I think it is mostly because I haven't worked with as2 in about 5 years so things are pretty hazy. Anyway, my problem is that I need to display PDF files within the flash movie. To do so I have resorted to running SWFTools in my backend and converting pdfs to swf for display. SWFTools, though, outputs AS2 files which I can load into AS3 but I can't actually control (for example, calling stop()).
Thus I have resorted to using an AS2 loader which gets loaded into the AS3 project which is responsible for loading the converted pdf swfs. The problem I am running into is that the listener does not seem to be firing when I load the AS2 file in via AS3 but it fires just fine when run on it's own.
This is the code I am running. To summarize when I run this code on it's own "LOADED" correctly prints to the output and the loaded SWF stops. However, when I run it via an AS3 container the swf loads in correctly but the "LOADED" trace never occurs and the stop is not executed.
thanks so much for any help!
var loader:MovieClipLoader
var listener = new Object();
listener.onLoadComplete = function(loadedClip) {
trace("LOADED");
loadedClip.stop();
}
loadFile("data/testing.swf");
function loadFile(target){
loader = new MovieClipLoader();
loader.addListener(listener);
loader.loadClip(target, holder_mc);
}
SWF Tools does support AS3, you need to change it in the options.
1. Open your PDF in swf tools
2. Edit=>Options
3. Viewer tab
4. Check "No viewer" and flash version 9. (Or use the simple viewer)
- You can also do the "Insert stop after each frame"
I know this because I've done the same thing with a PDF. If you don't have those options, then it's time to download the latest version!

FLVPlayback clip loading delays

I'm building a narrative click-through kiosk app in Flash/AS3. Currently, there are several (10+) locally loaded .flv files that I'm loading into an FLVPlayback component on the timeline. I am experiencing loading delays and am wondering what the best practice / best case scenario for this case. These are all using the "Load external video with playback component" option for Video importing.
So far I've tried implementing it two ways:
One frame, one FLVPlayback playback on the stage named "video_player", and upon the click through / user action to switch the video, I do the following:
var new_flv:String = "next_flv.flv";
video_player.stop();
video_player.source("_flvs/"+new_flv);
video_player.seek(0);
video_player.play();
This results in delays anywhere from a few seconds to 10 seconds.
This is unconventional to me, but I used multiple frames on the timeline. Each frame had an FLVPlayback instance on the stage, each with a different relative path placed in the 'source' property in the component parameters (see http://www.ashleylovespizza.org/stuff/flv_example.png ). The code is switching between frames based on frame label and then hitting play (autoplay is off in the component parameters as well).
var new_flv_frame_name:String = "next_frame";
this.gotoAndStop(new_flv_frame_name);
this.video_player.play();
The issue, again, is that loading is taking a long time. What could prevent this behavior? One long flv that I seek() to different moments of time on the playhead? Can I preload in a separate FLVPlayback instance, similar to double buffering?
Any tips or best practices are appreciated.
Although you have not told me where the flv files are being loaded from (locally or remote), and as you have said you are building a kiosk style app, I am going to go out on a limb here and say that you should almost certainly use Adobe AIR for a kiosk app.
There is no reason for creating more than one FLVPlayback instance, its capable of playing multiple videos using getVideoPlayer(index), its up to you to manage the streams by calling close() on them.
If you are loading files remotely, then using Adobe AIR you can download each video to a local folder using the FileStream class. This will speed up the process of playing back these files.

AS3: How to dynamically load movieclip from library without exporting in frame 1?

I have some fairly large movieclips in the library which need to be dynamically loaded at runtime. I don't want to export them all in frame 1, because that would slow down initial loading of the movie.
I tried putting an instance of each of these clips later in the timeline where they wouldn't normally be encountered. When I then tried to load one from the library dynamically, I was able to successfully get an instance of the movieclip, but its currentFrame property was 0 and I couldn't see anything on the stage. As soon as I enabled "Export in frame 1", it worked properly.
Does this old trick of putting an instance on the timeline somewhere no longer work in AS3?
I have had similar issues with large library assets and to solve my issue I would always just put the assets into separate swf's and load the external swf file when I needed it.
Check out the Loader class 'content' property - http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/Loader.html#content
The only downfall to this is managing the assets in separate files.
I hope this helps.

How can I copy a NetStream Object?

I'm using BulkLoader to load an array of 10 or so FLV files. I want to be able to use and control these FLVs throughout my app independently. So for instance, FLV_1 may be displayed in duplicate but I want to pause one instance and play the other in tandem.
I would like to pass the NetStream object around to other Video objects and display both. Is this possible? If so, how do I go about doing it?
It's definitely possible. BulkLoader will expose you the NetStream object, so you can pass it around to Video or anything else, for example:
var videoItem : VideoItem = bulkLoader.get("my-video.flv");
var video : Video = new Video();
video.attachStream(videoItem.content);
// or the shortcut:
video.attachStream(bulkLoader.getNetStream("my-video.flv");
Regards
Haven't tested this but logically you shouldn't be able to play more than one video containing the same instance of a NetStream asynchronously, simply because the pause/play/etc. methods are triggered directly on the NetStream instance (and not on the Video containers...).
On the other hand you can probably play the same instance of a NetStream synchronously within different Video instances (to be double checked!).
Probably the easiest hack would be to load the same FLV into two different items (in case you use BulkLoader) referencing them with unique ID's and hoping the end-user has his browser cache enabled. Thereafter you would add and control each NetStream separately just as if you were handling two different movies.