キューポイントとメタデータの使用

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

このコードでは、コールバックメソッドを実行するオブジェクトを設定する技法の 1 つを使用しています。他の技法を使用することもできます。詳しくは、メタデータとキューポイントのコールバックメソッドの作成を参照してください。

ビデオメタデータの使用

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 を返します。

前述のコードでは、キューポイント情報は表示されていません。 キューポイントメタデータを表示するには、オブジェクトのアイテムを再帰的に表示する次の関数を使用することができます。

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() コールバック関数に渡すことのできる、受信したオブジェクト内のビデオメタデータの値を示します。

パラメーター

説明

aacaot

AAC オーディオオブジェクトタイプ。0、1 または 2 がサポートされています。

avclevel

10、11、20、21 などの AVC IDC レベル番号です。

avcprofile

55、77、100 などの AVC プロファイル番号です。

audiocodecid

使用されたオーディオコーデック(コード / デコード技法)を示すストリング(「.Mp3」や「mp4a」など)です。

audiodatarate

オーディオがエンコードされるレートをキロバイト秒で示す数値です。

audiodelay

元の FLV ファイルの「time 0」の時間を示す数値です。 オーディオと正しく同期化するには、ビデオコンテンツを少し遅延させる必要があります。

canSeekToEnd

ブール値です。プログレッシブダウンロードされるビデオクリップの最後をシークできるようにするために、最後のフレームにキーフレームを付けて FLV ファイルをエンコードした場合に true になります。最後のフレームにキーフレームを付けずに FLV ファイルをエンコードした場合は false になります。

cuePoints

オブジェクトの配列。FLV ファイルに埋め込まれたそれぞれのキューポイントに 1 つずつあります。 FLV ファイルにキューポイントがない場合は、値は未定義となります。 各オブジェクトには次のプロパティがあります。

  • type:キューポイントのタイプを「navigation」または「event」として指定するストリング。

  • name:キューポイントの名前を示すストリング。

  • time:キューポイントの時間を示す数値。小数点以下 3 桁(ミリ秒)まで使用します。

  • parameters:キューポイントを作成するときにユーザーによって指定される、名前と値のペアを持つオプションのオブジェクト。

duration

ビデオファイルの長さを秒単位で示す数値です。

framerate

FLV ファイルのフレームレートを示す数値です。

height

FLV ファイルの高さをピクセル単位で示す数値です。

seekpoints

ミリ秒単位のタイムスタンプとして使用可能なキーフレームの一覧を示す配列です(オプション)。

tags

「ilst」アトム内の情報を表すキーと値のペアの配列であり、MP4 ファイルの ID3 タグと同等です。iTunes ではこれらのタグが使用されます。アートワークが使用可能な場合に、その表示に使用することができます。

trackinfo

サンプル説明 ID など、MP4 ファイル内のすべてのトラックに関する情報を提供するオブジェクトです。

videocodecid

ビデオのエンコードに使用されたコーデックバージョンを示すストリングです。例えば、「avc1」や「VP6F」などです。

videodatarate

FLV ファイルのビデオデータレートを示す数値です。

videoframerate

MP4 ビデオのフレームレートです。

width

FLV ファイルの幅をピクセル単位で示す数値です。

次の表に、videocodecid パラメーターで使用可能な値をまとめます。

videocodecid

コーデック名

2

Sorenson H.263

3

Screen Video(SWF バージョン 7 以降のみ)

4

VP6(SWF バージョン 8 以降のみ)

5

アルファチャンネルを使用する VP6 Video(SWF バージョン 8 以降のみ)

次の表に、audiocodecid パラメーターで使用可能な値をまとめます。

audiocodecid

コーデック名

0

uncompressed

1

ADPCM

2

MP3

4

Nellymoser @ 16 kHz モノラル

5

Nellymoser、8kHz モノラル

6

Nellymoser

10

AAC

11

Speex

onXMPData() の使用

onXMPData() コールバック関数は、Adobe F4V または FLV ビデオファイルに埋め込まれている Adobe Extensible Metadata Platform(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 Tick で格納されます。キューポイント時間を計算するには、開始時刻をフレームレートで除算します。例えば、7695905817600 の開始時刻を 254016000000 のフレームレートで除算すると、30:30 になります。

フレームレートを含む完全に未処理の XMP メタデータを表示するには、秒の前のコメント識別子(//)と、onXMPData() 関数の先頭にある 3 つ目の trace() ステートメントを削除します。

XMP について詳しくは、以下を参照してください。

イメージメタデータの使用

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 Timed Text 仕様に基づくフォーマットに関する追加情報を格納します。この仕様では、標準化されたサブタイトル形式が定義されます。この情報を処理する 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); 
}