Cannot create MovieClip from Bytes

I’ve been creating my AssetLibrary at runtime from a manifest. For SWF assets I have things working fine when deploying to HTML5 and converting to .bundle. I am having trouble supporting Flash target using plain old SWF however. You can see from the traces/comments below that everything works until I try to cast the bytes to a MovieClip.

trace("adding a swf file asset");
var id = "/assets/"+swflib+".swf";
//an AssetLibrary was created from a Manifest after  it got added using AssetManifest.addBytes earlier...trace(alp.getLibrary().list("BINARY")); // [/assets/swflibrary.swf]
trace("swflib id:"+id); // swflib id:/assets/swflibrary.swf
trace("exists:"+alp.getLibrary().exists(id,"BINARY")); // exists:true
var bytes = alp.getLibrary().getBytes (id); 
trace("bytes:"+bytes); // outputs: CWS S
var ba = ByteArray.fromBytes(bytes);
trace("byteArray:"+ba); // outputs: CWS S
var swf = new format.SWF(ba);
trace("swf:"+swf); // [object SWF]
var mc:MovieClip; 

for (key in swf.symbols.keys()) {
	trace(key); //LittleBoy
}
trace("actor.att.src:"+actor.att.src); // actor.att.src:LittleBoy
if (swf.symbols.exists (actor.att.src)) {

	var symbol:Dynamic = null;
	var charId:Int;
	charId = swf.symbols.get (actor.att.src);
	
	trace("making the actor..."); // making the actor...
	symbol = swf.data.getCharacter (charId);

	if (Std.is (symbol, SWFTimelineContainer)) {
		trace("attempt casting!"); // attempt casting!
		mc = cast symbol;
		trace("the movieclip is:"+mc); // NEVER GETS HERE
		a.addChild(mc);
		
	} 
}

I got some of this code from the format.SWF file, where the createMovieClip function has a similar “cast symbol” attempt commented out. It appears that my data is obviously there, since I can look up the symbol name. How should I properly convert the data to a MovieClip?

On Flash, it does not resolve as a format.SWF, but instead, you can use flash.display.Loader to load a SWF, then call getDefinition to grab loaded content from the SWF. This is effectively what the SWFLibrary class should be doing in OpenFL (internally)

I would like the loaded SWF to be contained in an AssetLibrary if I can because the rest of my framework retrieves other assets from named AssetLibraries. Is that possible?

Other than using an asset library like the SWF library (which loads the SWF into memory as part of the load() process) you could use a Loader at runtime to load SWF data from bytes. This adds an extra step, but effectively is what is required on the Flash target. It’s not entirely unlike BitmapData, which must be loaded from bytes at runtime to become usable, and cannot be done immediately

I was actually unfamiliar with the SWFLibrary; I’ll give that a try. Thanks!

Okay, I was able to successfully convert the bytes using loadbytes :

var id = "/assets/"+swflib+".swf";
//it got added as bytes earlier...
var bytes = alp.getLibrary().getBytes (id);
var mc:MovieClip; 
var context = new LoaderContext (false, ApplicationDomain.currentDomain, null);
context.allowCodeImport = true;
var loader = new Loader ();
loader.contentLoaderInfo.addEventListener (Event.COMPLETE, function (_) {
	trace("done:"+loader.content);
	mc = cast Type.createInstance (ApplicationDomain.currentDomain.getDefinition (actor.att.src), []); //where actor.att.src is the name of the MovieClip class
	trace("mc:"+mc);
	a.addChild(mc);
	a.init();
});
loader.loadBytes (bytes, context);

And so ends many days of debugging!

1 Like

Does this work without using the <library /> tag in the project.xml file?
If yes can you please put the full version of the code from loading the .swf file to the creation of the mc? I believe most of it is here except how to load & convert a .swf into bytes.

I have this working in Glory Framework, commit 7b68c9980323daa668ffb28a93513f41330dfe56. If you compile the ebook example to Flash, it should work as expected.

Note that one must compile to flash of course, and I’m using “lime build flash -debug” right now. DCE is having problems.

Thanks for the reply, it seems that it requires a .bundle or manifest for non flash targets and I noticed that in the bundle they have a swflite.bin any ideas what or how that was done? If I bundle my .swf using the process cmd it causes the same issues as described further below & Idk what manifest represents here or if it’s possible to turn a .swf into one.

To put it simply I’m looking for a way to get movieclips from a .swf (or maybe any converted format from it) without having to resort to the <library /> tag cuz it unfolds all the png files contained in the mcs into a bin/lib folder making the assets completely naked, any ideas how to work around that issue (not just for the flash target)?

I should have mentioned that Glory has a few wiki pages. Yes, for the non-flash targets one must run them through the “process” command.

When I use manifest in Glory framework, it is being built at runtime based on what is contained in the config.xml file. Setting it to “appMode” will embed all assets at compile time.

For non-flash targets I’m not sure how to prevent the assets from being exposed. My only idea would be to make a zip file of the bundle then decompress it at runtime.

Looks like this library is friendly with OpenFL.

I’ve read the wiki page concerning the .swf to Glory.
I’ve thought about the compression thing but I still don’t know how to get the mcs after I uncompress, I’m new to haxe & openfl. It’s alright though I’m thinking bout other ways to work around this issue for now until hopefully an update makes it possible to have something like the embed or .pak mechanisms for mcs that contain bitmaps.

Can you use openfl process to convert the SWF files first, and use those at runtime?

@EagleNebula Joshua is right; is a .bin file too much of an exposure?

I remember that even in the bundle the mc’s frames get split into png files so it’s kinda the same outcome.
@Confidant noat all but idk how to do & use that :confused:

When I ran my swf through process it generated a .bundle file which had a swflite.bin file contained within. I did not have a swf with bitmaps in it—just vector art— so it may be that bitmaps will not be part of the .bin file.

I tried it and it generates both the .bin file and the frames bitmap files, so it doesn’t solve the problem unless if I can just delete the bitmaps folder would I still be able to get them from the .bin? if so idk how.

It exports PNG and/or JPEG image files only if the original SWF includes bitmap data. If the SWF uses vector data instead (without “Export as Bitmap” checked in the MovieClips), it does not convert to bitmaps.

Vectors kill performance, can you pinpoint me to the part in openfl where it extracts and generates the bitmap files please? Wanna have a look.