使用提示點和中繼資料

Flash Player 9 以及更新的版本,Adobe AIR 1.0 以及更新的版本

使用 NetStream 回呼方法,即可在視訊播放時,捕捉及處理提示點和中繼資料事件。

使用提示點

下表說明您可以用來在 Flash Player 和 AIR 中捕捉 F4V 和 FLV 提示點的回呼方法。

執行階段

F4V

FLV

Flash Player 9/ AIR1.0

 

OnCuePoint

   

OnMetaData

Flash Player 10

 

OnCuePoint

 

OnMetaData

OnMetaData

 

OnXMPData

OnXMPData

下列範例會使用簡單的 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]

使用資訊物件

下表列出視訊中繼資料的可能值,這些值會傳遞至所收到之 Object 中的 onMetaData() 回呼函數:

參數

說明

aacaot

AAC 音效物件類型,支援 0、1 或 2。

avclevel

AVC IDC 階層編號,例如 10、11、20、21 等。

avcprofile

AVC 描述檔編號,例如 55、77、100 等。

audiocodecid

指定所使用之音效轉碼器 (編碼/解碼技術) 的字串,例如「.Mp3」或「mp4a」。

audiodatarate

指出編碼音效時使用的速率數字,即每秒的 KB 數。

audiodelay

數字,指出原始 FLV 檔的 FLV 檔「time 0」存在的時間。視訊內容必須經過些許延遲,才能正確地同步化音訊。

canSeekToEnd

Boolean 值,當 FLV 檔是以最後一個影格上的關鍵影格編碼,以允許搜尋漸進式下載視訊檔案的結尾時,則為 true。如果 FLV 檔不是以最後一個影格上的關鍵影格編碼,則為 false

cuePoints

物件的陣列,內嵌於 FLV 檔的其中一個提示點。如果 FLV 檔沒有任何提示點,值即為 undefined。每個物件都有下列屬性:

  • type:字串,用以指定做為「navigation」或「event」的提示點類型。

  • name:代表提示點名稱的字串。

  • time:數字,具有三位小數位數 (毫秒) 的提示點時間,以秒為單位。

  • parameters:具有使用者在建立提示點時所指定之名稱值配對的選擇性物件。

duration

數字,指定視訊檔案的持續時間,以秒為單位。

framerate

FLV 檔的影格速率。

height

數字,表示 FLV 檔的高度,以像素為單位。

seekpoints

陣列,將可用的關鍵影格列出做為以秒為單位的時間戳記。選擇性。

tags

索引鍵值配對的陣列,表示「ilst」Atom (MP4 檔之 ID3 標籤的對等項目) 中的資訊。iTunes 會使用這些標籤。如果可以的話,也能用於顯示圖案。

trackinfo

提供 MP4 檔中所有音軌之資訊 (包括其取樣描述 ID) 的物件。

videocodecid

字串,代表用來編碼視訊的編碼器版本。例如,「avc1」或「VP6F」。

videodatarate

FLV 檔的視訊資料速率。

videoframerate

MP4 視訊的影格速率。

width

數字,表示 FLV 檔的寬度,以像素為單位。

下表列出 videocodecid 參數的可能值:

videocodecid

轉碼器名稱

2

Sorenson H.263

3

螢幕視訊 (僅 SWF 第 7 版和更新版本)

4

VP6 (僅 SWF 第 8 版和更新版本)

5

具有 Alpha 色版的 VP6 視訊 (僅 SWF 第 8 版和更新版本)

下表列出 audiocodecid 參數的可能值:

audiocodecid

轉碼器名稱

0

未壓縮

1

ADPCM

2

Mp3

4

Nellymoser 16 kHz 單聲道

5

Nellymoser 8kHz 單聲道

6

Nellymoser

10

AAC

11

Speex

使用 onXMPData()

onXMPData() 回呼函數會接收內嵌於 Adobe F4V 或 FLV 視訊檔案中的 Adobe 可延伸中繼資料平台 (XMP) 專屬資訊。XMP 中繼資料包含提示點以及其它視訊中繼資料。XMP 中繼資料支援是 Flash Player 10 和 Adobe AIR 1.5 新增的功能,後續版本都將持續提供這項支援。

下列範例會處理 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() 陳述式之前的註解識別項 (//’s)。

使用影像中繼資料

onImageData 事件會透過 AMF0 資料通道,傳送影像資料做為位元組陣列。資料的格式可以是 JPEG、PNG 或 GIF。以您為 onCuePointonMetaData 定義回呼方法的相同方式來定義 onImageData() 回呼方法,即可處理此資訊。下列範例會使用 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 定時文字規格進行格式化的其它相關資訊。此規格會定義標準化的副標題格式。以您為 onCuePointonMetaData 定義回呼方法的相同方式,定義 onTextData() 回呼方法即可處理此資訊。在下列範例中,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); 
}