使用提示点和元数据Flash Player 9 和更高版本,Adobe AIR 1.0 和更高版本 使用 NetStream 回调方法可在视频播放时捕获并处理提示点和元数据事件。 使用提示点下表描述了可在 Flash Player 和 AIR 中用来捕获 F4V 和 FLV 提示点的回调方法。
下面的示例使用简单的 for..in 循环来遍历 onCuePoint() 函数收到的 infoObject 参数中的每一个属性。它在收到提示点数据时,调用 trace() 函数来显示消息: 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); function onCuePoint(infoObject:Object):void { var key:String; for (key in infoObject) { trace(key + ": " + infoObject[key]); } } 显示以下输出: parameters: name: point1 time: 0.418 type: navigation 此代码使用多种技术之一来设置运行回调方法的对象。您可以使用其他技术;有关详细信息,请参阅编写元数据和提示点的回调方法。 使用视频元数据可以使用 OnMetaData() 和 OnXMPData() 函数来访问视频文件中的元数据信息,包括提示点。 使用 OnMetaData()元数据包含有关视频文件的信息,如持续时间、宽度、高度和帧速率。添加到视频文件中的元数据信息取决于您用来编码视频文件的软件。 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); function onMetaData(infoObject:Object):void { var key:String; for (key in infoObject) { trace(key + ": " + infoObject[key]); } } 上面的代码生成如下输出: width: 320 audiodelay: 0.038 canSeekToEnd: true height: 213 cuePoints: ,, audiodatarate: 96 duration: 16.334 videodatarate: 400 framerate: 15 videocodecid: 4 audiocodecid: 2 如果您的视频没有音频,则与音频相关的元数据信息(如 audiodatarate)将返回 undefined,因为在编码期间没有将音频信息添加到元数据中。 在上面的代码中,未显示提示点信息。为了显示提示点元数据,可以使用以下函数,该函数会以递归方式显示 Object 中的项目: function traceObject(obj:Object, indent:uint = 0):void { var indentString:String = ""; var i:uint; var prop:String; var val:*; for (i = 0; i < indent; i++) { indentString += "\t"; } for (prop in obj) { val = obj[prop]; if (typeof(val) == "object") { trace(indentString + " " + prop + ": [Object]"); traceObject(val, indent + 1); } else { trace(indentString + " " + prop + ": " + val); } } } 使用上面的代码片断在 onMetaData() 方法中跟踪 infoObject 参数将产生以下输出: width: 320 audiodatarate: 96 audiocodecid: 2 videocodecid: 4 videodatarate: 400 canSeekToEnd: true duration: 16.334 audiodelay: 0.038 height: 213 framerate: 15 cuePoints: [Object] 0: [Object] parameters: [Object] lights: beginning name: point1 time: 0.418 type: navigation 1: [Object] parameters: [Object] lights: middle name: point2 time: 7.748 type: navigation 2: [Object] parameters: [Object] lights: end name: point3 time: 16.02 type: navigation 下面的示例显示 MP4 视频的元数据。它假设存在一个名为 metaDataOut 的 TextArea 对象,它将把元数据写入其中。 package { import flash.net.NetConnection; import flash.net.NetStream; import flash.events.NetStatusEvent; import flash.media.Video; import flash.display.StageDisplayState; import flash.display.Loader; import flash.display.Sprite; import flash.events.MouseEvent; public class onMetaDataExample extends Sprite { var video:Video = new Video(); public function onMetaDataExample():void { var videoConnection:NetConnection = new NetConnection(); videoConnection.connect(null); var videoStream:NetStream = new NetStream(videoConnection); videoStream.client = this; addChild(video); video.x = 185; video.y = 5; video.attachNetStream(videoStream); videoStream.play("video.mp4"); videoStream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler); } public function onMetaData(infoObject:Object):void { for(var propName:String in infoObject) { metaDataOut.appendText(propName + "=" + infoObject[propName] + "\n"); } } private function netStatusHandler(event:NetStatusEvent):void { if(event.info.code == "NetStream.Play.Stop") stage.displayState = StageDisplayState.NORMAL; } } } 对于此视频,onMetaData() 函数将生成以下输出: moovposition=731965 height=352 avclevel=21 videocodecid=avc1 duration=2.36 width=704 videoframerate=25 avcprofile=88 trackinfo=[object Object] 使用信息对象下表显示了在 onMetaData() 回调函数接收的 Object 中传递给 onMetaData() 回调函数的可能的视频元数据值。
下表显示 videocodecid 参数的可能值:
下表显示 audiocodecid 参数的可能值:
使用 onXMPData()onXMPData() 回调函数接收 Adobe F4V 或 FLV 视频文件中嵌入的 Adobe 可扩展元数据平台 (XMP) 专用信息。XMP 元数据包括提示点以及其他视频元数据。Flash Player 10 和 Adobe AIR 1.5 中引入了 XMP 元数据支持,并且后续版本都支持这种元数据。 下面的示例处理 XMP 元数据中的提示点数据: package { import flash.display.*; import flash.net.*; import flash.events.NetStatusEvent; import flash.media.Video; public class onXMPDataExample extends Sprite { public function onXMPDataExample():void { var videoConnection:NetConnection = new NetConnection(); videoConnection.connect(null); var videoStream:NetStream = new NetStream(videoConnection); videoStream.client = this; var video:Video = new Video(); addChild(video); video.attachNetStream(videoStream); videoStream.play("video.f4v"); } public function onMetaData(info:Object):void { trace("onMetaData fired"); } public function onXMPData(infoObject:Object):void { trace("onXMPData Fired\n"); //trace("raw XMP =\n"); //trace(infoObject.data); var cuePoints:Array = new Array(); var cuePoint:Object; var strFrameRate:String; var nTracksFrameRate:Number; var strTracks:String = ""; var onXMPXML = new XML(infoObject.data); // Set up namespaces to make referencing easier var xmpDM:Namespace = new Namespace("http://ns.adobe.com/xmp/1.0/DynamicMedia/"); var rdf:Namespace = new Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#"); for each (var it:XML in onXMPXML..xmpDM::Tracks) { var strTrackName:String = it.rdf::Bag.rdf::li.rdf::Description.@xmpDM::trackName; var strFrameRateXML:String = it.rdf::Bag.rdf::li.rdf::Description.@xmpDM::frameRate; strFrameRate = strFrameRateXML.substr(1,strFrameRateXML.length); nTracksFrameRate = Number(strFrameRate); strTracks += it; } var onXMPTracksXML:XML = new XML(strTracks); var strCuepoints:String = ""; for each (var item:XML in onXMPTracksXML..xmpDM::markers) { strCuepoints += item; } trace(strCuepoints); } } } 对于名为 startrekintro.f4v 的短视频文件,此示例生成以下跟踪行。这些行显示了 XMP 元数据中用于导航的提示点数据以及事件提示点: onMetaData fired onXMPData Fired <xmpDM:markers xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpDM="http://ns.adobe.com/xmp/1.0/DynamicMedia/" xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:x="adobe:ns:meta/"> <rdf:Seq> <rdf:li> <rdf:Description xmpDM:startTime="7695905817600" xmpDM:name="Title1" xmpDM:type="FLVCuePoint" xmpDM:cuePointType="Navigation"> <xmpDM:cuePointParams> <rdf:Seq> <rdf:li xmpDM:key="Title" xmpDM:value="Star Trek"/> <rdf:li xmpDM:key="Color" xmpDM:value="Blue"/> </rdf:Seq> </xmpDM:cuePointParams> </rdf:Description> </rdf:li> <rdf:li> <rdf:Description xmpDM:startTime="10289459980800" xmpDM:name="Title2" xmpDM:type="FLVCuePoint" xmpDM:cuePointType="Event"> <xmpDM:cuePointParams> <rdf:Seq> <rdf:li xmpDM:key="William Shatner" xmpDM:value="First Star"/> <rdf:li xmpDM:key="Color" xmpDM:value="Light Blue"/> </rdf:Seq> </xmpDM:cuePointParams> </rdf:Description> </rdf:li> </rdf:Seq> </xmpDM:markers> onMetaData fired 注: 在 XMP 数据中,时间是作为 DVA 刻度存储的,而不是秒。若要计算提示点时间,请将启动时间除以帧速率。例如,启动时间 7695905817600 除以帧速率 254016000000 等于 30:30。
若要查看全部原始 XMP 元数据,包括帧速率,请删除位于 onXMPData() 函数开头的第二和第三条 trace() 语句之前的注释标识符 (//)。 使用图像元数据onImageData 事件通过 AMF0 数据通道将图像数据作为字节数组发送。该数据可以是 JPEG、PNG 或 GIF 格式。可定义 onImageData() 回调方法来处理此信息,这与定义 onCuePoint 和 onMetaData 的回调方法的方式相同。下面的示例使用 onImageData() 回调方法访问并显示图像数据。 public function onImageData(imageData:Object):void { // display track number trace(imageData.trackid); var loader:Loader = new Loader(); //imageData.data is a ByteArray object loader.loadBytes(imageData.data); addChild(loader); } 使用文本元数据onTextData 事件通过 AMF0 数据通道发送文本数据。文本数据为 UTF-8 格式,并且包含有关基于 3GP 计时文本规范的格式化的更多信息。此规范定义了标准化的字幕格式。可定义 onTextData() 回调方法来处理此信息,这与定义 onCuePoint 或 onMetaData 的回调方法的方式相同。在下面的示例中,onTextData() 方法显示曲目 ID 号和对应的曲目文本。 public function onTextData(textData:Object):void { // display the track number trace(textData.trackid); // displays the text, which can be a null string, indicating old text // that should be erased trace(textData.text); } |
|