actionscript-3flashvideoevent-listenernetstream

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


I have a Flash SWF set up to play a netstream in response to keyboard commands. There are several very short video clips that are triggered by the number pad. Since there are so many (in this unfinished example there are only a few), two numbers must be pressed to play the video.

The first number triggers the videoArray function, and inside the videoArray function a new eventListener is created to play a video, while the old event listener is removed. Once the video finishes, I used NetStatusEvent to remove the netstream and add the videoArray eventListener again.

All of this works fine, however, There is a stopVideo function that is triggered by the S key. It has the same code as the NetStatusEvent to remove the netstream and re-ad the eventListener, but only the netstream is removed. The eventListener is not added.

Am I missing something that's stopping the eventListener from being added, or should I be doing this differently? Is it possible to skip to end of the video and trigger the NetStatusEvent to stop it?

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);
    }
}

Solution

  • Here is how I would rework your code. Much cleaner and easier to figure out what's going with a single key listener and to not be adding and removing different key listeners all the time. See the code comments

    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;
        }
    }