A few months ago I wrote about the dilemma of trying to load Captivate SWFs into an ActionScript 3-based parent SWF.

Dilemma solved!

I present to you the ActionScript 3 class LegacyCaptivateLoader. This class utilizes ExternalInterface and a proxy SWF to facilitate sending commands to and querying data from an ActionScript 2-based Captivate SWF.

How it works

The LegacyCaptivateController class extends sprite, and is basically a Loader with Captivate-specific methods. It uses ExternalInterface to facilitate synchronous communication between the AS3 SWF and the Captivate (AS2) SWF.

(Note: I previously created a LocalConnection workaround for AS3-to-Captivate communication, but the asynchronous nature of LocalConnection made it very difficult to work with, and ExternalInterface is more reliable.)

I will be the first to say this is not an elegant solution… it requires three hacks creative workarounds to enable the communication. However, it is easy to use, requires NO JavaScript in the HTML page, and — so far — seems to work fine in every browser I’ve tested (Windows IE6, FF2 and Safari 3.1 as of this writing, more testing will be done when I have the time).

The flow

  1. The AS3 SWF calls the class LegacyCaptivateLoader.
  2. The LegacyCaptivateLoader class automatically creates a Loader instance and loads a proxy SWF (AS2).
  3. The proxy SWF in turn contains a MovieClipLoader that loads the Captivate SWF.
  4. The queries and commands from AS3 go to the browser, where they are then routed to the proxy SWF via ExternalInterface. The proxy then sends commands directly to the Captivate SWF via direct ActionScript 2 communication.

Here hacky, hacky hacky!

As I mentioned, this system requires a few hacks. Here are the main ones:

Hack #1: The external proxy SWF. The AS3 SWF must load the proxy SWF for this system to work. The proxy SWF acts as a relay, which is necessary since we can’t add custom ActionScript ExternalInterface code directly to the Captivate SWF.

Hack #2: In order to avoid using JavaScript in the HMTL page or resorting to ugly eval() hacks in the ExternalInterface calls, we have to use the non-standard global namespace method of grabbing the SWF. So instead of using a DOM method such as

document.getElementById("myswf").myExternalInterfaceCall()Code language: JavaScript (javascript)

we simply use

myswf.myExternalInterfaceCall()Code language: CSS (css)

Standardistas cringe (me, too!), but in my mind it’s the least evil, most compatible, most secure and easiest to use hack of the bunch.

Hack #3: Because of hack #2, the HTML file must be in quirks mode (no DOCTYPE) to work in Firefox. Note that in my testing, the standards mode version (XHTML transitional) works in IE6 and Safari 3.1.

Give it a spin!

Please give the class a try and let me know how it works for you… success stories and bugs!

Similar Posts

11 Comments

  1. Hi Philip.

    Awesome; thanks for this.
    We are about to embark on an update of our learning management system, currently written in AS2/Player 7. We have LOTS of Captivate SWFs being loaded in, and we’d like to not republish everything once we push our LMS to Flex/FP9! Thanks! I’ll let you know how we do; working on preliminary experimentation right now…

  2. Very nice demo. I am working with a player (presently AS 2 in CS3) that Captivate and other swf content. For some reason, after pre-loading, the Captivate-generated swf files start on slide 1 (the second slide) when played the first time, and I cannot get them to start at slide 0.

    I have exauhsted the Adobe and other forums on this – any ideas as to why this is happening? Thanks

  3. Thanks for taking the time to reply – doesn’t look like I can post there, so…

    The Captivates play normally outside of the custom player. I have searched up and down for an inadvertent slide advance – it is not in there. At this point, it seems swfs with “question slides” are especially prone, whereas demos are not.

    Furthermore, when going back to the slides in my player, they will play from slide 0.

    I think there is a conflict between the preloading I do (using a class to load all external swf files into an holder clip, then put in an array) and the Captivate preloader. Turning off the Captivate loading screen option in the Publish settings, however, causes other issues (blank captivates and audio issues).

    Again, thanks for taking the time to answer.

  4. SO you use a preloader to load the Captivate SWFs into a Flash SWF AND use a Captivate preloader in the Captivate SWFs?

    I hear you about the Captivate ‘question’ slides… they’re no picnic to use and I always get frustrated with them for one reason or another.

    RE: the forum, you can post there, you just have to create a (free) account. Creating accounts helps me keep out spam bots. 🙂

  5. Without preloading into the player, I ended up with Captivate swfs that would start audio, but be invisible, or not start at all, and other very difficult issues. I had a player without a preloader, that loads each swf new every time you navigate to different ones, and that works fine with almost all Captivates. So the issues are related to preloading – but I do not want to give up the preloader for the player. Rather catch-22.

    My biggest concern – and I don’t know if you want to respond to this here – is that there is so much hacking involved in these solutions. My organization is, at this point, rather invested in our custom player of Captivate and other swfs. What if Adobe decides to tighten-up Captivate swfs even further, or, heaven forfend, do things to make exported swf files impossible to work with?

    I will create an account…

  6. Hacks are certainly a way of life with Captivate (so far, anyway). It makes sense, really, because many of us are using Captivate in ways the Captivate creators/developers hadn’t thought of or intended. From what I’ve heard, the Captivate developers like some of the things people are doing, and may try to formalize the hacks (add the hack as a feature) rather than try and shut people out. They’re certainly trying to add support for new Adobe technology such as ActionScript 3. But will today’s Captivate SWFs remain compatible with Captivate 2010? Who knows.

  7. Did anyone try to adapt this code to AS2?

    Seems useless, but sometimes we don’t have the possibility to use the latest actionscript version…

    I will try to rewrite LegacyCaptivateLoader.as and Proxy.as for AS2…

    1. LegacyCaptivateLoader was created specifically for loading AS2 SWFs into an AS3 SWF. I don’t understand what the point of rewriting it would be… you can import AS2 SWFs into AS2 SWFs without the LegacyCaptivateLoader.

  8. Is there a way to use this just with as3 holding as2 (no Captivate involved)? I have an as3 framework that loads an as2 swf into a movieclip. I have some functions in the as2 swf I want to trigger from as3.

Comments are closed.