flv视频播放中,编写元数据和提示点的回调方法
当播放器收到特定元数据或到达特定提示点时,可以在应用程序中触发动作。当这些事件发生时,必须将特定回调方法用作事件处理函数。NetStream 类指定了在播放期间可发生的以下元数据事件:onCuePoint(仅限 FLV 文件)、onImageData、onMetaData、onPlayStatus、onTextData 和 onXMPData。
必须为这些处理函数编写回调方法,否则,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 对象找不到 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 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 对象的创建,并处理 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");
}