Embedding Flash in Flex

Embedding Flash in Flex

At first I thought it has to be an easy task since Flash and Flex has the same father (Adobe). Well, actually it's a real pain because the results you get depends on the flash version you are trying to embed into Flex. You might have trouble aligning it and in the worst case you'll get an error.

My first attempt was using SWFLoader component, it has everything you need for embedding Flash you can even send parameters along with the URL, for example:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
    xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="absolute">

    <mx:SWFLoader id="movieClip" scaleContent="true" x="0" y="0" source="@Embed('/assets/demo2.swf')" width="100%" height="100%" />
</mx:Application>

In the above code relative URL can be used instead of the @Embed.

The problem with SWFLoader that it has a rough offset even if you are wrapping it with Canvas or a Box. SWFLoader results was not so good so I have decided to go deeper and use Action Script - maybe if I'll work with the  bits and bytes I could bend the rules a bit.

I have search google and most of the code didn't work. The most common mistake was to add the loader to a MovieClip and then play it. In case you'll do that the swf will be displayed but it will not be set into the layout properly. Look at the example below, adding the loader as a child will load and play the swf as expected

Anothe issue is that older versions will not cast the loader.content (AVM1Movie) to a MovieClip component that is not so convenient if you want to use the MovieClip's API.

If you need to embed flash into flex, test it first as see if it works for you.

as_embed_flash.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
    xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="absolute"
    creationComplete="complete()">

    <mx:Script>
        <![CDATA[
        import mx.core.UIComponent;

        private var sprite:FlashSprite;
        public function complete() : void {
            sprite = new FlashSprite();
            sprite.addEventListener("testListener", onSpriteComplete);
            sprite.load();

        }

        private function onSpriteComplete(event:Event):void {
            var component:UIComponent = new UIComponent();
            component.percentWidth = 100;
            component.percentHeight = 100;
            component.addChild(sprite);
            main_view.addChild(component);

            var loader:Loader = sprite.getLoader();
            swfVer.text = "SWF Version: " + loader.contentLoaderInfo.swfVersion;
            asVer.text = "Action Script Version: " + loader.contentLoaderInfo.actionScriptVersion;
            mcSupported.text = "Is MovieClip Supported? " + getMovieClip();

            this.setLoaderDimensions(main_view.width, main_view.height);
            main_view.visible = true;
        }

        /* Here you can do some custom manipulation if needed.*/
        override protected function updateDisplayList(unscaledWidth:Number,
                                            unscaledHeight:Number):void {

               super.updateDisplayList(unscaledWidth, unscaledHeight);
            this.setLoaderDimensions(unscaledWidth, unscaledHeight);
        }

        private function setLoaderDimensions(aWidth:Number, aHeight:Number):void {
            var loader:Loader = this.getLoader();
            if (loader != null) {
                loader.width = aWidth;
                loader.height = aHeight;
            }
        }

        private function getLoader():Loader {
            if (main_view.getChildren().length > 0 ) {
                var comp:UIComponent = UIComponent(main_view.getChildAt(0));
                var flashSprite:FlashSprite = FlashSprite(comp.getChildAt(0));
                if (flashSprite.getLoader() != null) {
                    var loader:Loader = flashSprite.getLoader();
                    if (loader != null) {
                        return loader;
                    }
                }
            }
            return null;
        }

        private function getMovie():AVM1Movie {
            var loader:Loader = getLoader();
            if (loader != null) {
                var movie:AVM1Movie =  loader.content as AVM1Movie;
                return movie;
            }
            return null;
        }

        private function getMovieClip():MovieClip {
            var loader:Loader = getLoader();
            if (loader != null) {
                var movie:MovieClip =  loader.content as MovieClip;
                return movie;
            }
            return null;
        }

        ]]>
    </mx:Script>

    <mx:Box id="main_view" width="100%" height="100%" visible="false"/>

    <mx:Label x="10" y="10" id="swfVer" text="SWF Version: "/>

    <mx:Label x="10" y="40" id="asVer" text="Action Script Version: "/>

    <mx:Label x="10" y="70" id="mcSupported" text="Is MovieClip Supported? "/>
</mx:Application>

FlashSprite.as

package {
    import flash.display.Loader;
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.net.URLRequest;
    import flash.system.ApplicationDomain;
    import flash.system.LoaderContext;

    import mx.events.FlexEvent;

    [Event(name="testListener", type="mx.events.FlexEvent")]

    public class FlashSprite extends Sprite {

        private var panorama:MovieClip;
        private var loader:Loader = new Loader();

        public function FlashSprite() {
        }

        public function load():void {
            var context:LoaderContext = new LoaderContext();
            context.applicationDomain = ApplicationDomain.currentDomain;
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
            loader.contentLoaderInfo.addEventListener(Event.UNLOAD, closeAllStreams);
            loader.load(new URLRequest("../src/assets/demo2.swf"), context);
        }

        public function unload():void {
            loader.unload();
        }

        public function getLoader():Loader {
            return loader;
        }

        // -- listeners
        private function loadComplete(e:Event):void {
            this.addChild(loader);
            this.dispatchEvent(new FlexEvent("testListener"));
        }

        private function closeAllStreams (e:Event):void {
            loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onRemoveComplete);
            loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onRemoveUnload);
             this.removeChild(loader);
        }

        private function onRemoveComplete(e:Event):void {
            // --
        }

        private function onRemoveUnload(e:Event):void {
            // --
        }

    }
}

Thank you for your interest!

We will contact you as soon as possible.

Send us a message

Oops, something went wrong
Please try again or contact us by email at info@tikalk.com