VoiceChat
Union と Google TTS を使ったチャット
/**
* Copyright paq ( http://wonderfl.net/user/paq )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/p2KD
*/
package
{
import flash.display.Sprite;
import flash.events.Event;
/**
* Union と Google TTS を使ったチャット.
* @author paq89
*/
[SWF(width="465", height="465", backgroundColor="0xFFFFFF", frameRate="60")]
public class Main extends Sprite
{
// Constructor
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// wonderfl capture fix
graphics.beginFill(0xFFFFFF);
graphics.drawRect(0, 0, 465, 465);
var context:Context = new Context(this);
addChild(context.view);
}
}
}
import com.bit101.components.InputText;
import com.bit101.components.PushButton;
import com.bit101.components.Style;
import com.bit101.components.Text;
import com.bit101.components.Window;
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.Event;
import flash.events.FocusEvent;
import flash.events.KeyboardEvent;
import flash.media.Sound;
import flash.net.URLRequest;
import flash.net.URLVariables;
import flash.system.Capabilities;
import flash.ui.Keyboard;
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;
/**
* Context.
* @author paq89
*/
internal class Context extends Object
{
private var _container:DisplayObjectContainer;
public function get container():DisplayObjectContainer { return _container; }
private var _stage:Stage;
public function get stage():Stage { return _stage; }
private var _model:Model;
public function get model():Model { return _model; }
private var _view:View;
public function get view():View { return _view; }
private var _controller:Controller;
public function get controller():Controller { return _controller; }
public function Context(container:DisplayObjectContainer)
{
_container = container;
_stage = container.stage;
_model = new Model();
_view = new View();
_controller = new Controller();
_view.setup(this);
_controller.setup(this);
_model.setup(this);
}
}
/**
* Model.
* @author paq89
*/
internal class Model extends Object
{
public static const LANGUAGES:Vector.<String> = Vector.<String>([
"en", "ja", "Beatbox", "es", "de", "is", "af", "ar", "sq", "hy",
"it", "id", "cy", "nl", "ca", "el", "ht", "hr", "sv", "es",
"sk", "sw", "sr", "cs", "da", "tr", "no", "hu", "hi", "fi",
"fr", "vi", "pl", "pt", "mk", "la", "lv", "ro", "ru", "ko",
"zh-CN", "zh-TW"]);
private var _context:Context;
private var _view:View;
private var _language:int;
private var _request:URLRequest;
private var _variable:URLVariables;
private var _reactor:Reactor;
private var _room:Room;
//-------------------------------------------------
public function Model()
{
}
public function setup(context:Context):void
{
_context = context;
_view = context.view;
_language = 0;
setLanguage(Capabilities.language);
_request = new URLRequest("http://wonder-tools.appspot.com/api/tts");
_variable = new URLVariables();
_request.data = _variable;
_reactor = new Reactor();
_reactor.addEventListener(ReactorEvent.READY, onReady);
_reactor.connect("tryunion.com", 80);
}
public function setLanguage(lang:String):void
{
for (var i:int = 0, len:int = LANGUAGES.length; i < len; i++)
{
if (LANGUAGES[i] == lang)
{
_language = i;
_view.window.title = ("Language (" + lang + ")");
}
}
}
public function getLanguageByNumber(n:int):String
{
return LANGUAGES[n];
}
public function sendMessage(message:String):void
{
_room.sendMessage("CHAT_MESSAGE", true, null, Utils.zeroPadding(_language, 2) + message);
}
private function onReady(e:ReactorEvent):void
{
var name:String = _context.container.root.loaderInfo.parameters["viewer.displayName"];
if (!name) name = "Guest";
_reactor.self().setAttribute("USERNAME", name);
_room = _reactor.getRoomManager().createRoom("wonderfl_paq_voice_chat");
_room.addEventListener(RoomEvent.ADD_OCCUPANT, onAddOccupant)
_room.addEventListener(RoomEvent.REMOVE_OCCUPANT, onRemoveOccupant);
_room.addMessageListener("CHAT_MESSAGE", onChatMessage);
_room.join();
}
private function onAddOccupant(e:RoomEvent):void
{
_view.displayMessage(e.getClient().getAttribute("USERNAME") + " joined the chat.");
}
private function onRemoveOccupant(e:RoomEvent):void
{
_view.displayMessage(e.getClient().getAttribute("USERNAME") + " left the chat.");
}
private function onChatMessage(client:IClient, message:String):void
{
_view.speak(message);
_view.displayMessage(client.getAttribute("USERNAME") + ":(" + LANGUAGES[int(message.slice(0, 2))] + ") " + message.slice(2));
}
}
/**
* View.
* @author paq89
*/
internal class View extends Sprite
{
private var _context:Context;
private var _controller:Controller;
private var _inputText:InputText;
public function get inputText():InputText { return _inputText; }
private var _outputText:Text;
private var _window:Window;
public function get window():Window { return _window; }
private var _variable:URLVariables;
private var _request:URLRequest;
private var _sound:Sound;
private var _tempStyle:Object;
//-------------------------------------------------
public function View()
{
}
public function setup(context:Context):void
{
_context = context;
_controller = context.controller;
_request = new URLRequest("http://wonder-tools.appspot.com/api/tts");
_variable = new URLVariables();
_request.data = _variable;
createLanguageWindow();
createInput();
createOutput();
}
public function displayMessage(text:String):void
{
_outputText.text = text + "\n" + _outputText.text;
}
public function setTitle(title:String):void
{
_window.title = title;
}
private function createInput():void
{
styleSave();
Style.embedFonts = false;
Style.fontSize = 12;
Style.fontName = "_sans";
_inputText = new InputText(this, 0, 465 - 20, "");
_inputText.width = 465 - 100;
_inputText.height = 20;
styleLoad();
new PushButton(this, 465 - 100, 465 - 20, "SEND", _controller.send);
_inputText.addEventListener(FocusEvent.FOCUS_IN, _controller.focusIn);
_inputText.addEventListener(FocusEvent.FOCUS_OUT, _controller.focusOut)
}
private function createOutput():void
{
styleSave();
Style.embedFonts = false;
Style.fontSize = 12;
Style.fontName = "_sans";
_outputText = new Text(null, 0, 0);
_outputText.width = 465;
_outputText.height = 465 - 20;
addChildAt(_outputText, 0)
styleLoad();
}
private function createLanguageWindow():void
{
_window = new Window(this, 465 - 100, 0, "Language Select");
_window.setSize(100, 440);
_window.minimized = true;
_window.shadow = false;
_window.draggable = false;
//title = "Language (" + _selectedLanguage + ")";
_window.hasMinimizeButton = true;
var len:int = Model.LANGUAGES.length;
var x:int = 0;
var y:int = 0;
for (var i:int = 0; i < len; i++ )
{
var button:PushButton = new PushButton(_window.content, x * 50, y * 20, Model.LANGUAGES[i], _controller.languageButtonClick);
button.width = 50;
x++;
if (x > 1) {
y++;
x = 0;
}
}
}
public function speak(text:String):void
{
_sound = new Sound();
_sound.addEventListener(Event.COMPLETE, onComplete);
var lang:String = _context.model.getLanguageByNumber(int(text.slice(0, 2)));
_variable.q = text.slice(2);
_variable.tl = lang;
_variable.format = null;
if (lang == "Beatbox")
{
_variable.tl = "de";
_variable.format = "bb";
}
_sound.load(_request);
}
private function onComplete(e:Event):void
{
_sound.play();
}
private function styleSave():void
{
_tempStyle = {
"BACKGROUND": Style.BACKGROUND,
"BUTTON_FACE": Style.BUTTON_FACE,
"DROPSHADOW": Style.DROPSHADOW,
"embedFonts": Style.embedFonts,
"fontName": Style.fontName,
"fontSize": Style.fontSize,
"INPUT_TEXT": Style.INPUT_TEXT,
"LABEL_TEXT": Style.LABEL_TEXT,
"PANEL": Style.PANEL,
"PROGRESS_BAR" : Style.PROGRESS_BAR
}
}
private function styleLoad():void
{
Style.BACKGROUND = _tempStyle.BACKGROUND;
Style.BUTTON_FACE = _tempStyle.BUTTON_FACE;
Style.DROPSHADOW = _tempStyle.DROPSHADOW;
Style.embedFonts = _tempStyle.embedFonts;
Style.fontName = _tempStyle.fontName;
Style.fontSize = _tempStyle.fontSize;
Style.INPUT_TEXT = _tempStyle.INPUT_TEXT;
Style.LABEL_TEXT = _tempStyle.LABEL_TEXT;
Style.PANEL = _tempStyle.PANEL;
Style.PROGRESS_BAR = _tempStyle.PROGRESS_BAR;
}
}
/**
* Controller.
* @author paq89
*/
internal class Controller extends Object
{
private var _context:Context;
private var _model:Model;
private var _view:View;
private var _tempKey:int;
//-------------------------------------------------
public function Controller()
{
}
public function setup(context:Context):void
{
_context = context;
_model = context.model;
_view = context.view;
}
public function focusIn(e:FocusEvent):void
{
e.target.addEventListener(KeyboardEvent.KEY_DOWN, keyDown);
e.target.addEventListener(KeyboardEvent.KEY_UP, keyUp);
}
public function focusOut(e:FocusEvent):void
{
e.target.removeEventListener(KeyboardEvent.KEY_DOWN, keyDown);
e.target.removeEventListener(KeyboardEvent.KEY_UP, keyUp);
}
public function keyDown(e:KeyboardEvent):void
{
_tempKey = e.charCode;
}
public function keyUp(e:KeyboardEvent):void
{
if (e.charCode == Keyboard.ENTER && e.charCode == _tempKey) {
send();
}
}
public function send(e:Event = null):void
{
if (_context.view.inputText.text == "") return;
_context.model.sendMessage(_context.view.inputText.text);
_context.view.inputText.text = "";
}
public function languageButtonClick(e:Event):void
{
_model.setLanguage(e.target.label);
_view.window.minimized = true;
}
}
internal class Utils extends Object
{
public static function zeroPadding(n:Number, size:int):String
{
var str:String = n.toString(10);
while (str.length < size)
{
str = "0" + str;
}
return str;
}
}