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

  • このエントリーをはてなブックマークに追加
  • 0

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

ActionScript

  1. /*
  2.     SimpleFlvWriterFP10.as
  3.         tarotarorg
  4.         http://tarotaro.org
  5.         11-2008
  6.     (
  7.     via. SimpleFlvWriter.as
  8.         Lee Felarca
  9.         http://www.zeropointnine.com/blog
  10.         5-2007
  11.         v0.8
  12.     )
  13.     Singleton class to create uncompressed FLV files.
  14.     Does not handle audio. Feel free to extend.
  15.    
  16.     Source code licensed under a Creative Commons Attribution 3.0 License.
  17.     http://creativecommons.org/licenses/by/3.0/
  18.     Some Rights Reserved.
  19.  
  20.     EXAMPLE USAGE:
  21.    
  22.         var myWriter:SimpleFlvWriterFP10 = SimpleFlvWriterFP10.getInstance();
  23.         myWriter.createFile(myByteArray, 320,240, 30, 120);
  24.         myWriter.saveFrame( myBitmapData1 );
  25.         myWriter.saveFrame( myBitmapData2 );
  26.         myWriter.saveFrame( myBitmapData3 ); // etc.
  27.        
  28.         var fr:FileReference = new FileReference();
  29.         fr.save("myByteArray,"sample.flv");
  30. */
  31.  
  32. package
  33. {
  34.     import flash.display.BitmapData;
  35.     import flash.utils.ByteArray;
  36.  
  37.     /**
  38.      * flv file writer for FlashPlayer10
  39.      * <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>
  40.      */
  41.     public class SimpleFlvWriterFP10
  42.     {
  43.         static private var _instance:SimpleFlvWriterFP10;
  44.                
  45.         private var frameWidth:int;
  46.         private var frameHeight:int;
  47.         private var frameRate:Number;
  48.         private var duration:Number;
  49.  
  50.         private const blockWidth:int = 32;
  51.         private const blockHeight:int = 32;
  52.         private var previousTagSize:uint = 0;
  53.         private var iteration:int = 0;
  54.         private var bmp:BitmapData;
  55.        
  56.         private var flvData:ByteArray;
  57.  
  58.         public static function getInstance():SimpleFlvWriterFP10
  59.         {
  60.             if(SimpleFlvWriterFP10._instance == null)
  61.                 SimpleFlvWriterFP10._instance = new SimpleFlvWriterFP10(new SingletonEnforcer());
  62.             return SimpleFlvWriterFP10._instance;
  63.         }
  64.  
  65.         public function SimpleFlvWriterFP10(singletonEnforcer:SingletonEnforcer)
  66.         {
  67.         }
  68.  
  69.         /**
  70.          * prepare flv file.(previous name:createFile)
  71.          * @param    data                for save data.
  72.          * @param    pWidth                width of video.
  73.          * @param    pHeight                height of video.
  74.          * @param    pFramesPerSecond    
  75.          * @param    pDurationInSeconds
  76.          */
  77.         public function prepareFlv(data:ByteArray, pWidth:int, pHeight:int, pFramesPerSecond:Number, pDurationInSeconds:Number=0):void
  78.         {
  79.             /*
  80.                 Parameters:
  81.                
  82.                 pFile: The file which will be created and written to
  83.                 pWidth: Video height
  84.                 pWidth: Video width
  85.                 pFramesPerSecond: Determines framerate of created video
  86.                 pDurationInSeconds: Duration of video file to be created. Used for metadata only. Optional.
  87.             */
  88.            
  89.            
  90.             frameWidth = pWidth;
  91.             frameHeight = pHeight;
  92.             frameRate = pFramesPerSecond;
  93.             duration = pDurationInSeconds;
  94.  
  95.             this.flvData = data;
  96.  
  97.             // create header
  98.             this.flvData.writeBytes(this.header());
  99.            
  100.             // create metadata tag
  101.             this.flvData.writeUnsignedInt( previousTagSize );
  102.             this.flvData.writeBytes( flvTagOnMetaData() );
  103.         }
  104.  
  105.         public function saveFrame(pBitmapData:BitmapData):void
  106.         {
  107.             // bitmap dimensions should of course match parameters passed to createFile()
  108.             bmp = pBitmapData;
  109.             this.flvData.writeUnsignedInt( previousTagSize );
  110.             this.flvData.writeBytes( flvTagVideo() );    
  111.         }
  112.        
  113.         public function closeFile():void
  114.         {
  115.             //fs.close();    
  116.         }        
  117.                
  118.         private function header():ByteArray
  119.         {
  120.             var ba:ByteArray = new ByteArray();
  121.             ba.writeByte(0x46) // 'F'
  122.             ba.writeByte(0x4C) // 'L'
  123.             ba.writeByte(0x56) // 'V'
  124.             ba.writeByte(0x01) // Version 1
  125.             ba.writeByte(0x01) // misc flags - video stream only
  126.             ba.writeUnsignedInt(0x09) // header length
  127.             return ba;
  128.         }        
  129.        
  130.         private function flvTagVideo():ByteArray
  131.         {
  132.             var tag:ByteArray = new ByteArray();
  133.             var dat:ByteArray = videoData();
  134.             var timeStamp:uint = uint(1000/frameRate * iteration++);
  135.  
  136.             // tag 'header'
  137.             tag.writeByte( 0x09 );                     // tagType = video
  138.             writeUI24(tag, dat.length);             // data size
  139.             writeUI24(tag, timeStamp);                // timestamp in ms
  140.             tag.writeByte(0);                        // timestamp extended, not using ***
  141.             writeUI24(tag, 0);                        // streamID always 0
  142.            
  143.             // videodata            
  144.             tag.writeBytes( dat );
  145.            
  146.             previousTagSize = tag.length;
  147.             return tag;
  148.         }
  149.        
  150.         private function videoData():ByteArray
  151.         {
  152.             var v:ByteArray = new ByteArray;
  153.            
  154.             // VIDEODATA 'header'
  155.             v.writeByte(0x13); // frametype (1) + codecid (3)
  156.            
  157.             // SCREENVIDEOPACKET 'header'            
  158.             // blockwidth/16-1 (4bits) + imagewidth (12bits)
  159.             writeUI4_12(v, int(blockWidth/16) - 1,  frameWidth);
  160.             // blockheight/16-1 (4bits) + imageheight (12bits)
  161.             writeUI4_12(v, int(blockHeight/16) - 1, frameHeight);            
  162.  
  163.             // VIDEODATA > SCREENVIDEOPACKET > IMAGEBLOCKS:
  164.  
  165.             var yMax:int = int(frameHeight/blockHeight);
  166.             var yRemainder:int = frameHeight % blockHeight;
  167.             if (yRemainder > 0) yMax += 1;
  168.  
  169.             var xMax:int = int(frameWidth/blockWidth);
  170.             var xRemainder:int = frameWidth % blockWidth;                
  171.             if (xRemainder > 0) xMax += 1;
  172.                
  173.             for (var y1:int = 0; y1 < yMax; y1++)
  174.             {
  175.                 for (var x1:int = 0; x1 < xMax; x1++)
  176.                 {
  177.                     // create block
  178.                     var block:ByteArray = new ByteArray();
  179.                    
  180.                     var yLimit:int = blockHeight;    
  181.                     if (yRemainder > 0 && y1 + 1 == yMax) yLimit = yRemainder;
  182.  
  183.                     for (var y2:int = 0; y2 < yLimit; y2++)
  184.                     {
  185.                         var xLimit:int = blockWidth;
  186.                         if (xRemainder > 0 && x1 + 1 == xMax) xLimit = xRemainder;
  187.                        
  188.                         for (var x2:int = 0; x2 < xLimit; x2++)
  189.                         {
  190.                             var px:int = (x1 * blockWidth) + x2;
  191.                             var py:int = frameHeight - ((y1 * blockHeight) + y2); // (flv's save from bottom to top)
  192.                             var p:uint = bmp.getPixel(px, py);
  193.  
  194.                             block.writeByte( p & 0xff );         // blue    
  195.  
  196.  
  197.                             block.writeByte( p >> 8 & 0xff );     // green
  198.                             block.writeByte( p >> 16 );         // red
  199.                         }
  200.                     }
  201.                     block.compress();
  202.  
  203.                     writeUI16(v, block.length); // write block length (UI16)
  204.                     v.writeBytes( block ); // write block
  205.                 }
  206.             }
  207.             return v;
  208.         }
  209.  
  210.         private function flvTagOnMetaData():ByteArray
  211.         {
  212.             var tag:ByteArray = new ByteArray();
  213.             var dat:ByteArray = metaData();
  214.  
  215.             // tag 'header'
  216.             tag.writeByte( 18 );                     // tagType = script data
  217.             writeUI24(tag, dat.length);             // data size
  218.             writeUI24(tag, 0);                        // timestamp should be 0 for onMetaData tag
  219.             tag.writeByte(0);                        // timestamp extended
  220.             writeUI24(tag, 0);                        // streamID always 0
  221.            
  222.             // data tag        
  223.             tag.writeBytes( dat );
  224.            
  225.             previousTagSize = tag.length;
  226.             return tag;
  227.         }
  228.  
  229.         private function metaData():ByteArray
  230.         {
  231.             // onMetaData info goes in a ScriptDataObject of data type 'ECMA Array'
  232.  
  233.             var b:ByteArray = new ByteArray();
  234.            
  235.             // ObjectNameType (always 2)
  236.             b.writeByte(2);    
  237.        
  238.             // ObjectName (type SCRIPTDATASTRING):
  239.             writeUI16(b, "onMetaData".length); // StringLength
  240.             b.writeUTFBytes( "onMetaData" ); // StringData
  241.        
  242.             // ObjectData (type SCRIPTDATAVALUE):
  243.            
  244.             b.writeByte(8); // Type (ECMA array = 8 )
  245.             b.writeUnsignedInt(7) // // Elements in array
  246.        
  247.             // SCRIPTDATAVARIABLES...
  248.            
  249.             if (duration > 0) {
  250.                 writeUI16(b, "duration".length);
  251.                 b.writeUTFBytes("duration");
  252.                 b.writeByte(0);
  253.                 b.writeDouble(duration);
  254.             }
  255.            
  256.             writeUI16(b, "width".length);
  257.             b.writeUTFBytes("width");
  258.             b.writeByte(0);
  259.             b.writeDouble(frameWidth);
  260.  
  261.             writeUI16(b, "height".length);
  262.             b.writeUTFBytes("height");
  263.             b.writeByte(0);
  264.             b.writeDouble(frameHeight);
  265.  
  266.             writeUI16(b, "framerate".length);
  267.             b.writeUTFBytes("framerate");
  268.             b.writeByte(0);
  269.             b.writeDouble(frameRate);
  270.  
  271.             writeUI16(b, "videocodecid".length);
  272.             b.writeUTFBytes("videocodecid");
  273.             b.writeByte(0);
  274.             b.writeDouble(3); // 'Screen Video' = 3
  275.  
  276.             writeUI16(b, "canSeekToEnd".length);
  277.             b.writeUTFBytes("canSeekToEnd");
  278.             b.writeByte(1);
  279.             b.writeByte(int(true));
  280.  
  281.             var mdc:String = "SimpleFLVWriter.as v0.8 zeropointnine.com";            
  282.             writeUI16(b, "metadatacreator".length);
  283.             b.writeUTFBytes("metadatacreator");
  284.             b.writeByte(2);
  285.             writeUI16(b, mdc.length);
  286.             b.writeUTFBytes(mdc);
  287.            
  288.             // VariableEndMarker1 (type UI24 - always 9)
  289.             writeUI24(b, 9);
  290.        
  291.             return b;            
  292.         }
  293.  
  294.         private function writeUI24(stream:*, p:uint):void
  295.         {
  296.             var byte1:int = p >> 16;
  297.             var byte2:int = p >> 8 & 0xff;
  298.             var byte3:int = p & 0xff;
  299.             stream.writeByte(byte1);
  300.             stream.writeByte(byte2);
  301.             stream.writeByte(byte3);
  302.         }
  303.        
  304.         private function writeUI16(stream:*, p:uint):void
  305.         {
  306.             stream.writeByte( p >> 8 )
  307.             stream.writeByte( p & 0xff );            
  308.         }
  309.  
  310.         private function writeUI4_12(stream:*, p1:uint, p2:uint):void
  311.         {
  312.             // writes a 4-bit value followed by a 12-bit value in two sequential bytes
  313.  
  314.             var byte1a:int = p1 << 4;
  315.             var byte1b:int = p2 >> 8;
  316.             var byte1:int = byte1a + byte1b;
  317.             var byte2:int = p2 & 0xff;
  318.  
  319.             stream.writeByte(byte1);
  320.             stream.writeByte(byte2);
  321.         }        
  322.     }
  323. }
  324.  
  325. class SingletonEnforcer {}
  326.  
  327. /*
  328.     FLV structure summary:
  329.  
  330.         header
  331.         previoustagsize
  332.         flvtag
  333.             [info]
  334.             videodata
  335.                 [info]
  336.                 screenvideopacket
  337.                     [info]
  338.                     imageblocks
  339.                     imageblocks
  340.                     ...
  341.         previoustagsize
  342.         flvtag
  343.         ...
  344.        
  345.  
  346.     FLV file format:
  347.    
  348.         header
  349.        
  350.         last tag size
  351.    
  352.         FLVTAG:
  353.             tagtype
  354.             datasize
  355.             timestamp
  356.             timestampextended
  357.             streamid                        
  358.             data [VIDEODATA]:
  359.                 frametype
  360.                 codecid
  361.                 videodata [SCREENVIDEOPACKET]:
  362.                     blockwidth                        ub[4]
  363.                     imagewidth                        ub[12]
  364.                     blockheight                        ub[4]
  365.                     imageheight                        ub[12]
  366.                     imageblocks [IMAGEBLOCKS[]]:    
  367.                         datasize                    ub[16] <same as 'ub16', i think>
  368.                         data..
  369.        
  370.         last tag size
  371.        
  372.         FLVTAG
  373.        
  374.         etc.        
  375. */
スポンサーリンク
スポンサーリンク
  • このエントリーをはてなブックマークに追加

フォローする

スポンサーリンク
スポンサーリンク