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;
}
}
我设置了一个 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;
}
}