In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

FP10.1用 超適当unionボイチャ

マウスダウンの間に録音、放すと送信
/**
 * Copyright keno42 ( http://wonderfl.net/user/keno42 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/b4uP
 */

// マウスダウンの間に録音、放すと送信
// forked from keno42's FP10.1用 マイク録音&再生
package  
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.SampleDataEvent;
	import flash.media.Microphone;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.text.TextField;
	import flash.utils.ByteArray;
	import flash.utils.Dictionary;
	import mx.utils.Base64Decoder;
	import mx.utils.Base64Encoder;
	import net.user1.reactor.IClient;
	import net.user1.reactor.Reactor;
	import net.user1.reactor.ReactorEvent;
	import net.user1.reactor.Room;
	import net.user1.reactor.RoomEvent;
	public class VoiceChat extends Sprite
	{
		private var re:Reactor = new Reactor();
		private var r:Room;
		
		private var recording:Sprite = new Sprite();
		private const recordR:Number = 100; // 半径
		private const recordW:Number = 40; // ボリュームに応じた揺れ幅
		private var mic:Microphone;
		private var info:TextField = new TextField();
		public function VoiceChat() 
		{
			info.autoSize = "left";
			info.text = "接続中...";
			addChild(info);
			re.addEventListener(ReactorEvent.READY, onReady);
			re.connect("tryunion.com", 9100);
		}
		private function onReady(e:ReactorEvent):void {
			info.text = "ログイン完了: user" + re.getClientManager().self().getClientID();
			r = re.getRoomManager().createRoom("w.vr");
			r.addMessageListener("voiceChat", onVoiceChat);
			r.addEventListener(RoomEvent.CLIENT_COUNT, onClientCount);
			r.join();
			
			addChild(recording);
			mic = Microphone.getMicrophone();
			mic.rate = 44;
			mic.setSilenceLevel(30,2);
			mic.setLoopBack(true); // 一度設定でOK押させる
			mic.setLoopBack(false);
			stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
			stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
		}
		private function onClientCount(e:RoomEvent):void {
			info.appendText( "\nクライアント数:" + e.getNumClients() );
		}
		private function onDown(e:MouseEvent):void {
			recording.x = e.localX;
			recording.y = e.localY;
			myVoice = new ByteArray();
			mic.addEventListener(SampleDataEvent.SAMPLE_DATA, onRecord);
		}
		private function onUp(e:MouseEvent):void {
			recording.graphics.clear();
			mic.removeEventListener(SampleDataEvent.SAMPLE_DATA, onRecord);
			myVoice.position = 0;
			myVoice.compress();
			var sendMsg:String = "";
			var encoder:Base64Encoder = new Base64Encoder();
			encoder.encodeBytes(myVoice);
			sendMsg = encoder.flush();
			if( sendMsg.length < 100000 ) {
				info.appendText( "\n送信: " + sendMsg.length + " bytes" );
				r.sendMessage("voiceChat", false, null, sendMsg);
			} else {
				info.text = "100KB以下のメッセージしか送れません";
			}
		}

		private function onVoiceChat(from:IClient, msg:String):void {
			info.appendText( "\n受信: " + msg.length + " bytes, user" + from.getClientID() );
			var ba:ByteArray = new ByteArray();
			var decoder:Base64Decoder = new Base64Decoder();
			decoder.decode(msg);
			ba = decoder.flush();
			ba.uncompress();
			var sound:Sound = new Sound();
			sound.addEventListener(SampleDataEvent.SAMPLE_DATA, function(e:SampleDataEvent):void {
				for ( var i:int = 0; i < 8192; i++ ) {
					var temp:Number = ( ba.bytesAvailable > 0)?ba.readFloat():0.0;
					e.data.writeFloat(temp);
					e.data.writeFloat(temp);
				}
			});
			sound.play();
		}
		private var myVoice:ByteArray = new ByteArray();
		private function onRecord(e:SampleDataEvent):void {
			myVoice.writeBytes(e.data);
			e.data.position = 0;
			recording.graphics.clear();
			recording.graphics.lineStyle(0);
			var fr:Number = recordR + recordW * e.data.readFloat();
			var fa:Number = Math.PI / 128;
			recording.graphics.moveTo( fr * Math.cos(fa), fr * Math.sin(fa) );
			for ( var i:int = 2; i < 256; i += 2 ) {
				var r:Number = recordR + recordW * e.data.readFloat();
				var a:Number = i * Math.PI / 128;
				recording.graphics.lineTo( r * Math.cos(a), r * Math.sin(a) );
			}
			recording.graphics.lineTo( fr * Math.cos(fa), fr * Math.sin(fa) );
		}
	}
	
}