SimpleFlvWriter for FlashPlayer10 – SimpleFlvWriterFP10(+FLAR電脳キューブデモ動画)

このエントリをはてなブックマークに追加このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加このエントリをkwoutに追加
2008年11月18日 火曜日0:54:08

と言うわけでソースはこちら。
元のソースを参考にコメントをつけたりしていったので、英語が不味かったり、
ライセンスが問題だったりするかもしれない。
基本的には、元のクラスでFileStreamだった部分をByteArrayにしただけ。

/*
    SimpleFlvWriterFP10.as
        tarotarorg
        http://tarotaro.org
        11-2008
    (
    via. SimpleFlvWriter.as
        Lee Felarca
        http://www.zeropointnine.com/blog
        5-2007
        v0.8
    )
    Singleton class to create uncompressed FLV files.
    Does not handle audio. Feel free to extend.
   
    Source code licensed under a Creative Commons Attribution 3.0 License.
    http://creativecommons.org/licenses/by/3.0/
    Some Rights Reserved.

    EXAMPLE USAGE:
   
        var myWriter:SimpleFlvWriterFP10 = SimpleFlvWriterFP10.getInstance();
        myWriter.createFile(myByteArray, 320,240, 30, 120);
        myWriter.saveFrame( myBitmapData1 );
        myWriter.saveFrame( myBitmapData2 );
        myWriter.saveFrame( myBitmapData3 ); // etc.
       
        var fr:FileReference = new FileReference();
        fr.save("myByteArray,"sample.flv");
*/

package
{
    import flash.display.BitmapData;
    import flash.utils.ByteArray;

    /**
     * flv file writer for FlashPlayer10
     * <a href="http://www.zeropointnine.com/blog/simpleflvwriteras-as3-class-to-create-flvs">zero point nine ? Blog Archive ? SimpleFlvWriter.as - AS3 Class to Create FLV’s</a>
     */

    public class SimpleFlvWriterFP10
    {
        static private var _instance:SimpleFlvWriterFP10;
               
        private var frameWidth:int;
        private var frameHeight:int;
        private var frameRate:Number;
        private var duration:Number;

        private const blockWidth:int = 32;
        private const blockHeight:int = 32;
        private var previousTagSize:uint = 0;
        private var iteration:int = 0;
        private var bmp:BitmapData;
       
        private var flvData:ByteArray;

        public static function getInstance():SimpleFlvWriterFP10
        {
            if(SimpleFlvWriterFP10._instance == null)
                SimpleFlvWriterFP10._instance = new SimpleFlvWriterFP10(new SingletonEnforcer());
            return SimpleFlvWriterFP10._instance;
        }

        public function SimpleFlvWriterFP10(singletonEnforcer:SingletonEnforcer)
        {
        }

        /**
         * prepare flv file.(previous name:createFile)
         * @param    data                for save data.
         * @param    pWidth                width of video.
         * @param    pHeight                height of video.
         * @param    pFramesPerSecond   
         * @param    pDurationInSeconds
         */

        public function prepareFlv(data:ByteArray, pWidth:int, pHeight:int, pFramesPerSecond:Number, pDurationInSeconds:Number=0):void
        {
            /*
                Parameters:
               
                pFile: The file which will be created and written to
                pWidth: Video height
                pWidth: Video width
                pFramesPerSecond: Determines framerate of created video
                pDurationInSeconds: Duration of video file to be created. Used for metadata only. Optional.
            */

           
           
            frameWidth = pWidth;
            frameHeight = pHeight;
            frameRate = pFramesPerSecond;
            duration = pDurationInSeconds;

            this.flvData = data;

            // create header
            this.flvData.writeBytes(this.header());
           
            // create metadata tag
            this.flvData.writeUnsignedInt( previousTagSize );
            this.flvData.writeBytes( flvTagOnMetaData() );
        }

        public function saveFrame(pBitmapData:BitmapData):void
        {
            // bitmap dimensions should of course match parameters passed to createFile()
            bmp = pBitmapData;
            this.flvData.writeUnsignedInt( previousTagSize );
            this.flvData.writeBytes( flvTagVideo() );   
        }
       
        public function closeFile():void
        {
            //fs.close();   
        }       
               
        private function header():ByteArray
        {
            var ba:ByteArray = new ByteArray();
            ba.writeByte(0x46) // 'F'
            ba.writeByte(0x4C) // 'L'
            ba.writeByte(0x56) // 'V'
            ba.writeByte(0x01) // Version 1
            ba.writeByte(0x01) // misc flags - video stream only
            ba.writeUnsignedInt(0x09) // header length
            return ba;
        }       
       
        private function flvTagVideo():ByteArray
        {
            var tag:ByteArray = new ByteArray();
            var dat:ByteArray = videoData();
            var timeStamp:uint = uint(1000/frameRate * iteration++);

            // tag 'header'
            tag.writeByte( 0x09 );                     // tagType = video
            writeUI24(tag, dat.length);             // data size
            writeUI24(tag, timeStamp);                // timestamp in ms
            tag.writeByte(0);                        // timestamp extended, not using ***
            writeUI24(tag, 0);                        // streamID always 0
           
            // videodata           
            tag.writeBytes( dat );
           
            previousTagSize = tag.length;
            return tag;
        }
       
        private function videoData():ByteArray
        {
            var v:ByteArray = new ByteArray;
           
            // VIDEODATA 'header'
            v.writeByte(0x13); // frametype (1) + codecid (3)
           
            // SCREENVIDEOPACKET 'header'           
            // blockwidth/16-1 (4bits) + imagewidth (12bits)
            writeUI4_12(v, int(blockWidth/16) - 1,  frameWidth);
            // blockheight/16-1 (4bits) + imageheight (12bits)
            writeUI4_12(v, int(blockHeight/16) - 1, frameHeight);           

            // VIDEODATA> SCREENVIDEOPACKET> IMAGEBLOCKS:

            var yMax:int = int(frameHeight/blockHeight);
            var yRemainder:int = frameHeight % blockHeight;
            if (yRemainder> 0) yMax += 1;

            var xMax:int = int(frameWidth/blockWidth);
            var xRemainder:int = frameWidth % blockWidth;               
            if (xRemainder> 0) xMax += 1;
               
            for (var y1:int = 0; y1 <yMax; y1++)
            {
                for (var x1:int = 0; x1 <xMax; x1++)
                {
                    // create block
                    var block:ByteArray = new ByteArray();
                   
                    var yLimit:int = blockHeight;   
                    if (yRemainder> 0 && y1 + 1 == yMax) yLimit = yRemainder;

                    for (var y2:int = 0; y2 <yLimit; y2++)
                    {
                        var xLimit:int = blockWidth;
                        if (xRemainder> 0 && x1 + 1 == xMax) xLimit = xRemainder;
                       
                        for (var x2:int = 0; x2 <xLimit; x2++)
                        {
                            var px:int = (x1 * blockWidth) + x2;
                            var py:int = frameHeight - ((y1 * blockHeight) + y2); // (flv's save from bottom to top)
                            var p:uint = bmp.getPixel(px, py);

                            block.writeByte( p & 0xff );         // blue   

                            block.writeByte( p>> 8 & 0xff );     // green
                            block.writeByte( p>> 16 );         // red
                        }
                    }
                    block.compress();

                    writeUI16(v, block.length); // write block length (UI16)
                    v.writeBytes( block ); // write block
                }
            }
            return v;
        }

        private function flvTagOnMetaData():ByteArray
        {
            var tag:ByteArray = new ByteArray();
            var dat:ByteArray = metaData();

            // tag 'header'
            tag.writeByte( 18 );                     // tagType = script data
            writeUI24(tag, dat.length);             // data size
            writeUI24(tag, 0);                        // timestamp should be 0 for onMetaData tag
            tag.writeByte(0);                        // timestamp extended
            writeUI24(tag, 0);                        // streamID always 0
           
            // data tag       
            tag.writeBytes( dat );
           
            previousTagSize = tag.length;
            return tag;
        }

        private function metaData():ByteArray
        {
            // onMetaData info goes in a ScriptDataObject of data type 'ECMA Array'

            var b:ByteArray = new ByteArray();
           
            // ObjectNameType (always 2)
            b.writeByte(2);   
       
            // ObjectName (type SCRIPTDATASTRING):
            writeUI16(b, "onMetaData".length); // StringLength
            b.writeUTFBytes( "onMetaData" ); // StringData
       
            // ObjectData (type SCRIPTDATAVALUE):
           
            b.writeByte(8); // Type (ECMA array = 8 )
            b.writeUnsignedInt(7) // // Elements in array
       
            // SCRIPTDATAVARIABLES...
           
            if (duration> 0) {
                writeUI16(b, "duration".length);
                b.writeUTFBytes("duration");
                b.writeByte(0);
                b.writeDouble(duration);
            }
           
            writeUI16(b, "width".length);
            b.writeUTFBytes("width");
            b.writeByte(0);
            b.writeDouble(frameWidth);

            writeUI16(b, "height".length);
            b.writeUTFBytes("height");
            b.writeByte(0);
            b.writeDouble(frameHeight);

            writeUI16(b, "framerate".length);
            b.writeUTFBytes("framerate");
            b.writeByte(0);
            b.writeDouble(frameRate);

            writeUI16(b, "videocodecid".length);
            b.writeUTFBytes("videocodecid");
            b.writeByte(0);
            b.writeDouble(3); // 'Screen Video' = 3

            writeUI16(b, "canSeekToEnd".length);
            b.writeUTFBytes("canSeekToEnd");
            b.writeByte(1);
            b.writeByte(int(true));

            var mdc:String = "SimpleFLVWriter.as v0.8 zeropointnine.com";           
            writeUI16(b, "metadatacreator".length);
            b.writeUTFBytes("metadatacreator");
            b.writeByte(2);
            writeUI16(b, mdc.length);
            b.writeUTFBytes(mdc);
           
            // VariableEndMarker1 (type UI24 - always 9)
            writeUI24(b, 9);
       
            return b;           
        }

        private function writeUI24(stream:*, p:uint):void
        {
            var byte1:int = p>> 16;
            var byte2:int = p>> 8 & 0xff;
            var byte3:int = p & 0xff;
            stream.writeByte(byte1);
            stream.writeByte(byte2);
            stream.writeByte(byte3);
        }
       
        private function writeUI16(stream:*, p:uint):void
        {
            stream.writeByte( p>> 8 )
            stream.writeByte( p & 0xff );           
        }

        private function writeUI4_12(stream:*, p1:uint, p2:uint):void
        {
            // writes a 4-bit value followed by a 12-bit value in two sequential bytes

            var byte1a:int = p1 <<4;
            var byte1b:int = p2>> 8;
            var byte1:int = byte1a + byte1b;
            var byte2:int = p2 & 0xff;

            stream.writeByte(byte1);
            stream.writeByte(byte2);
        }       
    }
}

class SingletonEnforcer {}

/*
    FLV structure summary:

        header
        previoustagsize
        flvtag
            [info]
            videodata
                [info]
                screenvideopacket
                    [info]
                    imageblocks
                    imageblocks
                    ...
        previoustagsize
        flvtag
        ...
       

    FLV file format:
   
        header
       
        last tag size
   
        FLVTAG:
            tagtype
            datasize
            timestamp
            timestampextended
            streamid                       
            data [VIDEODATA]:
                frametype
                codecid
                videodata [SCREENVIDEOPACKET]:
                    blockwidth                        ub[4]
                    imagewidth                        ub[12]
                    blockheight                        ub[4]
                    imageheight                        ub[12]
                    imageblocks [IMAGEBLOCKS[]]:   
                        datasize                    ub[16] <same as 'ub16', i think>
                        data..
       
        last tag size
       
        FLVTAG
       
        etc.       
*/

  • ページ:
  • 1
  • 2

TrackBack URL :

コメントする

HTML convert time: 1.710 sec.