编写元数据和提示点的回调方法

Flash Player 9 和更高版本,Adobe AIR 1.0 和更高版本

当播放器收到特定元数据或到达特定提示点时,可以在应用程序中触发动作。当这些事件发生时,必须将特定回调方法用作事件处理函数。NetStream 类指定了在播放期间可发生的以下元数据事件: onCuePoint (仅限 FLV 文件)、 onImageData onMetaData onPlayStatus onTextData onXMPData

必须为这些处理程序编写回调方法,否则 Flash 运行时可能会引发错误。例如,以下代码播放 SWF 文件所在文件夹中名为 video.flv 的 FLV 文件:

var nc:NetConnection = new NetConnection(); 
nc.connect(null); 
 
var ns:NetStream = new NetStream(nc); 
ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler); 
ns.play("video.flv"); 
function asyncErrorHandler(event:AsyncErrorEvent):void 
{ 
    trace(event.text); 
} 
 
var vid:Video = new Video(); 
vid.attachNetStream(ns); 
addChild(vid);

上面的代码加载一个名为 video.flv 的本地视频文件并侦听要调度的 asyncError ( AsyncErrorEvent.ASYNC_ERROR )。当本机异步代码中引发异常时调度此事件。在本例中,当视频文件中包含元数据或提示点信息,并且未定义相应的侦听器时,将调度此事件。如果您对视频文件的元数据或提示点信息不感兴趣,则可以使用上面的代码处理 asyncError 事件并忽略错误。如果 FLV 中有元数据和多个提示点,则 trace() 函数将显示以下错误消息:

Error #2095: flash.net.NetStream was unable to invoke callback onMetaData. 
Error #2095: flash.net.NetStream was unable to invoke callback onCuePoint. 
Error #2095: flash.net.NetStream was unable to invoke callback onCuePoint. 
Error #2095: flash.net.NetStream was unable to invoke callback onCuePoint.

发生错误的原因是 NetStream 对象找不到 onMetaData onCuePoint 回调方法。在应用程序中定义这些回调方法有多种方式。

将 NetStream 对象的 client 属性设置为一个 Object

通过将 client 属性设置为一个 Object 或设置为 NetStream 的一个子类,可以重新发送 onMetaData onCuePoint 回调方法或彻底忽略这些方法。以下示例演示如何使用空的 Object 忽略这些回调方法而不侦听 asyncError 事件:

var nc:NetConnection = new NetConnection(); 
nc.connect(null); 
 
var customClient:Object = new Object(); 
 
var ns:NetStream = new NetStream(nc); 
ns.client = customClient; 
ns.play("video.flv"); 
 
var vid:Video = new Video(); 
vid.attachNetStream(ns); 
addChild(vid);

如果想要侦听 onMetaData onCuePoint 回调方法,则需要定义用于处理这些回调方法的方法,如以下代码片断所示:

var customClient:Object = new Object(); 
customClient.onMetaData = metaDataHandler; 
function metaDataHandler(infoObject:Object):void 
{ 
    trace("metadata"); 
}

上面的代码侦听 onMetaData 回调方法并调用 metaDataHandler() 方法,后者会输出一个字符串。如果 Flash 运行时遇到一个提示点,那么即使未定义 onCuePoint 回调方法,也不会生成错误。

创建自定义类并定义用于处理回调方法的方法

以下代码将 NetStream 对象的 client 属性设置为一个自定义类 CustomClient,该类为回调方法定义处理函数:

var nc:NetConnection = new NetConnection(); 
nc.connect(null); 
 
var ns:NetStream = new NetStream(nc); 
ns.client = new CustomClient(); 
ns.play("video.flv"); 
 
var vid:Video = new Video(); 
vid.attachNetStream(ns); 
addChild(vid);

CustomClient 类如下所示:

package 
{ 
    public class CustomClient 
    { 
        public function onMetaData(infoObject:Object):void 
        { 
            trace("metadata"); 
        } 
    } 
}

CustomClient 类为 onMetaData 回调处理函数定义一个处理函数。如果遇到了提示点,并且调用了 onCuePoint 回调处理函数,则会调度一个 asyncError 事件 ( AsyncErrorEvent.ASYNC_ERROR ),显示“flash.net.NetStream 无法调用回调 onCuePoint”。为了防止发生此错误,需要在 CustomClient 类中定义一个 onCuePoint 回调方法,或者为 asyncError 事件定义一个事件处理函数。

扩展 NetStream 类并添加处理回调方法的方法

以下代码创建 CustomNetStream 类的一个实例,CustomNetStream 类在后面的代码清单中定义:

var ns:CustomNetStream = new CustomNetStream(); 
ns.play("video.flv"); 
 
var vid:Video = new Video(); 
vid.attachNetStream(ns); 
addChild(vid);

以下代码清单定义 CustomNetStream 类,该类扩展 NetStream 类、处理必要的 NetConnection 对象的创建,并处理 onMetaData onCuePoint 回调处理函数方法:

package 
{ 
    import flash.net.NetConnection; 
    import flash.net.NetStream; 
    public class CustomNetStream extends NetStream 
    { 
        private var nc:NetConnection; 
        public function CustomNetStream() 
        { 
            nc = new NetConnection(); 
            nc.connect(null); 
            super(nc); 
        } 
        public function onMetaData(infoObject:Object):void 
        { 
            trace("metadata"); 
        } 
        public function onCuePoint(infoObject:Object):void 
        { 
            trace("cue point"); 
        } 
    } 
}

如果要重命名 CustomNetStream 类中的 onMetaData() onCuePoint() 方法,可以使用以下代码:

package 
{ 
    import flash.net.NetConnection; 
    import flash.net.NetStream; 
    public class CustomNetStream extends NetStream 
    { 
        private var nc:NetConnection; 
        public var onMetaData:Function; 
        public var onCuePoint:Function; 
        public function CustomNetStream() 
        { 
            onMetaData = metaDataHandler; 
            onCuePoint = cuePointHandler; 
            nc = new NetConnection(); 
            nc.connect(null); 
            super(nc); 
        } 
        private function metaDataHandler(infoObject:Object):void 
        { 
            trace("metadata"); 
        } 
        private function cuePointHandler(infoObject:Object):void 
        { 
            trace("cue point"); 
        } 
    } 
}

扩展 NetStream 类并使其为动态类

可以扩展 NetStream 类并使其子类为动态类,以便可以动态添加 onCuePoint onMetaData 回调处理函数。以下代码清单演示了这一过程:

var ns:DynamicCustomNetStream = new DynamicCustomNetStream(); 
ns.play("video.flv"); 
 
var vid:Video = new Video(); 
vid.attachNetStream(ns); 
addChild(vid);

DynamicCustomNetStream 类如下所示:

package 
{ 
    import flash.net.NetConnection; 
    import flash.net.NetStream; 
    public dynamic class DynamicCustomNetStream extends NetStream 
    { 
        private var nc:NetConnection; 
        public function DynamicCustomNetStream() 
        { 
            nc = new NetConnection(); 
            nc.connect(null); 
            super(nc); 
        } 
    } 
}

由于 DynamicCustomNetStream 类为动态类,因此,即使 onMetaData onCuePoint 回调处理函数没有处理函数,也不会引发错误。如果想要为 onMetaData onCuePoint 回调处理函数定义方法,可以使用以下代码:

var ns:DynamicCustomNetStream = new DynamicCustomNetStream(); 
ns.onMetaData = metaDataHandler; 
ns.onCuePoint = cuePointHandler; 
ns.play("http://www.helpexamples.com/flash/video/cuepoints.flv"); 
 
var vid:Video = new Video(); 
vid.attachNetStream(ns); 
addChild(vid); 
 
function metaDataHandler(infoObject:Object):void 
{ 
    trace("metadata"); 
} 
function cuePointHandler(infoObject:Object):void 
{ 
    trace("cue point"); 
}

将 NetStream 对象的 client 属性设置为 this

通过将 client 属性设置为 this ,应用程序将在当前作用域内查找 onMetaData() onCuePoint() 方法。以下示例演示了这一效果:

var nc:NetConnection = new NetConnection(); 
nc.connect(null); 
 
var ns:NetStream = new NetStream(nc); 
ns.client = this; 
ns.play("video.flv"); 
 
var vid:Video = new Video(); 
vid.attachNetStream(ns); 
addChild(vid);

如果调用 onMetaData onCuePoint 回调处理函数,在不存在处理该回调的方法时不会生成错误。若要处理这些回调处理函数,请在代码中创建 onMetaData() onCuePoint() 方法,如以下代码片断所示:

function onMetaData(infoObject:Object):void 
{ 
    trace("metadata"); 
} 
function onCuePoint(infoObject:Object):void 
{ 
    trace("cue point"); 
}