2016-07-26 49 views
0

我有一個Flash SWF設置爲響應鍵盤命令來播放網絡流。有幾個非常短的視頻剪輯是由數字鍵盤觸發的。由於有很多(在這個未完成的例子中只有少數),所以必須按兩個數字來播放視頻。AS3 KeyboardEvent不會在NetStream停止後添加eventListener

第一個數字觸發videoArray函數,並在videoArray函數內創建一個新的eventListener來播放視頻,而舊的事件偵聽器被刪除。視頻完成後,我使用NetStatusEvent刪除網絡流,並再次添加videoArray eventListener。

所有這些工作正常,但是,有一個由S鍵觸發的stopVideo函數。它具有與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); 
    } 
} 
+0

我沒有看得太緊密(你發佈了很多不太容易閱讀的代碼),但是你的問題可能是內聯函數被用作事件監聽器的結果。每次調用'videoArray'函數時,都會創建一個全新的play1/play方法集,這些方法與以前的方法不同。 – BadFeelingAboutThis

+0

正如我試圖做你所建議的,我注意到事件監聽器正在被videoArray函數中刪除,並且也沒有其他語句。因此,無論何時按下另一個鍵(在本例中爲S),都會禁用eventListeners,但不會觸發play1,play2功能。謝謝參觀。 – Browntastic

回答

1

這裏是我將如何重做你的代碼。更清楚和更容易弄清楚單個按鍵偵聽器正在發生什麼,並且不會隨時添加和刪除不同的按鍵偵聽器。看到代碼註釋

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

事件偵聽器在videoArray函數中被刪除,並且沒有else語句。所以無論何時按下另一個按鍵,它都會禁用eventListeners,但不會觸發play1,play2功能。

+0

這似乎確實可能是問題。這也許只有當你點擊'S'或網絡流緩衝區清空時纔會再次添加監聽器。 – BadFeelingAboutThis