diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/common/views/IOSVideoView.as b/clients/flash/air-client/src/org/bigbluebutton/air/common/views/IOSVideoView.as index 4054d71ce0..ba9f0e96c9 100755 --- a/clients/flash/air-client/src/org/bigbluebutton/air/common/views/IOSVideoView.as +++ b/clients/flash/air-client/src/org/bigbluebutton/air/common/views/IOSVideoView.as @@ -1,116 +1,121 @@ -package org.bigbluebutton.air.common.views { - import mx.formatters.DateFormatter; - - import spark.components.Image; - - import org.bigbluebutton.BBBRtmpPlayer; - import org.bigbluebutton.BBBRtmpPlayerEvent; - - public class IOSVideoView extends VideoBaseView { - - protected var player:BBBRtmpPlayer; - protected var dateFormat:DateFormatter = new DateFormatter("Y-MM-DD J:NN:SS:QQ"); - - private function get image():Image { - return videoComp as Image; - } - - public function startStream(uri:String, streamName:String, imgWidth:Number, imgHeight:Number, meetingId:String, authToken:String, externalUserId:String):void { - - if (player) { - close(); - } - - videoComp = new Image(); - if (numChildren == 0) { - addChild(videoComp); - } - - this.originalVideoWidth = imgWidth; - this.originalVideoHeight = imgHeight; - - var url:String = uri + "/" + streamName + " live=1 conn=S:" + meetingId + " conn=S:" + externalUserId + " conn=S:" + authToken; - - player = new BBBRtmpPlayer(url); - - player.addEventListener(BBBRtmpPlayerEvent.CONNECTED, onConnected); - player.addEventListener(BBBRtmpPlayerEvent.CONNECTING, onConnecting); - player.addEventListener(BBBRtmpPlayerEvent.CONNECTION_FAILED, onConnectionFailed); - player.addEventListener(BBBRtmpPlayerEvent.DISCONNECTED, onDisconnected); - - player.play(); - } - - private function onConnected(e:BBBRtmpPlayerEvent):void { - trace(dateFormat.format(new Date()) + " EVENT: " + e.type + " MESSAGE: " + e.getMessage()); - image.source = player.getBmpData(); - } - - private function onConnecting(e:BBBRtmpPlayerEvent):void { - trace(dateFormat.format(new Date()) + " EVENT: " + e.type + " MESSAGE: " + e.getMessage()); - } - - private function onConnectionFailed(e:BBBRtmpPlayerEvent):void { - close(); - } - - private function onDisconnected(e:BBBRtmpPlayerEvent):void { - close(); - } - - public function close():void { - if (player) { - player.removeEventListener(BBBRtmpPlayerEvent.CONNECTED, onConnected); - player.removeEventListener(BBBRtmpPlayerEvent.CONNECTING, onConnecting); - player.removeEventListener(BBBRtmpPlayerEvent.CONNECTION_FAILED, onConnectionFailed); - player.removeEventListener(BBBRtmpPlayerEvent.DISCONNECTED, onDisconnected); - } - if (numChildren > 0 && getChildAt(0) == image) { - removeChild(image); - } - videoComp = null; - player = null; - } - - override protected function updateDisplayList(w:Number, h:Number):void { - super.updateDisplayList(w, h); - - if (player) { - resizeForPortrait(); - } - } - - public function rotateVideo(rotation:Number):void { - if (image && stage.contains(image)) { - removeChild(image); - } - videoComp = new Image(); - switch (rotation) { - case 0: - resizeForPortrait(); - image.x = width / 2 - image.width / 2; - image.y = height / 2 - image.height / 2; // + topMenuBarHeight; - break; - case -90: - resizeForLandscape(); - image.x = (width / 2) - (image.height / 2); - image.y = (height / 2) + (image.width / 2); // + topMenuBarHeight; - break; - case 90: - resizeForLandscape(); - image.x = (width / 2) + (image.height / 2); - image.y = (height / 2) - (image.width / 2); // + topMenuBarHeight; - break; - case 180: - resizeForPortrait(); - image.x = width / 2 + image.width / 2; - image.y = (height / 2) + (image.height / 2); // + topMenuBarHeight - break; - default: - break; - } - image.rotation = rotation; - addChild(image); - } - } -} +package org.bigbluebutton.air.common.views { + import mx.formatters.DateFormatter; + + import spark.components.Image; + + import org.bigbluebutton.BBBRtmpPlayer; + import org.bigbluebutton.BBBRtmpPlayerEvent; + import org.bigbluebutton.air.util.ConnUtil; + + public class IOSVideoView extends VideoBaseView { + + protected var player:BBBRtmpPlayer; + protected var dateFormat:DateFormatter = new DateFormatter("Y-MM-DD J:NN:SS:QQ"); + + private var _connectionId : String; + + private function get image():Image { + return videoComp as Image; + } + + public function startStream(uri:String, streamName:String, imgWidth:Number, imgHeight:Number, meetingId:String, authToken:String, externalUserId:String):void { + + if (player) { + close(); + } + + videoComp = new Image(); + if (numChildren == 0) { + addChild(videoComp); + } + + this.originalVideoWidth = imgWidth; + this.originalVideoHeight = imgHeight; + + _connectionId = ConnUtil.generateConnId(); + + var url:String = uri + "/" + streamName + " live=1 conn=S:" + meetingId + " conn=S:" + externalUserId + " conn=S:" + authToken + " conn=S:" + _connectionId; + + player = new BBBRtmpPlayer(url); + + player.addEventListener(BBBRtmpPlayerEvent.CONNECTED, onConnected); + player.addEventListener(BBBRtmpPlayerEvent.CONNECTING, onConnecting); + player.addEventListener(BBBRtmpPlayerEvent.CONNECTION_FAILED, onConnectionFailed); + player.addEventListener(BBBRtmpPlayerEvent.DISCONNECTED, onDisconnected); + + player.play(); + } + + private function onConnected(e:BBBRtmpPlayerEvent):void { + trace(dateFormat.format(new Date()) + " EVENT: " + e.type + " MESSAGE: " + e.getMessage()); + image.source = player.getBmpData(); + } + + private function onConnecting(e:BBBRtmpPlayerEvent):void { + trace(dateFormat.format(new Date()) + " EVENT: " + e.type + " MESSAGE: " + e.getMessage()); + } + + private function onConnectionFailed(e:BBBRtmpPlayerEvent):void { + close(); + } + + private function onDisconnected(e:BBBRtmpPlayerEvent):void { + close(); + } + + public function close():void { + if (player) { + player.removeEventListener(BBBRtmpPlayerEvent.CONNECTED, onConnected); + player.removeEventListener(BBBRtmpPlayerEvent.CONNECTING, onConnecting); + player.removeEventListener(BBBRtmpPlayerEvent.CONNECTION_FAILED, onConnectionFailed); + player.removeEventListener(BBBRtmpPlayerEvent.DISCONNECTED, onDisconnected); + } + if (numChildren > 0 && getChildAt(0) == image) { + removeChild(image); + } + videoComp = null; + player = null; + } + + override protected function updateDisplayList(w:Number, h:Number):void { + super.updateDisplayList(w, h); + + if (player) { + resizeForPortrait(); + } + } + + public function rotateVideo(rotation:Number):void { + if (image && stage.contains(image)) { + removeChild(image); + } + videoComp = new Image(); + switch (rotation) { + case 0: + resizeForPortrait(); + image.x = width / 2 - image.width / 2; + image.y = height / 2 - image.height / 2; // + topMenuBarHeight; + break; + case -90: + resizeForLandscape(); + image.x = (width / 2) - (image.height / 2); + image.y = (height / 2) + (image.width / 2); // + topMenuBarHeight; + break; + case 90: + resizeForLandscape(); + image.x = (width / 2) + (image.height / 2); + image.y = (height / 2) - (image.width / 2); // + topMenuBarHeight; + break; + case 180: + resizeForPortrait(); + image.x = width / 2 + image.width / 2; + image.y = (height / 2) + (image.height / 2); // + topMenuBarHeight + break; + default: + break; + } + image.rotation = rotation; + addChild(image); + } + } +} diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/main/services/BigBlueButtonConnection.as b/clients/flash/air-client/src/org/bigbluebutton/air/main/services/BigBlueButtonConnection.as index 795ebabb88..e2f0009888 100755 --- a/clients/flash/air-client/src/org/bigbluebutton/air/main/services/BigBlueButtonConnection.as +++ b/clients/flash/air-client/src/org/bigbluebutton/air/main/services/BigBlueButtonConnection.as @@ -1,107 +1,110 @@ -package org.bigbluebutton.air.main.services { - - import flash.net.NetConnection; - import flash.net.Responder; - import mx.utils.ObjectUtil; - import org.bigbluebutton.air.common.services.DefaultConnectionCallback; - import org.bigbluebutton.air.common.services.IBaseConnection; - import org.bigbluebutton.air.main.models.IConferenceParameters; - import org.osflash.signals.ISignal; - import org.osflash.signals.Signal; - - public class BigBlueButtonConnection extends DefaultConnectionCallback implements IBigBlueButtonConnection { - public static const NAME:String = "BigBlueButtonConnection"; - - protected var _connectionSuccessSignal:ISignal = new Signal(); - - protected var _connectionFailureSignal:ISignal = new Signal(); - - [Inject] - public var baseConnection:IBaseConnection; - - private var _applicationURI:String; - - private var _conferenceParameters:IConferenceParameters; - - private var _tried_tunneling:Boolean = false; - - [PostConstruct] - public function init():void { - baseConnection.init(this); - baseConnection.connectionSuccessSignal.add(onConnectionSuccess); - baseConnection.connectionFailureSignal.add(onConnectionFailure); - } - - private function onConnectionFailure(reason:String):void { - connectionFailureSignal.dispatch(reason); - } - - private function onConnectionSuccess():void { - connectionSuccessSignal.dispatch(); - } - - public function get connectionFailureSignal():ISignal { - return _connectionFailureSignal; - } - - public function get connectionSuccessSignal():ISignal { - return _connectionSuccessSignal; - } - - public function set uri(uri:String):void { - _applicationURI = uri; - } - - public function get uri():String { - return _applicationURI; - } - - public function get connection():NetConnection { - return baseConnection.connection; - } - - /** - * Connect to the server. - * uri: The uri to the conference application. - * username: Fullname of the participant. - * role: MODERATOR/VIEWER - * conference: The conference room - * mode: LIVE/PLAYBACK - Live:when used to collaborate, Playback:when being used to playback a recorded conference. - * room: Need the room number when playing back a recorded conference. When LIVE, the room is taken from the URI. - */ - public function connect(params:IConferenceParameters, tunnel:Boolean = false):void { - _conferenceParameters = params; - _tried_tunneling = tunnel; - var uri:String = _applicationURI + "/" + _conferenceParameters.room; - - var username:String = _conferenceParameters.username; - var role:String = _conferenceParameters.role; - var intMeetingId:String = _conferenceParameters.room; - var voiceConf:String = _conferenceParameters.voicebridge; - var recorded:Boolean = _conferenceParameters.record; - var extUserId:String = _conferenceParameters.externUserID; - var intUserId:String = _conferenceParameters.internalUserID; - var muteOnStart:Boolean = _conferenceParameters.muteOnStart; - var guest:Boolean = _conferenceParameters.guest; - var authToken:String = _conferenceParameters.authToken; - - var connectParams:Array = [username, role, intMeetingId, voiceConf, recorded, extUserId, intUserId, muteOnStart, guest, authToken]; - - trace("BBB Apps connect: " + connectParams); - baseConnection.connect.apply(null, new Array(uri).concat(connectParams)); - } - - public function disconnect(onUserCommand:Boolean):void { - baseConnection.disconnect(onUserCommand); - } - - /**** NEED TO REMOVE THIS BEFORE CONVERSION IS FINISHED ******/ - public function sendMessage(service:String, onSuccess:Function, onFailure:Function, message:Object = null):void { - //baseConnection.sendMessage(service, onSuccess, onFailure, message); - } - - public function sendMessage2x(onSuccess:Function, onFailure:Function, message:Object):void { - baseConnection.sendMessage2x(onSuccess, onFailure, message); - } - } -} +package org.bigbluebutton.air.main.services { + + import flash.net.NetConnection; + + import org.bigbluebutton.air.common.services.DefaultConnectionCallback; + import org.bigbluebutton.air.common.services.IBaseConnection; + import org.bigbluebutton.air.main.models.IConferenceParameters; + import org.bigbluebutton.air.util.ConnUtil; + import org.osflash.signals.ISignal; + import org.osflash.signals.Signal; + + public class BigBlueButtonConnection extends DefaultConnectionCallback implements IBigBlueButtonConnection { + public static const NAME:String = "BigBlueButtonConnection"; + + protected var _connectionSuccessSignal:ISignal = new Signal(); + + protected var _connectionFailureSignal:ISignal = new Signal(); + + [Inject] + public var baseConnection:IBaseConnection; + + private var _applicationURI:String; + + private var _conferenceParameters:IConferenceParameters; + + private var _connectionId : String; + + private var _tried_tunneling:Boolean = false; + + [PostConstruct] + public function init():void { + baseConnection.init(this); + baseConnection.connectionSuccessSignal.add(onConnectionSuccess); + baseConnection.connectionFailureSignal.add(onConnectionFailure); + } + + private function onConnectionFailure(reason:String):void { + connectionFailureSignal.dispatch(reason); + } + + private function onConnectionSuccess():void { + connectionSuccessSignal.dispatch(); + } + + public function get connectionFailureSignal():ISignal { + return _connectionFailureSignal; + } + + public function get connectionSuccessSignal():ISignal { + return _connectionSuccessSignal; + } + + public function set uri(uri:String):void { + _applicationURI = uri; + } + + public function get uri():String { + return _applicationURI; + } + + public function get connection():NetConnection { + return baseConnection.connection; + } + + /** + * Connect to the server. + * uri: The uri to the conference application. + * username: Fullname of the participant. + * role: MODERATOR/VIEWER + * conference: The conference room + * mode: LIVE/PLAYBACK - Live:when used to collaborate, Playback:when being used to playback a recorded conference. + * room: Need the room number when playing back a recorded conference. When LIVE, the room is taken from the URI. + */ + public function connect(params:IConferenceParameters, tunnel:Boolean = false):void { + _conferenceParameters = params; + _tried_tunneling = tunnel; + _connectionId = ConnUtil.generateConnId(); + var uri:String = _applicationURI + "/" + _conferenceParameters.room; + + var username:String = _conferenceParameters.username; + var role:String = _conferenceParameters.role; + var intMeetingId:String = _conferenceParameters.room; + var voiceConf:String = _conferenceParameters.voicebridge; + var recorded:Boolean = _conferenceParameters.record; + var extUserId:String = _conferenceParameters.externUserID; + var intUserId:String = _conferenceParameters.internalUserID; + var muteOnStart:Boolean = _conferenceParameters.muteOnStart; + var guest:Boolean = _conferenceParameters.guest; + var authToken:String = _conferenceParameters.authToken; + + var connectParams:Array = [username, role, intMeetingId, voiceConf, recorded, extUserId, intUserId, muteOnStart, guest, authToken, _connectionId]; + + trace("BBB Apps connect: " + connectParams); + baseConnection.connect.apply(null, new Array(uri).concat(connectParams)); + } + + public function disconnect(onUserCommand:Boolean):void { + baseConnection.disconnect(onUserCommand); + } + + /**** NEED TO REMOVE THIS BEFORE CONVERSION IS FINISHED ******/ + public function sendMessage(service:String, onSuccess:Function, onFailure:Function, message:Object = null):void { + //baseConnection.sendMessage(service, onSuccess, onFailure, message); + } + + public function sendMessage2x(onSuccess:Function, onFailure:Function, message:Object):void { + baseConnection.sendMessage2x(onSuccess, onFailure, message); + } + } +} diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/screenshare/views/IOSScreenshareView.as b/clients/flash/air-client/src/org/bigbluebutton/air/screenshare/views/IOSScreenshareView.as index 0897b15913..753c5a0c96 100755 --- a/clients/flash/air-client/src/org/bigbluebutton/air/screenshare/views/IOSScreenshareView.as +++ b/clients/flash/air-client/src/org/bigbluebutton/air/screenshare/views/IOSScreenshareView.as @@ -10,7 +10,8 @@ package org.bigbluebutton.air.screenshare.views { import spark.components.ProgressBar; import org.bigbluebutton.BBBRtmpPlayer; - import org.bigbluebutton.BBBRtmpPlayerEvent; + import org.bigbluebutton.BBBRtmpPlayerEvent; + import org.bigbluebutton.air.util.ConnUtil; // FIXME : Work in progress class, needs behave like Android screensahring display public class IOSScreenshareView extends UIComponent { @@ -26,6 +27,8 @@ package org.bigbluebutton.air.screenshare.views { private var _waitingTimer : Timer; + private var _connectionId : String; + private const WAITING_SECONDS : int = 15; protected var dateFormat:DateFormatter = new DateFormatter("Y-MM-DD J:NN:SS:QQ"); @@ -136,7 +139,9 @@ package org.bigbluebutton.air.screenshare.views { this.originalVideoWidth = imgWidth; this.originalVideoHeight = imgHeight; - var url:String = uri + "/" + streamName + " live=1 conn=S:" + meetingId + " conn=S:" + externalUserId + " conn=S:" + authToken; + _connectionId = ConnUtil.generateConnId(); + + var url:String = uri + "/" + streamName + " live=1 conn=S:" + meetingId + " conn=S:" + externalUserId + " conn=S:" + authToken + " conn=S:" + _connectionId; player = new BBBRtmpPlayer(url); diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/user/services/UsersMessageSender.as b/clients/flash/air-client/src/org/bigbluebutton/air/user/services/UsersMessageSender.as index 20f059643f..bb34b34c40 100755 --- a/clients/flash/air-client/src/org/bigbluebutton/air/user/services/UsersMessageSender.as +++ b/clients/flash/air-client/src/org/bigbluebutton/air/user/services/UsersMessageSender.as @@ -19,7 +19,7 @@ package org.bigbluebutton.air.user.services { public function joinMeeting():void { var message:Object = { header: {name: "UserJoinMeetingReqMsg", meetingId: conferenceParameters.meetingID, userId: conferenceParameters.internalUserID}, - body: {userId: conferenceParameters.internalUserID, authToken: conferenceParameters.authToken} + body: {userId: conferenceParameters.internalUserID, authToken: conferenceParameters.authToken, clientType: "FLASH"} }; userSession.mainConnection.sendMessage2x(defaultSuccessResponse, defaultFailureResponse, message); diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/util/ConnUtil.as b/clients/flash/air-client/src/org/bigbluebutton/air/util/ConnUtil.as index 125930a9af..ceeddfb9ed 100755 --- a/clients/flash/air-client/src/org/bigbluebutton/air/util/ConnUtil.as +++ b/clients/flash/air-client/src/org/bigbluebutton/air/util/ConnUtil.as @@ -14,5 +14,20 @@ package org.bigbluebutton.air.util var result:Array = pattern.exec(appURL); return result; } + + private static function generateRandomString(strlen:Number):String{ + var chars:String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + var num_chars:Number = chars.length - 1; + var randomChar:String = ""; + + for (var i:Number = 0; i < strlen; i++){ + randomChar += chars.charAt(Math.floor(Math.random() * num_chars)); + } + return randomChar; + } + + public static function generateConnId():String { + return generateRandomString(15); + } } } \ No newline at end of file diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/video/services/VideoConnection.as b/clients/flash/air-client/src/org/bigbluebutton/air/video/services/VideoConnection.as index b8b8dc714c..50cb850696 100755 --- a/clients/flash/air-client/src/org/bigbluebutton/air/video/services/VideoConnection.as +++ b/clients/flash/air-client/src/org/bigbluebutton/air/video/services/VideoConnection.as @@ -16,6 +16,7 @@ package org.bigbluebutton.air.video.services { import org.bigbluebutton.air.main.models.IUserSession; import org.bigbluebutton.air.main.models.LockSettings2x; import org.bigbluebutton.air.user.models.UserRole; + import org.bigbluebutton.air.util.ConnUtil; import org.bigbluebutton.air.video.commands.ShareCameraSignal; import org.bigbluebutton.air.video.commands.StopShareCameraSignal; import org.bigbluebutton.air.video.models.VideoProfile; @@ -64,6 +65,8 @@ package org.bigbluebutton.air.video.services { protected var _selectedCameraRotation:int; + private var _connectionId : String; + [PostConstruct] public function init():void { baseConnection.init(this); @@ -130,7 +133,8 @@ package org.bigbluebutton.air.video.services { public function connect():void { trace("Video connect"); - baseConnection.connect(uri, conferenceParameters.meetingID, userSession.userId, conferenceParameters.authToken); + _connectionId = ConnUtil.generateConnId(); + baseConnection.connect(uri, conferenceParameters.meetingID, userSession.userId, conferenceParameters.authToken, _connectionId); } public function disconnect(onUserCommand:Boolean):void { diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/voice/services/VoiceConnection.as b/clients/flash/air-client/src/org/bigbluebutton/air/voice/services/VoiceConnection.as index b6f4d5dae3..711842d5ce 100755 --- a/clients/flash/air-client/src/org/bigbluebutton/air/voice/services/VoiceConnection.as +++ b/clients/flash/air-client/src/org/bigbluebutton/air/voice/services/VoiceConnection.as @@ -13,11 +13,11 @@ package org.bigbluebutton.air.voice.services { import org.bigbluebutton.air.main.models.IUserSession; import org.bigbluebutton.air.main.models.LockSettings2x; import org.bigbluebutton.air.user.models.UserRole; + import org.bigbluebutton.air.util.ConnUtil; import org.bigbluebutton.air.voice.commands.MicrophoneMuteSignal; - import org.bigbluebutton.air.voice.commands.ShareMicrophoneSignal; import org.bigbluebutton.air.voice.models.VoiceUser; import org.osflash.signals.ISignal; - import org.osflash.signals.Signal; + import org.osflash.signals.Signal; public class VoiceConnection extends DefaultConnectionCallback implements IVoiceConnection { public const LOG:String = "VoiceConnection::"; @@ -50,6 +50,8 @@ package org.bigbluebutton.air.voice.services { protected var _conferenceParameters:IConferenceParameters; + private var _connectionId : String; + public function VoiceConnection() { } @@ -116,8 +118,9 @@ package org.bigbluebutton.air.voice.services { // we don't use scope in the voice communication (many hours lost on it) _conferenceParameters = confParams; _username = encodeURIComponent(confParams.internalUserID + "-bbbID-" + confParams.username); + _connectionId = ConnUtil.generateConnId(); trace("Voice app connect"); - baseConnection.connect(_applicationURI, confParams.meetingID, confParams.externUserID, _username, confParams.authToken); + baseConnection.connect(_applicationURI, confParams.meetingID, confParams.externUserID, _username, confParams.authToken, _connectionId); } public function disconnect(onUserCommand:Boolean):void {