テキストエアボーカル

h_sakurai2006-08-16


エアボーカルってのが流行ってるとかなんとかってのを見まして、
うおー、これは、テキストでアニメーションさせたいなー。
思ってしまったので、作ってみました。


なんというか、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);
		}
	}
}