SimpleFlvWriter for FlashPlayer10 – SimpleFlvWriterFP10(+FLAR電脳キューブデモ動画)
と言うわけでソースはこちら。
元のソースを参考にコメントをつけたりしていったので、英語が不味かったり、
ライセンスが問題だったりするかもしれない。
基本的には、元のクラスで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




