VoiceChat

by paq
Union と Google TTS を使ったチャット
♥41 | Line 332 | Modified 2011-01-06 23:10:13 | MIT License
play

ActionScript3 source code

/**
 * 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;
    }
}

Forked