freeswitch/clients/flex/freeswitch.mxml

509 lines
15 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()"
preinitialize="presetup()"
width="250" height="150"
xmlns:local="*">
<mx:Script>
<![CDATA[
import flash.external.*;
import flash.net.NetConnection;
import flash.net.NetStream;
import mx.utils.ObjectUtil;
import mx.core.FlexGlobals;
import flash.system.Security;
import flash.system.SecurityPanel;
import flash.media.*;
import com.adobe.crypto.MD5;
import com.adobe.serialization.json.JSON;
[Bindable]
public var netConnection:NetConnection = null;
private var incomingNetStream:NetStream = null;
private var outgoingNetStream:NetStream = null;
private var mic:Microphone = null;
[Bindable] private var microphoneList:Array;
private var sessionid:String;
private var auth_user:String;
private var auth_domain:String;
private var mic_index:int = -1;
private var attachedUUID:String = "";
[Embed(source="Sound_of_phone_ringing2.mp3")]
[Bindable]
private var soundOfPhoneRinging_MP3:Class;
private var ringChannel:SoundChannel = null;
private var ringUUID:String = "";
private var soundOfPhoneRinging:Sound;
public function presetup():void
{
/* Load config here */
soundOfPhoneRinging = new soundOfPhoneRinging_MP3();
}
/********* JavaScript functions *********/
public function makeCall(number:String, account:String, evt:Object):void {
if (netConnection != null) {
if (incomingNetStream == null) {
setupStreams();
}
netConnection.call("makeCall", null, number, account, evt);
}
}
public function sendDTMF(digits:String, duration:int):void {
if (netConnection != null) {
netConnection.call("sendDTMF", null, digits, duration);
}
}
public function answer(uuid:String):void {
if (ringChannel != null) {
ringChannel.stop();
ringChannel = null;
}
if (incomingNetStream == null) {
setupStreams();
}
if (netConnection != null) {
netConnection.call("answer", null, uuid);
}
}
public function hangup(uuid:String):void {
if (uuid == attachedUUID) {
destroyStreams();
}
if (netConnection != null) {
netConnection.call("hangup", null, uuid);
}
}
public function register(account:String, nickname:String):void {
if (netConnection != null) {
netConnection.call("register", null, account, nickname);
}
}
public function unregister(account:String, nickname:String):void {
if (netConnection != null) {
netConnection.call("unregister", null, account, nickname);
}
}
public function attach(uuid:String):void {
if (netConnection != null) {
netConnection.call("attach", null, uuid);
}
}
public function transfer(uuid:String, number:String):void {
if (netConnection != null) {
netConnection.call("transfer", null, uuid, number);
}
}
public function three_way(uuid1:String, uuid2:String):void {
if (netConnection != null) {
netConnection.call("three_way", null, uuid1, uuid2);
}
}
public function join(uuid1:String, uuid2:String):void {
if (netConnection != null) {
netConnection.call("join", null, uuid1, uuid2);
}
}
public function sendevent(data:Object):void {
if (netConnection != null) {
netConnection.call("sendevent", null, data);
}
}
public function getMic():int {
return mic_index;
}
public function micList():Object {
return JSON.encode(microphoneList);
}
public function setMic(index:int):void {
mic_index = index;
setupMic();
}
public function isMuted():Boolean {
if (mic != null) {
return mic.muted;
} else {
return false;
}
}
public function showPrivacy():void {
Security.showSettings(SecurityPanel.PRIVACY);
}
public function login(username:String, password:String):void {
if (netConnection != null) {
netConnection.call("login", null, username, MD5.hash(sessionid + ":" + username + ":" + password));
}
}
public function logout(account:String):void {
if (netConnection != null) {
netConnection.call("logout", null, account);
}
}
public function setVolume(value:Number):void {
if (incomingNetStream != null) {
var st:SoundTransform = new SoundTransform(value);
incomingNetStream.soundTransform = st;
}
}
public function setMicVolume(value:Number):void {
if (outgoingNetStream != null) {
var st:SoundTransform = new SoundTransform(value);
outgoingNetStream.soundTransform = st;
}
}
/********* FreeSWITCH functions *********/
/* XXX: TODO: Move those in a separate object so a malicious server can't setup streams and spy on the user */
public function connected(sid:String):void{
sessionid = sid;
if (ExternalInterface.available) {
ExternalInterface.call("onConnected", sid);
}
}
public function onHangup(uuid:String, cause:String):void {
if (ringUUID == uuid && ringChannel != null) {
ringChannel.stop();
ringChannel = null;
}
if (ExternalInterface.available) {
ExternalInterface.call("onHangup", uuid, cause);
}
}
public function onLogin(result:String, user:String, domain:String):void {
if (result == "success") {
auth_user = user;
auth_domain = domain;
}
if (ExternalInterface.available) {
ExternalInterface.call("onLogin", result, user, domain);
}
}
public function onLogout(user:String, domain:String):void {
if (ExternalInterface.available) {
ExternalInterface.call("onLogout", user, domain);
}
}
public function onAttach(uuid:String):void {
attachedUUID = uuid;
if (ringChannel != null && uuid != "") {
ringChannel.stop();
ringChannel = null;
}
if (attachedUUID == "") {
destroyStreams();
} else if (incomingNetStream == null || outgoingNetStream == null) {
setupStreams();
}
if (ExternalInterface.available) {
ExternalInterface.call("onAttach", uuid);
}
}
public function onMakeCall(uuid:String, number:String, account:String):void {
if (ExternalInterface.available) {
ExternalInterface.call("onMakeCall", uuid, number, account);
}
}
public function callState(uuid:String, state:String):void {
if (ExternalInterface.available) {
ExternalInterface.call("onCallState", uuid, state);
}
}
public function displayUpdate(uuid:String, name:String, number:String):void {
if (ExternalInterface.available) {
ExternalInterface.call("onDisplayUpdate", uuid, name, number);
}
}
public function incomingCall(uuid:String, name:String, number:String, account:String, evt:Object):void {
if (attachedUUID == "" && ringChannel == null) {
ringUUID = uuid;
ringChannel = soundOfPhoneRinging.play(0, 3);
}
if (evt != null) {
if (evt.hasOwnProperty("rtmp_auto_answer")) {
if (evt.rtmp_auto_answer == "true") {
answer(uuid);
}
}
}
if (ExternalInterface.available) {
ExternalInterface.call("onIncomingCall", uuid, name, number, account, evt);
}
}
public function event(event:Object):void {
if (ExternalInterface.available) {
ExternalInterface.call("onEvent", JSON.encode(event));
}
}
/********* Internal functions *********/
private function onDebug(message:String):void {
//statusTxt.text = (statusTxt.text != "") ? statusTxt.text + "\n" + message : message;
if (ExternalInterface.available) {
ExternalInterface.call("onDebug", message);
}
}
private function init():void
{
NetConnection.defaultObjectEncoding = ObjectEncoding.AMF0;
try {
Security.allowDomain("*");
} catch(e:Error) {
onDebug("Exception: " + e.toString());
}
if (ExternalInterface.available) {
try {
ExternalInterface.marshallExceptions = true;
ExternalInterface.addCallback("login", this.login);
ExternalInterface.addCallback("logout", this.logout);
ExternalInterface.addCallback("makeCall", this.makeCall);
ExternalInterface.addCallback("attach", this.attach);
ExternalInterface.addCallback("answer", this.answer);
ExternalInterface.addCallback("hangup", this.hangup);
ExternalInterface.addCallback("sendDTMF", this.sendDTMF);
ExternalInterface.addCallback("register", this.register);
ExternalInterface.addCallback("unregister", this.unregister);
ExternalInterface.addCallback("transfer", this.transfer);
ExternalInterface.addCallback("three_way", this.three_way);
ExternalInterface.addCallback("getMic", this.getMic);
ExternalInterface.addCallback("micList", this.micList);
ExternalInterface.addCallback("setMic", this.setMic);
ExternalInterface.addCallback("isMuted", this.isMuted);
ExternalInterface.addCallback("showPrivacy", this.showPrivacy);
ExternalInterface.addCallback("connect", this.connect);
ExternalInterface.addCallback("disconnect", this.disconnect);
ExternalInterface.addCallback("join", this.join);
ExternalInterface.addCallback("sendevent", this.sendevent);
ExternalInterface.addCallback("setVolume", this.setVolume);
ExternalInterface.addCallback("setMicVolume", this.setMicVolume);
//txtStatus.text = "Connecting...";
} catch(e:Error) {
//txtStatus.text = e.toString();
onDebug("Exception: " + e.toString());
}
} else {
onDebug("ExternalInterface is disabled");
}
try {
microphoneList = Microphone.names;
setupMic();
connect();
} catch(e:Error) {
onDebug("Exception: " + e.toString());
}
if (ExternalInterface.available) {
ExternalInterface.call("onInit");
}
}
public function connect():void{
if (netConnection != null) {
disconnect();
}
netConnection = new NetConnection();
netConnection.client = this;
netConnection.addEventListener( NetStatusEvent.NET_STATUS , netStatus );
netConnection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
netConnection.connect(FlexGlobals.topLevelApplication.parameters.rtmp_url);
}
public function disconnect():void {
if (netConnection != null) {
netConnection.close();
netConnection = null;
incomingNetStream = null;
outgoingNetStream = null;
}
}
private function destroyStreams():void {
if (outgoingNetStream != null) {
onDebug("Closing media streams")
outgoingNetStream.close();
outgoingNetStream = null;
}
if (incomingNetStream != null) {
incomingNetStream.close();
incomingNetStream = null;
}
}
private function setupMic():void {
try {
mic = Microphone.getMicrophone(mic_index);
mic.addEventListener(ActivityEvent.ACTIVITY, activityHandler);
mic.addEventListener(StatusEvent.STATUS, statusHandler);
mic.codec = SoundCodec.SPEEX;
mic.setUseEchoSuppression(true);
mic.setLoopBack(false);
mic.setSilenceLevel(0,20000);
mic.framesPerPacket = 1;
mic.gain = 55;
mic.rate = 16;
mic_index = mic.index;
if (outgoingNetStream != null) {
outgoingNetStream.close();
outgoingNetStream = new NetStream(netConnection);
outgoingNetStream.addEventListener(NetStatusEvent.NET_STATUS, netStatus);
outgoingNetStream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
outgoingNetStream.attachAudio(mic);
outgoingNetStream.publish("publish", "live");
}
} catch(e:Error) {
onDebug("Couldn't setup microphone: " + e.message);
}
}
private function setupStreams():void {
onDebug("Setup media streams");
if (mic == null || mic.index != mic_index) {
setupMic();
}
incomingNetStream = new NetStream(netConnection);
incomingNetStream.addEventListener(NetStatusEvent.NET_STATUS, netStatus);
incomingNetStream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
incomingNetStream.client = this;
incomingNetStream.bufferTime = 0.2;
incomingNetStream.play("play");
incomingNetStream.receiveAudio(true);
outgoingNetStream = new NetStream(netConnection);
outgoingNetStream.addEventListener(NetStatusEvent.NET_STATUS, netStatus);
outgoingNetStream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
outgoingNetStream.attachAudio(mic);
outgoingNetStream.publish("publish", "live");
}
private function onDisconnected():void {
if (ExternalInterface.available) {
ExternalInterface.call("onDisconnected");
}
}
private function securityErrorHandler(event:SecurityErrorEvent):void {
onDebug("securityErrorHandler: " + event.text);
}
private function asyncErrorHandler(event:AsyncErrorEvent):void {
onDebug("asyncErrorHandler: " + event.text);
}
private function activityHandler(event:ActivityEvent):void {
onDebug("activityHandler: " + event);
}
private function statusHandler(event:StatusEvent):void {
onDebug("statusHandler: " + event);
}
private function netStatus (evt:NetStatusEvent ):void {
onDebug("netStatus: " + evt.info.code);
switch(evt.info.code) {
case "NetConnection.Connect.Success":
//txtStatus.text = "Connected";
break;
case "NetConnection.Connect.Failed":
netConnection = null;
incomingNetStream = null;
outgoingNetStream = null;
//btnCall.label = "Connect";
//txtStatus.text = "Failed";
onDisconnected();
break;
case "NetConnection.Connect.Closed":
netConnection = null;
incomingNetStream = null;
outgoingNetStream = null;
//btnCall.label = "Connect";
//txtStatus.text = "Disconnected";
onDisconnected();
break;
case "NetConnection.Connect.Rejected":
netConnection = null;
incomingNetStream = null;
outgoingNetStream = null;
//btnCall.label = "Connect";
//txtStatus.text = "Rejected";
onDisconnected();
break;
case "NetStream.Play.StreamNotFound":
break;
case "NetStream.Play.Failed":
break;
case "NetStream.Play.Start":
break;
case "NetStream.Play.Stop":
break;
case "NetStream.Buffer.Full":
break;
default:
}
}
]]>
</mx:Script>
<!--<mx:Panel id="reader" title="Test" width="500">
<mx:TextArea width="500" color="#FF0000" id="statusTxt"/>
</mx:Panel>-->
</mx:Application>