flv视频播放中,编写元数据和提示点的回调方法

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

必须为这些处理函数编写回调方法,否则,Flash Player 可能会引发错误。例如,以下代码播放 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 对象找不到 onMetaDataonCuePoint 回调方法。在应用程序中定义这些回调方法有多种方式:

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

通过将 client 属性设置为一个 Object 或设置为 NetStream 的一个子类,可以重新发送 onMetaDataonCuePoint 回调方法或彻底忽略这些方法。以下示例演示如何使用空的 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);

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

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

上面的代码侦听 onMetaData 回调方法并调用 metaDataHandler() 方法,后者会输出一个字符串。如果 Flash Player 遇到一个提示点,那么即使未定义 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 对象的创建,并处理 onMetaDataonCuePoint 回调处理函数方法:

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 类并使其子类为动态类,以便可以动态添加 onCuePointonMetaData 回调处理函数。以下代码清单演示了这一过程:

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 类为动态类,因此,即使 onMetaDataonCuePoint 回调处理函数没有处理函数,也不会引发错误。如果想要为 onMetaDataonCuePoint 回调处理函数定义方法,可以使用以下代码:

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

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

function onMetaData(infoObject:Object):void 
{
trace("metadata");
}
function onCuePoint(infoObject:Object):void
{
trace("cue point");
}
posted @ 2010-05-16 19:47  rob_2010  阅读(712)  评论(0编辑  收藏  举报