AVM1Movie Controller in Flex

Overcome restrictions on an AVM1 SWF file loaded by an AVM2 SWF file:

While trying to control AVM1Movie (Flash Player 8, 9, 10 or older) from flex, we will get the below error message: ”Property stop not found on flash.display.AVM1Movie and there is no default value. ”

To overcome this problem, ForcibleLoader class converts them into latest player versions on runtime. The below is an working example for how to control AVM1Movie from Flex.

<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”absolute” initialize=”init()”>
<mx:Script>
<![CDATA[
private var swfURL:String = "AVM1Movie.swf";
private var libMC:MovieClip = new MovieClip();
private function init():void{
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, swfComplete);
var fLoader:ForcibleLoader = new ForcibleLoader(loader);
fLoader.load(new URLRequest(swfURL));
swfContainer.addChild(loader);
}
private function swfComplete(event:Event):void{
libMC = event.currentTarget.content as MovieClip;
libMC.gotoAndStop(1);
}
]]>
</mx:Script>
<mx:UIComponent id=”swfContainer”/>
<mx:NumericStepper id=”slide” change=”{libMC.gotoAndStop(slide.value)}”/>
</mx:Application>

30 Responses to “AVM1Movie Controller in Flex”

  1. fiCh Says:

    you are missing to publish the ForcibleEvent class code wont work

  2. nsdevaraj Says:

    sorry, for that. I have removed that event class but forgot to update. (not required)

  3. nsdevaraj Says:

    For Flash version you have to add the library components
    of Flex SDK
    frameworks\libs\rpc.swc
    frameworks\libs\framework.swc

    And the below is the modified code,

    package
    {
    import flash.display.Sprite;

    /**
    * …
    * @author Devaraj CSSWFLoader()
    */
    public class CSSWFLoader extends Sprite
    {
    import flash.display.Loader;
    import flash.events.Event;
    import mx.collections.*;
    import flash.display.MovieClip;
    import mx.rpc.events.ResultEvent;
    import flash.events.ProgressEvent;
    import mx.rpc.http.HTTPService;
    import flash.system.System;
    import flash.net.URLRequest

    private var cursorInd:int;
    private var lastInCollection:Boolean;
    private var firstInCollection:Boolean;
    private var myCursor:IViewCursor;
    private var myXMLC:XMLListCollection;
    private var fLoader:ForcibleLoader;

    private var sort:Sort = new Sort();
    private var swfMC:MovieClip= new MovieClip();
    private var enterFrameCatcher:MovieClip = new MovieClip();
    private var xmlLoaders:HTTPService = new HTTPService();
    private var myXMLList:XMLList = new XMLList();
    private var swfloader:Loader = new Loader();

    public function CSSWFLoader():void {
    xmlLoaders.url = “loaders.xml”;
    xmlLoaders.resultFormat = “e4x”;
    xmlLoaders.addEventListener(ResultEvent.RESULT,resultHandler);
    xmlLoaders.useProxy=false;
    xmlLoaders.send();
    }
    private function init():void {
    myXMLC = new XMLListCollection(myXMLList);
    myCursor = myXMLC.createCursor();
    sort.fields = [new SortField('@label', false,false,true)];
    myXMLC.sort=sort;
    myXMLC.refresh();
    swfloader.contentLoaderInfo.addEventListener(Event.COMPLETE, swfComplete, false, 0, true);
    addEnterFrameCatcher();
    navigate(‘first’);
    }
    private function onSwfProgressHandler(mProgress:ProgressEvent):void
    {
    var percent:int = (mProgress.bytesLoaded / mProgress.bytesTotal) * 100;
    }
    private function countSelection(str:String):void {
    if(myCursor.findAny(XML(“”))){
    navigate(’seek’)
    }
    }
    private function nextCollection():void {
    if(! myCursor.afterLast) {
    myCursor.moveNext();
    }
    }
    private function backCollection():void {
    if(!myCursor.beforeFirst) {
    myCursor.movePrevious();
    }
    }
    private function firstCollection():void {
    myCursor.seek(CursorBookmark.FIRST);
    }
    private function lastCollection():void {
    myCursor.seek(CursorBookmark.LAST);
    }
    private function seekCollection():void {
    var mark:CursorBookmark=myCursor.bookmark;
    while (myCursor.moveNext()) {
    }
    myCursor.seek(mark);
    }
    private function navigate(caseStr:String):void {
    switch(caseStr) {
    case ‘first’:
    firstCollection();
    break;
    case ‘back’:
    backCollection();
    break;
    case ‘next’:
    nextCollection();
    break;
    case ‘last’:
    lastCollection();
    break;
    case ’seek’:
    seekCollection();
    break;
    }
    if (swfMC) {
    swfMC.stop();
    swfMC = null;
    }
    cursorInd = myXMLC.getItemIndex(myCursor.current);
    loadSWF(cursorInd);
    enableDisableButtons();
    }
    private function enableDisableButtons():void {
    firstInCollection = myXMLC.getItemAt(0) == myCursor.current;
    //first.enabled = back.enabled = !firstInCollection
    lastInCollection = myXMLC.getItemAt(myXMLC.length – 1) == myCursor.current;
    //last.enabled = next.enabled = !lastInCollection;
    }
    private function resultHandler(event:ResultEvent):void
    {
    myXMLList = event.result.data as XMLList;
    init();
    }
    private function loadSWF(swfInd:int):void
    {
    try {
    System.gc();
    Loader(swfloader).close();
    Loader(fLoader.loader).close();
    swfloader.unloadAndStop();
    Loader(fLoader.loader).unloadAndStop();
    }catch (err:Error) {
    //mx.controls.Alert.show(“contentLoader: no stream to close”);
    }finally {
    fLoader = null;
    fLoader = new ForcibleLoader(swfloader);
    fLoader._stream.addEventListener(ProgressEvent.PROGRESS, onSwfProgressHandler, false, 0, true);
    fLoader.load(new URLRequest(String(myXMLList[swfInd]+’.swf’)));
    if (swfloader) if (swfloader.parent) swfloader.parent.removeChild(swfloader);
    addChild(swfloader);
    }
    }
    private function swfComplete(event:Event):void {
    swfMC = event.currentTarget.content as MovieClip;
    relistenEnterFrameCatcher();
    }
    private function enterFrameHandler(ev:Event) : void
    {
    if (swfMC) {
    if (swfMC.currentFrame == swfMC.totalFrames) {
    removeEnterFrameCatcher();
    if (lastInCollection) {
    navigate(‘first’);
    }else {
    navigate(‘next’);
    }
    }
    }
    }
    private function addEnterFrameCatcher(): void
    {
    if (enterFrameCatcher) enterFrameCatcher.addEventListener(Event.ENTER_FRAME, enterFrameHandler, false, 0, true);
    }
    private function removeEnterFrameCatcher() : void
    {
    if (enterFrameCatcher && enterFrameCatcher.hasEventListener(Event.ENTER_FRAME))
    {
    enterFrameCatcher.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
    }
    return;
    }
    private function relistenEnterFrameCatcher() : void
    {
    if (enterFrameCatcher && !enterFrameCatcher.hasEventListener(Event.ENTER_FRAME))
    {
    enterFrameCatcher.addEventListener(Event.ENTER_FRAME, enterFrameHandler, false, 0, true);
    }
    }
    }

    }

  4. iongion Says:

    What do you to have an unified loader and controller for avm1 and avm2 loaded files, is this enough for that ?

  5. nsdevaraj Says:

    Yes, it is enough as an unified loader for both AVM1 and AVM2.

  6. Casey Says:

    I keep getting an Error #2044: Unhandled IOErrorEvent:. text=Error #2124: Loaded file is an unknown type.

    Any ideas?

  7. nsdevaraj Says:

    First, have an exception case written like the below:

    try {
    }catch (err:Error) {
    mx.controls.Alert.show(String(err));
    }finally {
    }

    If possible, share the code I will try to debug.

  8. Wahhaj Says:

    I am getting this error for flash versions (7&8). Error #2044: Unhandled IOErrorEvent:. text=Error #2124: Loaded file is an unknown type.

    But works fine for (6 and 9). I think little tweaking is needed. Need Help!

  9. nsdevaraj Says:

    It’s Weird. Are you using the ForcibleLoader ?

  10. Anjana Says:

    Using flash in built components inside the AVM1 movies and it starts to blink events are not working… Anyidea

    • Young Says:

      My SWF loaded completely, but it is blinking a lot. I tried to apply the movie.stop() or movie.gotoAndStop(), but it does not stop blinking. Any ideas, thanks?

    • Tom Schober Says:

      I too am seeing the blinking. Has anyone found a solution to this?

  11. nsdevaraj Says:

    First of all, the ForcibleLoader does converts the AVM1Movie version to Flash player version 9. The ForcibleLoader is to use the old animations and assets from AVM1Movie. Obviously, some functionalities and actions will not perform the way as it supposed to be. Have to do some tweaks in these cases, frankly no idea about the tweaks required as it differs as per scenario.

  12. Max Wiertz Says:

    Hi,

    Thanks for sharing this component.

    I try to use within Flash CS3, so far so good.

    But I always get the error:
    1046: Type was not found or was not a compile-time constant: ResultEvent.

    I tried your version for Flash, but what do you mean by:

    For Flash version you have to add the library components
    of Flex SDK
    frameworks\libs\rpc.swc
    frameworks\libs\framework.swc

    ??

    I just copied the files into my Flash project, but does make no difference.

    Thanks, regards
    Max

    • nsdevaraj Says:

      In Flash Movie Publish Settings -> Settings -> Second Tab “Library path” include the library files of flex.

  13. Max Wiertz Says:

    Thanks nsdevaraj,

    I added the path were I copied the files, as well as the original path (flex install), but I still get the same error message:

    1046: Type was not found or was not a compile-time constant: ResultEvent.

    Seems that the mx.* inports (like import mx.rpc.events.ResultEvent;) still do not work properly.

    Any other ideas maybe?

  14. Max Wiertz Says:

    I’m using Flash CS3 btw, don’t know if that matters…

  15. Max Wiertz Says:

    Another question…

    How to load the external swf (avm1movie), using CSSWFLoader?

    Thanks

  16. Xav Says:

    Hi – I’m trying the class but swfComplete is never called – I’m using Flex 3 – everything builds fine, I checked as well the the forcibleloader is called and loads the swf. Any idea? Would love to get this working this is a very helpful code. thanks!

  17. nsdevaraj Says:

    give me your files, i will try compiling as i couldn’t figure what went wrong

  18. Xav Says:

    actually the loader is called but my swf is flash 7 and this seems to generate issues, oups – i guess that is the issue for me – flash 7 swf supported through this?

  19. nsdevaraj Says:

    For the Flash 7 swf this function -> insertFileAttributesTag(inputBytes); is called and version is modified on run-time. providing the animation assets of that swf

  20. David Says:

    I’m getting the same error as Max.

    How are you including the .SWC’s from Flex’s SDK into CS3?

    I can’t include a .SWC file directly. Including the directory of where the .SWC’s are also fails. And including the files as required individually leads to too many dependencies in the chain and errors.

  21. Troy Says:

    It seems like this is downloading the entire avm1movie before it will begin playing it. Is it possible to start it playing after a few seconds or set some sort of buffer length? I would like to use Flash’s progressive download feature.

    This is working great for me so far. Thanks!

    • nsdevaraj Says:

      It can be achieved if we were using the class in AIR, In Flex/ Flash it’s difficult to achieve that (nothing is impossible as long as bits and bytes are there)

  22. Chris Says:

    Hi,

    Thanks for sharing this code. When I try to use it, I’m getting the following error:

    SecurityError: Error #3015: Loader.loadBytes() is not permitted to load content with executable code.

    The error is being caught in the ForcibleLoader.completeHandler() method. I’m developing an Air application in Flex 3, in which I’m trying to use some SWF files built for Flash 6. Any ideas?

    Best,

    Chris

  23. Chris Says:

    I found the solution to the problem described in my earlier comment here:

    http://www.dreaminginflash.com/2008/05/14/%E2%80%9Csecurityerror-error-3015-loaderloadbytes-is-not-permitted-to-load-content-with-executable-code/

    Basically, add the following lines before the “loader.loadBytes()” call in ForcibleLoader.completeHandler:

    var loaderContext:LoaderContext = new LoaderContext();
    loaderContext.allowLoadBytesCodeExecution = true;

    -Chris

  24. Chris Says:

    Hi,

    I’m now seeing the same behavior as Xav above. The loader.contentLoaderInfo is never dispatching a “complete” event. I tried catching other events, and can see “progress” events showing the SWF file being downloaded. But no “init” event, nor the “complete” event is ever dispatched by the contentLoaderInfo.

    This is using Flex 3.0.2, building an Air application.

    Best,

    Chris

  25. fuoco Says:

    White screen on this row:

    loader.loadBytes(inputBytes);

    seems like endless loop.

  26. フラスコ » loaderで読み込んだswf(AVM1Movie)no再生制御 Says:

    [...] – Spark project AVM1Movie Controller in Flex « Flex User とりあえずはswfファイルの制御 – ichiro_jの日記 Markus Raab – All I don’t know. » [...]

Leave a Reply