テキストエアボーカル
エアボーカルってのが流行ってるとかなんとかってのを見まして、
うおー、これは、テキストでアニメーションさせたいなー。
思ってしまったので、作ってみました。
なんというか、flvプレーヤ、
プログラマ用(というか、単にUI作るのめんどいだけ)になっております。
flvファイルを再生しながら、テキストに変換して再生します。
以下ソース
続きを読むって、これだけだったんだ。。。どんな、めんどくさがり屋だ。
package { import flash.display.*; import flash.events.*; import flash.media.*; import flash.net.*; import flash.filters.*; import flash.geom.*; import flash.utils.*; import flash.text.*; public class VideoEx extends Sprite { private var connection: NetConnection;//コネクション private var stream: NetStream; //ストリーム private var video: Video; private var bitmapData:BitmapData; private var textField:TextField; private var format:TextFormat = new TextFormat(); private var rect:Rectangle = new Rectangle(0, 0, VW, VH); private var dt3:Array; //コンストラクタ // private static var VW:int = 320/8*2; // private static var VH:int = 240/16*2; private static var VW:int = 800/8; private static var VH:int = int(600/16); public function VideoEx() { //コネクションの生成 connection=new NetConnection(); connection.addEventListener(NetStatusEvent.NET_STATUS,netStatusHandler); connection.addEventListener(SecurityErrorEvent.SECURITY_ERROR,securityErrorHandler); connection.connect(null); bitmapData = new BitmapData(VW, VH); mkArray(); } private function mkArray():void { var ba:ByteArray = new ByteArray(); ba.position = 0; for(var i:int = 0x20; i < 127;i++) ba.writeByte(i); ba.position = 0; var text:String = ""; for(i = 0x20; i < 127;i++) text += ba.readUTFBytes(1); var size:int = 8; textField = new TextField(); textField.text = text; textField.autoSize =TextFieldAutoSize.LEFT;//オートサイズ format.font = "_等幅"; //フォント名 format.color = 0xdd8800;//色 format.size = size*2; textField.setTextFormat(format); addChild(textField); var bd:BitmapData = new BitmapData((127-0x20)*size,size*3); bd.draw(textField); var r1:Rectangle = new Rectangle(0, 0, (127-0x20)*size,size*3); ba = bd.getPixels(r1); var dt:Array = new Array(); var dt2:Object = new Object(); for(i = 0; i < 127-0x20;i++) { var d:int = i; for(var x:int = 0; x < size;x++) { for(var y:int = 0; y < size*3;y++) { var n:int = i*size + x + y * (127-0x20)*size; d += ba[n*4+1]; } } dt2[d] = i + 0x20; dt[dt.length] = d; } dt = dt.sort().reverse(); var dt4:Array = new Array(); dt3 = new Array(); for(i = 0; i < 127-0x20;i++) { dt4[i] = dt2[dt[i]]; } var max:int = dt[0]; var min:int = dt[dt.length-1]; for(i= 0; i < 256;i++) { var n2:int = 127-32-1-find(dt, int(i*(max-min)/255) + min); // var n1:int = int(i*(127-32-1)/255); // dt3[i] = chr(dt4[int((n2+n1)/2)]); dt3[i] = chr(dt4[n2]); } } private function find(dt:Array, no:int):int { var len:int = dt.length; for(var i:int = 0; i < len; i++) { if (no > dt[i]-10) return i; } return len - 1; } private function chr(a:int):String { var ba:ByteArray = new ByteArray(); ba.position = 0; ba.writeByte(a); ba.position = 0; return ba.readUTFBytes(1); } private function netStatusHandler(evt:NetStatusEvent):void { switch (evt.info.code) { case "NetConnection.Connect.Success": stream = new NetStream(connection); stream.addEventListener(NetStatusEvent.NET_STATUS,netStatusHandler); stream.addEventListener(AsyncErrorEvent.ASYNC_ERROR,asyncErrorHandler); video =new Video(VW,VH); video.attachNetStream(stream); var filter: ColorMatrixFilter = new ColorMatrixFilter([ 0.6,0.6,0.6,0, -75, 0,0,0,1,0, 0,0,0,1,0, 0,0,0,1,0 ]); video.filters = [filter]; this.addEventListener(Event.ENTER_FRAME, renderHandler); stream.play("air3.flv"); break; case "NetStream.Play.StreamNotFound": trace("ファイルが見つからない"); break; } } private function securityErrorHandler(evt:SecurityErrorEvent):void { trace("セキュリティーエラー"); } private function asyncErrorHandler(evt:AsyncErrorEvent):void { trace("同期エラー"); } private function renderHandler(event:Event):void { if (video == null) return; var r: Rectangle = rect; bitmapData.draw(video); var ba:ByteArray = bitmapData.getPixels(r); var text:String = ""; for (var y:int = 0; y < VH; y++) { var off:int = y * VW * 4 + 1; for (var x:int = 0; x < VW; x++, off += 4) { text += dt3[ba[off]]; } text += "\n"; } textField.text = text; textField.setTextFormat(format); } } }