AS3 KeyboardEvent 不会在 NetStream 停止后添加 eventListener

AS3 KeyboardEvent won't add eventListener after NetStream has been stopped

我设置了一个 Flash SWF 来响应键盘命令播放网络流。有几个非常短的视频剪辑是由数字键盘触发的。由于数量太多(在这个未完成的例子中只有几个),必须按两个数字才能播放视频。

第一个数字触发 videoArray 函数,在 videoArray 函数内部创建一个新的 eventListener 来播放视频,同时删除旧的事件监听器。视频结束后,我使用 NetStatusEvent 删除网络流并再次添加 videoArray eventListener。

所有这些工作正常,但是,有一个由 S 键触发的停止视频功能。它与 NetStatusEvent 具有相同的代码来删除网络流并重新添加 eventListener,但仅删除网络流。未添加 eventListener。

我是否遗漏了阻止添加 eventListener 的内容,或者我应该以不同的方式执行此操作?是否可以跳到视频结尾并触发 NetStatusEvent 停止播放?

import flash.ui.Keyboard;
import flash.events.KeyboardEvent;

// Create a NetConnection object
var nc:NetConnection = new NetConnection(); 
nc.connect(null);

// Create a NetStream object with NetConnection object as a parameter
var ns:NetStream = new NetStream(nc); 
var vid:Video = new Video();

// Play control
stage.addEventListener(KeyboardEvent.KEY_UP,videoArray);

function preStop(event:KeyboardEvent):void {
    if (event.keyCode == 97) {
        trace("O Stop");
        ns.close();
        removeChild(vid);
        vid.attachNetStream(null);
    }
    else if (event.keyCode == 98) {
        trace("P Stop");
        ns.close();
        removeChild(vid);
        vid.attachNetStream(null);
    }
}

function videoArray(event:KeyboardEvent):void {
    stage.removeEventListener(KeyboardEvent.KEY_DOWN,preStop);
    stage.removeEventListener(KeyboardEvent.KEY_UP,videoArray);

    if (event.keyCode == 97) { 
        stage.addEventListener(KeyboardEvent.KEY_UP,play1);
        trace("play1");
    }
    else if (event.keyCode == 98) { 
        stage.addEventListener(KeyboardEvent.KEY_UP,play2);
        trace("play2");
    }

    // PLAY 1
    function play1(event:KeyboardEvent):void { 
        if (event.keyCode == 97) { 
            stage.removeEventListener(KeyboardEvent.KEY_UP,play1);
            stage.removeEventListener(KeyboardEvent.KEY_UP,play2);

            // Play video
            ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler); 
            ns.play("cfa.mov"); 

            // Create a new Video object and attach NetStream object
            vid.attachNetStream(ns); 
            addChild(vid);      
        }
        else if (event.keyCode == 98) { 
            stage.removeEventListener(KeyboardEvent.KEY_UP,play1);
            stage.removeEventListener(KeyboardEvent.KEY_UP,play2);

            // Create a NetStream object with NetConnection object as a parameter
            ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler); 
            ns.play("matilda.mov"); 

            // Create a new Video object and attach NetStream object
            vid.attachNetStream(ns); 
            addChild(vid);
        }
        stage.addEventListener(KeyboardEvent.KEY_UP,videoArray);
    }

    // PLAY 2
    function play2(event:KeyboardEvent):void { 
        if (event.keyCode == 97) { 
            stage.removeEventListener(KeyboardEvent.KEY_UP,play1);
            stage.removeEventListener(KeyboardEvent.KEY_UP,play2);

            // Create a NetStream object with NetConnection object as a parameter
            ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler); 
            ns.play("illusionists.mov"); 

            // Create a new Video object and attach NetStream object
            vid.attachNetStream(ns); 
            addChild(vid);      
        }
        else if (event.keyCode == 98) { 
            stage.removeEventListener(KeyboardEvent.KEY_UP,play1);
            stage.removeEventListener(KeyboardEvent.KEY_UP,play2);

            // Create a NetStream object with NetConnection object as a parameter
            ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler); 
            ns.play("janis.mp4"); 

            // Create a new Video object and attach NetStream object
            vid.attachNetStream(ns); 
            addChild(vid);
        }
        stage.addEventListener(KeyboardEvent.KEY_UP,videoArray);
    }

    function asyncErrorHandler(event:AsyncErrorEvent):void { 
        // ignore error 
    }
}





// Stop at end of video
ns.addEventListener(NetStatusEvent.NET_STATUS, statusHandler);

function statusHandler(event:NetStatusEvent):void 
{ 
    trace(event.info.code)

    if (event.info.code == 'NetStream.Buffer.Empty') {
        ns.close();
        removeChild(vid);
        vid.attachNetStream(null);
        stage.addEventListener(KeyboardEvent.KEY_DOWN,preStop);
        stage.addEventListener(KeyboardEvent.KEY_UP,videoArray);
    }
}


// Pause control
stage.addEventListener(KeyboardEvent.KEY_UP,togglePauseHandler); 

function togglePauseHandler(event:KeyboardEvent):void { 
    if (event.keyCode == Keyboard.SPACE) { 
        ns.togglePause();  
    }
}


// Stop control
stage.addEventListener(KeyboardEvent.KEY_UP,stopVideo);

function stopVideo(event:KeyboardEvent):void {
    if (event.keyCode == Keyboard.S) {
        ns.close();
        removeChild(vid);
        vid.attachNetStream(null);
        stage.addEventListener(KeyboardEvent.KEY_DOWN,preStop);
        stage.addEventListener(KeyboardEvent.KEY_UP,videoArray);
    }
}

videoArray函数中去掉了事件监听器,没有else语句。因此,只要按下另一个键,它就会禁用 eventListeners,但不会触发 play1、play2 函数。

以下是我将如何修改您的代码。更清晰、更容易弄清楚单个键侦听器的情况,而不是一直添加和删除不同的键侦听器。看代码注释

import flash.events.AsyncErrorEvent;
import flash.events.NetStatusEvent;
import flash.media.Video;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.ui.Keyboard;
import flash.events.KeyboardEvent;

// Create a NetConnection object
var nc:NetConnection = new NetConnection(); 
nc.connect(null);

// Create a NetStream object with NetConnection object as a parameter
var ns:NetStream = new NetStream(nc);

//add your netstream listeners just once (the next line was in your play functions)
ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler); 
ns.addEventListener(NetStatusEvent.NET_STATUS, statusHandler);

var vid:Video = new Video();



var firstNum:int = 0; //to track the first number pressed in a set

//a list of all your videos, this example supports 81 items in this array/list.
var streams:Array = ["matilda.mov", "cfa.mov", "illusionists.mov", "janis.mp4"];

// A single Key up listener to handle everything
stage.addEventListener(KeyboardEvent.KEY_UP, keyUp);

function asyncErrorHandler(event:AsyncErrorEvent):void { 
    //ignore error 
}

//write the close and open stream code just once
function closeStream(event:KeyboardEvent):void {
    ns.close();
    removeChild(vid);
    vid.attachNetStream(null);
}

function openStream(path:String):void {
    // Play video
    ns.play(path); 

    // Create a new Video object and attach NetStream object
    vid.attachNetStream(ns); 
    addChild(vid);  
}

function keyUp(event:KeyboardEvent):void {
    //if they key event is numpad key
    if (event.keyCode >= Keyboard.NUMPAD_1 && event.keyCode <= Keyboard.NUMPAD_9) {
        var index:int = event.keyCode - Keyboard.NUMPAD_0; //which number was pushed between 1 - 9


        if (firstNum < 1) {
            //if this is the first number press, just assign that number
            firstNum = index;
        }else {
            //if the second press, play the appropriate video

            //this is the math for finding the video number
            index = ((firstNum - 1) * 9) + index - 1; // -1 one at the end since arrays are 0 based

            //if the number is higher the amount of videos available, set the index to the last video in the list
            if (streams.length >= index) {
                index = streams.length - 1;
            }

            //play the video
            openStream(streams[index]);

            //reset the firstNum
            firstNum = 0;
        }

        return; //don't look at any other key presses below since there's no reason to
    } 

    switch(event.keyCode) {
        case Keyboard.SPACE:
            ns.togglePause();
            break;

        case Keyboard.S:
            closeStream();
            break;
    }
}

function statusHandler(event:NetStatusEvent):void { 
    trace(event.info.code)

    switch(event.info.code){
        case 'NetStream.Buffer.Empty':
        case 'NetStream.Play.Stop':
        case 'NetStream.Play.Complete':
            closeStream();
            break;
    }
}