多次点击后 Flash AS3 崩溃 - 参数错误 - noSource 错误

Flash AS3 Crashing After A Multiple Clicks - Argument Error - noSource error

我这里有一些用于创建 19 个按钮的交互式信息亭的 AS3。它调用 20 个不同的 video_files 在 FLVPLayer 中播放。单击一个按钮时,它会绘制播放器并指定源。

发生在我​​们的 PC 上的是我们的 crazy-kid-test,我们在其中单击几个不同的按钮开始和停止视频,然后按下几个按钮后 SWF 崩溃。

我遇到了参数错误(根据 Adob​​e Scout 的说法) 我在调试器中出现 noSource 错误(指向 removeChild(movie_container); 还有其他一些看似随机的 bugs/error 消息。

有人介意看一下代码吗?谢谢你。注意:因为它有 500 行长,所以我将粘贴到 buttonTwo。

    import flash.events.*;
import flash.display.*;
import flash.ui.Mouse;
import fl.video.*;
import flash.utils.Timer;


//Mouse.hide();

stop();

addEventListener(Event.ENTER_FRAME, timerHandler);

//===================== Primary Event Listeners ==========================//
buttonOne.addEventListener(MouseEvent.MOUSE_DOWN, playVideoOne);
buttonTwo.addEventListener(MouseEvent.MOUSE_DOWN, playVideoTwo);

// Show buttons so users can click - cheaper than adding/removing 20 e:listeners
function showTheButtons(): void {
    buttonOne.visible = true;
    buttonTwo.visible = true;

}

// Hide buttons so users cant crazy-click resulting in massive slowdown - cheaper than adding/removing 20 e:listeners
function hideTheButtons(): void {
    buttonOne.visible = false;
    buttonTwo.visible = false;

}

// ADD ALL EVENT Listeners after AttractLoop removed

//=====================
var attractTimer: Timer = new Timer(300000); //should be 7min OR 420000ms in production
attractTimer.addEventListener(TimerEvent.TIMER, timerHandler, false, 0, true);
attractTimer.start();
//=====================

this.aLoopMovie.visible = false;

aLoopMovie.addEventListener(MouseEvent.CLICK, stopRemoveVideo);
function stopRemoveVideo(event: Event): void {
    showTheButtons();
    aLoopMovie.visible = false;
    aLoopMovie.gotoAndStop(1);
    //=====================
    attractTimer.start();
    //=====================
}

function timerHandler(event: Event): void {
    attractTimer.stop();
    hideTheButtons();
    //++
    removeEventListener(Event.ENTER_FRAME, timerHandler);
    //++
    if (this.aLoopMovie.visible != true) {
        this.aLoopMovie.visible = true;
        this.aLoopMovie.play();
    }
}

//////////// BUILD PLAYER ///////////////
var movie_container: MovieClip = new MovieClip();

function launchVideo(vBox, vFile): void {
    hideTheButtons();

    var flvPlayer: FLVPlayback = new FLVPlayback();

    flvPlayer.source = vFile;
    flvPlayer.skinAutoHide = true;
    flvPlayer.skinBackgroundColor = 0x000000;

    flvPlayer.width = 1920;
    flvPlayer.height = 1080;
    flvPlayer.autoRewind = true;

    vBox.addChild(flvPlayer);

    // Allow Playabck timer //
    var playbackTimer: Timer = new Timer(5000); //should be 2sec OR 2000ms in production
    playbackTimer.addEventListener(TimerEvent.TIMER, allowPlayback);
    function allowPlayback(event: Event): void {
        playbackTimer.stop();
        movie_container.addEventListener(MouseEvent.CLICK, stopRemoveVideo);

        function stopRemoveVideo(event: Event): void {
            showTheButtons();
            flvPlayer.stop();
            //=====================
            movie_container.removeEventListener(MouseEvent.CLICK, stopRemoveVideo);
            //=====================
            removeChild(movie_container);
            attractTimer.start();
        }

        flvPlayer.addEventListener(fl.video.VideoEvent.COMPLETE, completeHandler);
        function completeHandler(event: fl.video.VideoEvent): void {
            flvPlayer.stop();
            playbackTimer.stop();
            showTheButtons();
            flvPlayer.removeEventListener(fl.video.VideoEvent.COMPLETE, completeHandler);
            //=====================
            removeChild(movie_container);
            //=====================
            attractTimer.start();
        }
    }
    playbackTimer.start();
    //////////////////////////

}
//////////// END BUILD PLAYER ///////////////

//===================== Primary Functions
function playVideoOne(event: Event): void {

    //=====================
    attractTimer.stop();
    hideTheButtons();
    //=====================

    // Place container on stage
    addChild(movie_container);
    movie_container.x = 0;
    movie_container.y = 0;

    //Video Source
    var video_file = "MPVideos/MP-01.mp4";

    launchVideo(movie_container, video_file);
}

function playVideoTwo(event: Event): void {

    //=====================
    attractTimer.stop();
    hideTheButtons();
    //=====================

    // Place container on stage
    addChild(movie_container);
    movie_container.x = 0;
    movie_container.y = 0;

    //Video Source
    var video_file = "MPVideos/MP-02.mp4";

    launchVideo(movie_container, video_file);

}

已更新

function playVideoOne(event: Event): void {

    //=====================
    attractTimer.stop();
    hideTheButtons();
    //=====================

    var movie_container: MovieClip = new MovieClip();

    // Place container on stage
    addChild(movie_container);
    movie_container.x = 0;
    movie_container.y = 0;

    //Video Source
    var video_file = "MPVideos/MP-01.mp4";
    var flvPlayer: FLVPlayback = new FLVPlayback();

    function launchVideo(vBox, vFile): void {

        flvPlayer.source = vFile;
        flvPlayer.skinAutoHide = true;
        flvPlayer.skinBackgroundColor = 0x000000;

        flvPlayer.width = 1920;
        flvPlayer.height = 1080;
        flvPlayer.autoRewind = true;

        vBox.addChild(flvPlayer);

    }

    flvPlayer.addEventListener(fl.video.VideoEvent.COMPLETE, completeHandler);
    function completeHandler(event: fl.video.VideoEvent): void {
        flvPlayer.stop();
        flvPlayer.closeVideoPlayer(0);
        showTheButtons();
        flvPlayer.removeEventListener(fl.video.VideoEvent.COMPLETE, completeHandler);
        //=====================
        attractTimer.start();
        //=====================
        removeChild(movie_container);
        //=====================
    }

    movie_container.addEventListener(MouseEvent.CLICK, stopRemoveVideo);
    function stopRemoveVideo(event: Event): void {
        flvPlayer.stop();
        flvPlayer.closeVideoPlayer(0);
        showTheButtons();
        removeChild(movie_container);
        //=====================
        attractTimer.start();
        //=====================
        movie_container.removeEventListener(MouseEvent.CLICK, stopRemoveVideo);
        //=====================

    }

    launchVideo(movie_container, video_file);
}

将嵌套函数上移了一层。这些事件侦听器(完成和点击)在 playVideoOne 函数之外不起作用。

您的主要错误是您在函数中声明了一个变量,以便在嵌套函数中使用它。这些并不像您想象的那样起作用,实际上我怀疑这不是描述的未定义行为类型。而且,你有很多这样设计的功能。您应该做的是:让 flvPlayer 成为顶层的变量,在事件侦听器中初始化,并使用相应的事件侦听器清除播放器,并将 function launchVideo(vBox, vFile) 也重新定位到顶层 -这些在您的每个听众中都完美复制。此外,您应该将所有侦听器的公共部分包装到一个参数化函数中,该函数将创建 movie_container 并使用提供的字符串启动正确的视频。

//===================== Additional variables
var flvPlayer:FLVPlayback;
var movie_container:MovieClip;

//===================== Primary Functions
function playVideoByString(source:String):void {
    attractTimer.stop();
    hideTheButtons();
    movie_container = new MovieClip();
    addChild(movie_container);
    movie_container.x = 0;
    movie_container.y = 0;

    launchVideo(movie_container, source); // that's it
}

function playVideoOne(event: Event): void {
    playVideoByString("MPVideos/MP-01.mp4"); // that's it as well
}

现在,您没有处理 FLVPlayback 实例的正确删除,它们有侦听器,所以是它们阻塞了您的记忆。甚至 Object 泄漏已经是有害的,而且您正在泄漏整个视频播放器。这么快 运行 内存不足也就不足为奇了。因此,如果按下新按钮或播放器完成播放,您必须正确停止并分离视频播放器。根据您对问题的更新,您设计了一些函数来执行此操作,并且要使它们起作用,您只需要全局级别的变量。但是你的错误是你在初始化时添加了两个监听器,但是在任何一个删除函数中只删除了一个 - 另一个监听器保留下来并防止 movie_containerflvPlayer 被垃圾收集,有效地泄漏整个视频播放器实例。

// Primary functions (cont.)
function stopRemoveVideo(event: Event): void {
    doCleanup();
}
function completeHandler(event: fl.video.VideoEvent): void {
    doCleanup();
}
function doCleanup():void {
    // these actions are common between handlers, so put em in one place
    flvPlayer.stop();
    flvPlayer.closeVideoPlayer(0);
    showTheButtons();
    removeChild(movie_container);
    attractTimer.start();
    movie_container.removeEventListener(MouseEvent.CLICK, stopRemoveVideo);
    flvPlayer.removeEventListener(fl.video.VideoEvent.COMPLETE, completeHandler);
    // clear the references just in case
    movie_container=null;
    flvPlayer=null;
    // you need to remove both listeners in either case, otherwise you leak objects!
}
function launchVideo(vBox, vFile): void {
    flvPlayer=new FLVPlayback();
    flvPlayer.source = vFile;
    flvPlayer.skinAutoHide = true;
    flvPlayer.skinBackgroundColor = 0x000000;

    flvPlayer.width = 1920;
    flvPlayer.height = 1080;
    flvPlayer.autoRewind = false; // this changes as well
    // you close the vid if you hit movie end, why allow the player to autorewind?

    vBox.addChild(flvPlayer);
    // adding listeners in here
    flvPlayer.addEventListener(fl.video.VideoEvent.COMPLETE, completeHandler);
    movie_container.addEventListener(MouseEvent.CLICK, stopRemoveVideo);
}

这可能不足以消除源代码中的所有错误,但它应该为您提供一个良好的开端,让您了解如何优化使用在其中之一中实例化的对象的应用程序和函数。