« リンケージの設定と同時にクラスファイルを自動生成するJSFLコマンド | メイン | 七五三ゲームを作ってみましたよ。 »

2008年7月14日

[as3] NetStreamのonMetaDataイベント

AS3 で FLV のメタデータの取り方が分からずに、かなり無駄に時間を費やしてしまった。。。
FLV のメタデータは NetStream から onMetaData を使って取得できるんだけども、
この onMetaData の使い方がさっぱり分からなかったので忘れないようにメモ。
経過があまりにもアホくさすぎて絶対忘れないけども。

ビデオメタデータの使用
NetStreamオブジェクトの client プロパティを指定して、
指定したオブジェクトに onMetaData メソッドを定義しておくと使える。

この client プロパティの存在に気づかずに四苦八苦してた自分が情けない。

挙句の果てに、ここ見て自前で ByteArray からメタデータ取ろうとしてしまった。

ByteArray から取得した FLV の値を出力した一例。
// FLV Header
Signature = FLV
Version = 1
Flags = 5
Offset = 9

// FLV Stream
PreviousTagSize = 0

// FLV Tag
Type = 18
BodyLength = 224
Timestamp = 0
TimestampExtended = 0
StreamId = 0

// MetaData
videodatarate = 1000
audiocodecid = 2
canSeekToEnd = true
duration = 8.866
audiodatarate = 128
framerate = 30
width = 450
videocodecid = 4
height = 400
audiodelay = 0.038

アホですよ。まったく。

ここまでやって、ちゃんと取得できることに気づいた。
そもそも何で AS3 なのに NetStream はこんな実装なんだ。
腹立たしい。アホか!

一応以下にソース残しときます。
結果的に中途半端なものになってますが、
なんか消してしまうのも勿体ない気がしてしまって。(費やした時間が。)

public function readFLV(data:ByteArray):void
{
    // FLV Header
    var Signature:String = data.readUTFBytes(3);
    var Version:uint = uint8(data);
    var Flags:uint = uint8(data);
    var Offset:uint = uint32(data);
    
    // FLV Stream
    var PreviousTagSize:uint = uint32(data);
    
    // FLV Tag
    var Type:uint = uint8(data);
    var BodyLength:uint = uint24(data);
    var Timestamp:uint = uint24(data);
    var TimestampExtended:uint = uint8(data);
    var StreamId:uint = uint24(data);
    var Body:ByteArray = new ByteArray();
    data.readBytes(Body, 0, BodyLength);
    
    
    // Body(FLV Tag Type = 0x12 : AMF)
    var a:uint = uint8(Body);// ???
    var b:uint = uint8(Body);// ???
    
    // MetaData
    readString(Body);
    var metadata:Object = readMixedArray(Body);
    
    
    trace(Signature, Version, Flags, Offset);
    trace(PreviousTagSize);
    trace(Type, BodyLength, Timestamp, TimestampExtended, StreamId);
    
    // MetaData の中身
    for (var val:String in metadata) {
        trace(val + "=" + metadata[val]);
    }
    
}

public function  uint8(data:ByteArray):uint { return data.readByte(); }
public function uint16(data:ByteArray):uint { return data.readUnsignedShort(); }
public function uint24(data:ByteArray):uint { return data[data.position++]<<16 | data[data.position++]<<8 | data[data.position++]; }
public function uint32(data:ByteArray):uint { return data.readUnsignedInt(); }

public function readNumber(data:ByteArray):Number
{
    return data.readDouble();
}
public function readBoolean(data:ByteArray):Boolean
{
    return data.readByte() == 0x01;
}
public function readString(data:ByteArray):String
{
    var len:uint = data.readByte();
    return data.readUTFBytes(len);
}
public function readObject(data:ByteArray):Object
{
    return null;
}
public function readMixedArray(data:ByteArray):Object
{
    data.readByte();
    var length:uint = data.readInt();
    var res:Object = { };
    var value:*;
    var name:String;
    var type:uint;
    var len:uint = data.length;
    for (;; ) {
        var separator:uint = data.readByte();
        name = readString(data);
        type = data.readByte();
        
        if (type == 0x09) break;
        
        switch(type) {
            case 0x00 : { value = readNumber(data); break; } // Object
            case 0x01 : { value = readBoolean(data); break; } // Object
            case 0x02 : { value = readString(data); break; } // Object
            case 0x03 : { value = readObject(data); break; } // Object
            //case 0x04 : { break; } // Movie Clip
            case 0x05 : { value = null; break; } // Object
            case 0x06 : { value = undefined; break; } // Object
            //case 0x07 : { break; } // Reference
            case 0x08 : { value = readMixedArray(data); break; } // MixedArray
            case 0x0a : { value = readArray(data); break; } // Array
            case 0x0b : { value = readDate(data); break; } // Date
        }
        res[name] = value;
    }
    return res;
}
public function readArray(data:ByteArray):Array
{
    return null;
}
public function readDate(data:ByteArray):String
{
    return null;
}

トラックバック(0)

このブログ記事を参照しているブログ一覧: NetStreamのonMetaDataイベント

このブログ記事に対するトラックバックURL: http://system.seyself.com/mt-tb.cgi/507

コメントする


画像の中に見える文字を入力してください。

しばらく時間が経過すると、システム内部と表示されている文字内容に食い違いが発生するようなので、
投稿する前にページをリロードすることをお勧めします。
リロードしてもフォームの内容は維持されます。