OSMF and SWFElement timeline

During development of couple simple OSMF dynamic plugins recently I bumped into the problem that SWFElement doesn’t provide any control over the timeline of the underlying movieclip. In fact if you look at the OSMF source code you’ll see that the class looks really simplistic and does little else than add a DisplayObjectTrait and LoadTrait.

If for instance you’d need to move the playhead to other frames, play/stop the SWF you are not really given any means to do that.

Even though I really hate the awful mess that is OSMF traits and metadata, I was expecting SeekTrait, PlayTrait and TimeTrait on the SWFElement instances. Why OSMF developers chose not to have them there is a mystery.

Anyway to make a bit better version of the class I extended it and because I’ve really grown to dislike the OSMF-traits, I didn’t bother with adding any new ones. Just added methods play(), stop(), gotoAndPlay() and gotoAndStop().

To achieve that you need to first extend the SWFElement class and add an event listener grabbing TRAIT_ADD events in the constructor:

public class BetterSWFElement extends SWFElement
{
    public function BetterSWFElement(url:URLResource=null, loader:SWFLoader=null)
    {
        super(url, loader);
        addEventListener(MediaElementEvent.TRAIT_ADD, onAddTrait);
    }
...

And in onAddTrait() you need to get the displayObject property from the DisplayObjectTrait, cast it to Loader and cast the attribute called content to Movieclip and this the timeline. It took me full three hours to figure that out. Why this isn’t documented anywhere is beyond me.

private function onAddTrait(event:MediaElementEvent):void
{
    if (event.traitType == MediaTraitType.DISPLAY_OBJECT) {
        var displayObjectTrait:DisplayObjectTrait = getTrait(MediaTraitType.DISPLAY_OBJECT) as DisplayObjectTrait;
        var displayObject:DisplayObject = displayObjectTrait.displayObject;
        timeLine = (displayObject as Loader).content as MovieClip;
    }
}

private var timeLine:MovieClip;

Looks kind of freaky but it does work and I don’t know any other way. If somebody does – please do let me know.

And in case you didn’t figure out yet – the rest is really simple:

public function play():void
{
    if (timeLine != null) {
        timeLine.play();
    }
}

public function stop():void
{
    if (timeLine != null) {
        timeLine.stop();
    }
}

public function gotoAndPlay(frame:Object, scene:String = null):void
{
    if (timeLine != null) {
        timeLine.gotoAndPlay(frame, scene);
    }
}

public function gotoAndStop(frame:Object, scene:String = null):void
{
    if (timeLine != null) {
        timeLine.gotoAndStop(frame, scene);
    }
}

I hope this saves somebody some nerves and helps to keep down the frustrated cursing levels of the world…

Compiling Strobe Media Playback using command line

The developers of Strobe Media Playback are rather vague about how to compile the source code. This article tries to list all the steps needed to get a working SWF on any modern OS.

Here is a list of things you will need to make the magic happen:

  • Java JDK 6
  • Apache Ant
  • Adobe Flex SDK 4
  • FlexUnit 4
  • Ant Contrib

First make sure you have Java (JDK 6) installed on your OS.
Next get Apache Ant from http://ant.apache.org/bindownload.cgi (I used v1.8.2 for this article) or if you are running some OS with central software repositories (Linux, FreeBSD, etc), then install using the tools provided with it (yum, pkg_add, apt-get, etc).
When setting up Apache Ant on a Windows machine make sure you add the bin directory to PATH variable of the system.

Then go and download the Strobe Media Playback source from http://sourceforge.net/projects/smp.adobe/files/ (for this article I used v1.5.1). Uncompress the downloaded file and at the root of the uncompressed source directory create the following subdirectories:

./buildtools/
./buildtools/libs/
./buildtools/sdks/
./buildtools/sdks/4.1.0/

Now lets populate the ./buildtools folder with some… umm build tools obviously… duh…

Go and download Flex 4 SDK from http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4 (for this article I used v4.1.0.16076). Uncompress the files into the ./buildtools/sdks/4.1.0/ subdirectory.

Now we’ll need something called ANT Contrib. Version 1.0b3 to be precise. Uncompress the archive and move the ant-contrib-1.0b3.jar file to ./buildtools/libs/

Finally something called FlexUnit… from the download page choose the stable release FlexUnit (4.0 SDK). Uncompress the the archive and move flexUnitTasks-4.0.0.jar to ./buildtools/libs/

If using Windows, then now you can execute the “src\build.bat compile.strobe”.

For unix-like OS-es you need to create a shell script ./src/compile.strobe, like:

#!/bin/bash
BUILD_TOOLS=”..\buildtools”
/usr/bin/ant \
-lib ${BUILD_TOOLS}\sdks\4.1.0\lib \
-lib ${BUILD_TOOLS}\sdks\4.1.0\ant\lib \
-lib ${BUILD_TOOLS}\libs \
compile.strobe

If you don’t have bash, then just tweak the script a bit to match the conventions of your favourite shell.

If you look inside ./src/build.xml, you’ll notice that there are many other build targets besides “compile.strobe”. Haven’t yet worked out how to make them all work… will post an update when I do.

Debug build for Flash Player 10.1