first attempt to use an auto-reconnection handler, still not working properly
This commit is contained in:
parent
423ffdeffa
commit
867e9b9b36
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
*
|
||||
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package org.bigbluebutton.main.model.users
|
||||
{
|
||||
import flash.events.TimerEvent;
|
||||
import flash.utils.Timer;
|
||||
|
||||
public class AutoReconnect
|
||||
{
|
||||
public static const LOG:String = "AutoReconnect - ";
|
||||
|
||||
private var _backoff:Number = 2000;
|
||||
private var _reconnectCallback:Function;
|
||||
private var _reconnectParameters:Array;
|
||||
|
||||
public function onDisconnect(callback:Function, ...parameters):void {
|
||||
trace(LOG + "onDisconnect, parameters=" + parameters.toString());
|
||||
_reconnectCallback = callback;
|
||||
_reconnectParameters = parameters;
|
||||
attemptReconnect(1000);
|
||||
}
|
||||
|
||||
public function onConnectionAttemptFailed():void {
|
||||
trace(LOG + "onConnectionAttemptFailed");
|
||||
attemptReconnect(_backoff);
|
||||
}
|
||||
|
||||
private function attemptReconnect(backoff:Number):void{
|
||||
trace(LOG + "attemptReconnect backoff=" + backoff);
|
||||
var retryTimer:Timer = new Timer(backoff, 1);
|
||||
retryTimer.addEventListener(TimerEvent.TIMER, function():void {
|
||||
trace(LOG + "Reconnecting");
|
||||
_reconnectCallback.apply(null, _reconnectParameters);
|
||||
});
|
||||
retryTimer.start();
|
||||
if (_backoff < 16000) _backoff = backoff *2;
|
||||
}
|
||||
}
|
||||
}
|
@ -30,10 +30,11 @@ package org.bigbluebutton.main.model.users
|
||||
import org.bigbluebutton.core.UsersUtil;
|
||||
import org.bigbluebutton.core.services.BandwidthMonitor;
|
||||
import org.bigbluebutton.main.api.JSLog;
|
||||
import org.bigbluebutton.main.events.ClientStatusEvent;
|
||||
import org.bigbluebutton.main.events.InvalidAuthTokenEvent;
|
||||
import org.bigbluebutton.main.model.ConferenceParameters;
|
||||
import org.bigbluebutton.main.model.users.events.ConnectionFailedEvent;
|
||||
import org.bigbluebutton.main.model.users.events.UsersConnectionEvent;
|
||||
import org.bigbluebutton.main.model.users.events.UsersConnectionEvent;
|
||||
|
||||
public class NetConnectionDelegate
|
||||
{
|
||||
@ -60,6 +61,8 @@ package org.bigbluebutton.main.model.users
|
||||
private var _messageListeners:Array = new Array();
|
||||
|
||||
private var authenticated: Boolean = false;
|
||||
private var reconnect:AutoReconnect = new AutoReconnect();
|
||||
private var reconnecting:Boolean = false;
|
||||
|
||||
public function NetConnectionDelegate():void
|
||||
{
|
||||
@ -158,6 +161,10 @@ package org.bigbluebutton.main.model.users
|
||||
trace(LOG + "*** handleValidateAuthTokenTimedOut. valid=[ " + tokenValid + "] **** \n");
|
||||
dispatcher.dispatchEvent(new InvalidAuthTokenEvent());
|
||||
}
|
||||
if (reconnecting) {
|
||||
onReconnect();
|
||||
reconnecting = false;
|
||||
}
|
||||
}
|
||||
|
||||
private function handleValidateAuthTokenReply(msg: Object):void {
|
||||
@ -173,7 +180,31 @@ package org.bigbluebutton.main.model.users
|
||||
trace(LOG + "*** handleValidateAuthTokenReply. valid=[ " + tokenValid + "] **** \n");
|
||||
dispatcher.dispatchEvent(new InvalidAuthTokenEvent());
|
||||
}
|
||||
if (reconnecting) {
|
||||
onReconnect();
|
||||
reconnecting = false;
|
||||
}
|
||||
}
|
||||
|
||||
private function onReconnect():void {
|
||||
if (authenticated) {
|
||||
onReconnectSuccess();
|
||||
} else {
|
||||
onReconnectFailed();
|
||||
}
|
||||
}
|
||||
|
||||
private function onReconnectSuccess():void {
|
||||
dispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.SUCCESS_MESSAGE_EVENT,
|
||||
"Connection reestablished",
|
||||
"Main connection has been reestablished successfully"));
|
||||
}
|
||||
|
||||
private function onReconnectFailed():void {
|
||||
dispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.FAIL_MESSAGE_EVENT,
|
||||
"Connection failed",
|
||||
"It was not possible to reestablish the main connection"));
|
||||
}
|
||||
|
||||
private function sendConnectionSuccessEvent(userid:String):void{
|
||||
var e:UsersConnectionEvent = new UsersConnectionEvent(UsersConnectionEvent.CONNECTION_SUCCESS);
|
||||
@ -367,8 +398,20 @@ package org.bigbluebutton.main.model.users
|
||||
logData.reason = reason;
|
||||
logData.user = UsersUtil.getUserData();
|
||||
JSLog.warn("User disconnected from BBB App.", logData);
|
||||
var e:ConnectionFailedEvent = new ConnectionFailedEvent(reason);
|
||||
dispatcher.dispatchEvent(e);
|
||||
|
||||
if (reconnecting) {
|
||||
reconnect.onConnectionAttemptFailed();
|
||||
} else {
|
||||
dispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.WARNING_MESSAGE_EVENT,
|
||||
"Main connection dropped",
|
||||
"Attempting to reconnect"));
|
||||
reconnecting = true;
|
||||
authenticated = false;
|
||||
reconnect.onDisconnect(connect, _conferenceParameters, tried_tunneling);
|
||||
}
|
||||
|
||||
//var e:ConnectionFailedEvent = new ConnectionFailedEvent(reason);
|
||||
//dispatcher.dispatchEvent(e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -377,15 +420,6 @@ package org.bigbluebutton.main.model.users
|
||||
dispatcher.dispatchEvent(e);
|
||||
}
|
||||
|
||||
private function attemptReconnect(backoff:Number):void{
|
||||
var retryTimer:Timer = new Timer(backoff, 1);
|
||||
retryTimer.addEventListener(TimerEvent.TIMER, function():void{
|
||||
connect(_conferenceParameters, tried_tunneling);
|
||||
});
|
||||
retryTimer.start();
|
||||
if (this.backoff < 16000) this.backoff = backoff *2;
|
||||
}
|
||||
|
||||
public function onBWCheck(... rest):Number {
|
||||
return 0;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ package org.bigbluebutton.modules.deskshare.services.red5
|
||||
{
|
||||
import com.asfusion.mate.events.Dispatcher;
|
||||
|
||||
import flash.events.AsyncErrorEvent;
|
||||
import flash.events.EventDispatcher;
|
||||
import flash.events.NetStatusEvent;
|
||||
import flash.events.SecurityErrorEvent;
|
||||
@ -32,13 +33,16 @@ package org.bigbluebutton.modules.deskshare.services.red5
|
||||
import flash.utils.Timer;
|
||||
|
||||
import mx.events.MetadataEvent;
|
||||
import mx.utils.ObjectUtil;
|
||||
|
||||
import org.bigbluebutton.common.LogUtil;
|
||||
import org.bigbluebutton.core.UsersUtil;
|
||||
import org.bigbluebutton.main.events.ClientStatusEvent;
|
||||
import org.bigbluebutton.main.model.users.AutoReconnect;
|
||||
import org.bigbluebutton.modules.deskshare.events.AppletStartedEvent;
|
||||
import org.bigbluebutton.modules.deskshare.events.CursorEvent;
|
||||
import org.bigbluebutton.modules.deskshare.events.ViewStreamEvent;
|
||||
|
||||
import org.bigbluebutton.modules.deskshare.events.ViewStreamEvent;
|
||||
|
||||
|
||||
public class Connection {
|
||||
public static const LOG:String = "Deskshare::Connection - ";
|
||||
@ -54,6 +58,9 @@ package org.bigbluebutton.modules.deskshare.services.red5
|
||||
private var width:Number;
|
||||
private var height:Number;
|
||||
private var room:String;
|
||||
private var reconnect:AutoReconnect = new AutoReconnect();
|
||||
private var logoutOnUserCommand:Boolean = false;
|
||||
private var reconnecting:Boolean = false;
|
||||
|
||||
private var dispatcher:Dispatcher = new Dispatcher();
|
||||
|
||||
@ -92,6 +99,8 @@ package org.bigbluebutton.modules.deskshare.services.red5
|
||||
nc.objectEncoding = ObjectEncoding.AMF0;
|
||||
nc.client = this;
|
||||
|
||||
nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, debugAsyncErrorHandler);
|
||||
nc.addEventListener(NetStatusEvent.NET_STATUS, debugNetStatusHandler);
|
||||
nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
|
||||
nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
|
||||
|
||||
@ -113,11 +122,11 @@ package org.bigbluebutton.modules.deskshare.services.red5
|
||||
|
||||
nc.connect(getURI(), UsersUtil.getInternalMeetingID());
|
||||
|
||||
if (!retry) {
|
||||
retryTimer = new Timer(connectionTimeout, 1);
|
||||
retryTimer.addEventListener(TimerEvent.TIMER_COMPLETE, connectTimeoutHandler);
|
||||
retryTimer.start();
|
||||
}
|
||||
//if (!retry) {
|
||||
// retryTimer = new Timer(connectionTimeout, 1);
|
||||
// retryTimer.addEventListener(TimerEvent.TIMER_COMPLETE, connectTimeoutHandler);
|
||||
// retryTimer.start();
|
||||
//}
|
||||
}
|
||||
|
||||
private function connectTimeoutHandler(e:TimerEvent):void {
|
||||
@ -182,6 +191,9 @@ package org.bigbluebutton.modules.deskshare.services.red5
|
||||
|
||||
switch(event.info.code){
|
||||
case "NetConnection.Connect.Failed":
|
||||
if (reconnecting) {
|
||||
reconnect.onConnectionAttemptFailed();
|
||||
}
|
||||
ce.status = ConnectionEvent.FAILED;
|
||||
|
||||
dispatcher.dispatchEvent(ce);
|
||||
@ -189,6 +201,12 @@ package org.bigbluebutton.modules.deskshare.services.red5
|
||||
|
||||
case "NetConnection.Connect.Success":
|
||||
ce.status = ConnectionEvent.SUCCESS;
|
||||
if (reconnecting) {
|
||||
dispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.SUCCESS_MESSAGE_EVENT,
|
||||
"Connection reestablished",
|
||||
"Deskshare connection has been reestablished successfully"));
|
||||
reconnecting = false;
|
||||
}
|
||||
dispatcher.dispatchEvent(ce);
|
||||
connectionSuccessHandler();
|
||||
break;
|
||||
@ -201,7 +219,14 @@ package org.bigbluebutton.modules.deskshare.services.red5
|
||||
case "NetConnection.Connect.Closed":
|
||||
trace(LOG + "Deskshare connection closed.");
|
||||
ce.status = ConnectionEvent.CLOSED;
|
||||
// dispatcher.dispatchEvent(ce);
|
||||
stopViewing();
|
||||
if (!logoutOnUserCommand) {
|
||||
dispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.WARNING_MESSAGE_EVENT,
|
||||
"Deskshare connection dropped",
|
||||
"Attempting to reconnect"));
|
||||
reconnecting = true;
|
||||
reconnect.onDisconnect(connect);
|
||||
}
|
||||
break;
|
||||
|
||||
case "NetConnection.Connect.InvalidApp":
|
||||
@ -256,6 +281,7 @@ package org.bigbluebutton.modules.deskshare.services.red5
|
||||
}
|
||||
|
||||
public function disconnect():void{
|
||||
logoutOnUserCommand = true;
|
||||
if (nc != null) nc.close();
|
||||
}
|
||||
|
||||
@ -264,10 +290,20 @@ package org.bigbluebutton.modules.deskshare.services.red5
|
||||
var deskSOName:String = room + "-deskSO";
|
||||
deskSO = SharedObject.getRemote(deskSOName, uri, false);
|
||||
deskSO.client = this;
|
||||
deskSO.addEventListener(AsyncErrorEvent.ASYNC_ERROR, debugAsyncErrorHandler);
|
||||
deskSO.addEventListener(NetStatusEvent.NET_STATUS, debugNetStatusHandler);
|
||||
deskSO.connect(nc);
|
||||
|
||||
checkIfStreamIsPublishing(room);
|
||||
}
|
||||
|
||||
private function debugNetStatusHandler(e:NetStatusEvent):void {
|
||||
trace(LOG + "netStatusHandler target=" + e.target + " info=" + ObjectUtil.toString(e.info));
|
||||
}
|
||||
|
||||
private function debugAsyncErrorHandler(e:AsyncErrorEvent):void {
|
||||
trace(LOG + "asyncErrorHandler target=" + e.target + " text=" + e.text);
|
||||
}
|
||||
|
||||
public function getConnection():NetConnection{
|
||||
return nc;
|
||||
|
@ -41,6 +41,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
import flash.sampler.NewObjectSample;
|
||||
import flexlib.mdi.events.MDIWindowEvent;
|
||||
import mx.core.UIComponent;
|
||||
import mx.utils.ObjectUtil;
|
||||
import org.bigbluebutton.common.Images;
|
||||
import org.bigbluebutton.common.LogUtil;
|
||||
import org.bigbluebutton.core.managers.UserManager;
|
||||
@ -72,6 +73,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
private static const VIDEO_WIDTH_PADDING:int = 7;
|
||||
private static const VIDEO_HEIGHT_PADDING:int = 65;
|
||||
|
||||
public static const LOG:String = "Deskshare::DesktopViewWindow - ";
|
||||
|
||||
// The following code block is to deal with a bug in FLexLib
|
||||
// with MDI windows not responding well to being maximized
|
||||
private var savedWindowWidth:Number;
|
||||
@ -178,10 +181,13 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
}
|
||||
|
||||
private function onAsyncError(e:AsyncErrorEvent):void{
|
||||
trace(LOG + "onAsyncError " + e.toString());
|
||||
LogUtil.debug("VIdeoWindow::asyncerror " + e.toString());
|
||||
}
|
||||
|
||||
private function onNetStatus(e:NetStatusEvent):void{
|
||||
trace(LOG + "onNetStatus info=" + e.info.text);
|
||||
|
||||
switch(e.info.code){
|
||||
case "NetStream.Play.Start":
|
||||
LogUtil.debug("NetStream.Publish.Start for broadcast stream " + stream);
|
||||
|
@ -1,199 +1,238 @@
|
||||
/**
|
||||
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
*
|
||||
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package org.bigbluebutton.modules.videoconf.business
|
||||
{
|
||||
import com.asfusion.mate.events.Dispatcher;
|
||||
|
||||
import flash.events.AsyncErrorEvent;
|
||||
import flash.events.IOErrorEvent;
|
||||
import flash.events.NetStatusEvent;
|
||||
import flash.events.SecurityErrorEvent;
|
||||
import flash.media.H264Level;
|
||||
import flash.media.H264Profile;
|
||||
import flash.media.H264VideoStreamSettings;
|
||||
import flash.net.NetConnection;
|
||||
import flash.net.NetStream;
|
||||
import flash.system.Capabilities;
|
||||
|
||||
import mx.collections.ArrayCollection;
|
||||
|
||||
import org.bigbluebutton.common.LogUtil;
|
||||
import org.bigbluebutton.core.BBB;
|
||||
import org.bigbluebutton.core.UsersUtil;
|
||||
import org.bigbluebutton.core.managers.UserManager;
|
||||
import org.bigbluebutton.main.model.users.BBBUser;
|
||||
import org.bigbluebutton.main.model.users.events.StreamStartedEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.ConnectedEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.StartBroadcastEvent;
|
||||
import org.bigbluebutton.modules.videoconf.model.VideoConfOptions;
|
||||
|
||||
|
||||
public class VideoProxy
|
||||
{
|
||||
public var videoOptions:VideoConfOptions;
|
||||
|
||||
private var nc:NetConnection;
|
||||
private var ns:NetStream;
|
||||
private var _url:String;
|
||||
|
||||
private function parseOptions():void {
|
||||
videoOptions = new VideoConfOptions();
|
||||
videoOptions.parseOptions();
|
||||
}
|
||||
|
||||
public function VideoProxy(url:String)
|
||||
{
|
||||
_url = url;
|
||||
parseOptions();
|
||||
nc = new NetConnection();
|
||||
/**
|
||||
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
*
|
||||
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package org.bigbluebutton.modules.videoconf.business
|
||||
{
|
||||
import com.asfusion.mate.events.Dispatcher;
|
||||
|
||||
import flash.events.AsyncErrorEvent;
|
||||
import flash.events.IOErrorEvent;
|
||||
import flash.events.NetStatusEvent;
|
||||
import flash.events.SecurityErrorEvent;
|
||||
import flash.events.TimerEvent;
|
||||
import flash.media.H264Level;
|
||||
import flash.media.H264Profile;
|
||||
import flash.media.H264VideoStreamSettings;
|
||||
import flash.net.NetConnection;
|
||||
import flash.net.NetStream;
|
||||
import flash.system.Capabilities;
|
||||
import flash.utils.Timer;
|
||||
|
||||
import mx.collections.ArrayCollection;
|
||||
|
||||
import org.bigbluebutton.common.LogUtil;
|
||||
import org.bigbluebutton.core.BBB;
|
||||
import org.bigbluebutton.core.UsersUtil;
|
||||
import org.bigbluebutton.core.managers.UserManager;
|
||||
import org.bigbluebutton.main.events.ClientStatusEvent;
|
||||
import org.bigbluebutton.main.model.users.AutoReconnect;
|
||||
import org.bigbluebutton.main.model.users.BBBUser;
|
||||
|
||||
import org.bigbluebutton.main.model.users.events.StreamStartedEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.ConnectedEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.StartBroadcastEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.StopBroadcastEvent;
|
||||
import org.bigbluebutton.modules.videoconf.model.VideoConfOptions;
|
||||
|
||||
|
||||
public class VideoProxy
|
||||
{
|
||||
public static const LOG:String = "VideoProxy - ";
|
||||
|
||||
public var videoOptions:VideoConfOptions;
|
||||
|
||||
private var nc:NetConnection;
|
||||
private var ns:NetStream;
|
||||
private var _url:String;
|
||||
private var logoutOnUserCommand:Boolean = false;
|
||||
private var reconnect:AutoReconnect = new AutoReconnect();
|
||||
private var reconnecting:Boolean = false;
|
||||
private var dispatcher:Dispatcher = new Dispatcher();
|
||||
|
||||
private function parseOptions():void {
|
||||
videoOptions = new VideoConfOptions();
|
||||
videoOptions.parseOptions();
|
||||
}
|
||||
|
||||
public function VideoProxy(url:String)
|
||||
{
|
||||
_url = url;
|
||||
parseOptions();
|
||||
nc = new NetConnection();
|
||||
nc.proxyType = "best";
|
||||
nc.client = this;
|
||||
nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, onAsyncError);
|
||||
nc.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
|
||||
nc.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
|
||||
nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
|
||||
|
||||
}
|
||||
|
||||
public function connect():void {
|
||||
nc.connect(_url, UsersUtil.getInternalMeetingID(), UsersUtil.getMyUserID());
|
||||
}
|
||||
|
||||
private function onAsyncError(event:AsyncErrorEvent):void{
|
||||
}
|
||||
|
||||
private function onIOError(event:NetStatusEvent):void{
|
||||
}
|
||||
|
||||
private function onConnectedToVideoApp():void{
|
||||
var dispatcher:Dispatcher = new Dispatcher();
|
||||
dispatcher.dispatchEvent(new ConnectedEvent(ConnectedEvent.VIDEO_CONNECTED));
|
||||
}
|
||||
|
||||
private function onNetStatus(event:NetStatusEvent):void{
|
||||
switch(event.info.code){
|
||||
case "NetConnection.Connect.Success":
|
||||
ns = new NetStream(nc);
|
||||
onConnectedToVideoApp();
|
||||
break;
|
||||
default:
|
||||
LogUtil.debug("[" + event.info.code + "] for [" + _url + "]");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function onSecurityError(event:NetStatusEvent):void{
|
||||
}
|
||||
|
||||
public function get connection():NetConnection{
|
||||
return this.nc;
|
||||
}
|
||||
|
||||
public function startPublishing(e:StartBroadcastEvent):void{
|
||||
ns.addEventListener( NetStatusEvent.NET_STATUS, onNetStatus );
|
||||
ns.addEventListener( IOErrorEvent.IO_ERROR, onIOError );
|
||||
ns.addEventListener( AsyncErrorEvent.ASYNC_ERROR, onAsyncError );
|
||||
ns.client = this;
|
||||
ns.attachCamera(e.camera);
|
||||
// Uncomment if you want to build support for H264. But you need at least FP 11. (ralam july 23, 2011)
|
||||
// if (Capabilities.version.search("11,0") != -1) {
|
||||
if ((BBB.getFlashPlayerVersion() >= 11) && videoOptions.enableH264) {
|
||||
// if (BBB.getFlashPlayerVersion() >= 11) {
|
||||
LogUtil.info("Using H264 codec for video.");
|
||||
var h264:H264VideoStreamSettings = new H264VideoStreamSettings();
|
||||
var h264profile:String = H264Profile.MAIN;
|
||||
if (videoOptions.h264Profile != "main") {
|
||||
h264profile = H264Profile.BASELINE;
|
||||
}
|
||||
var h264Level:String = H264Level.LEVEL_4_1;
|
||||
if (videoOptions.h264Level == "1") {
|
||||
h264Level = H264Level.LEVEL_1;
|
||||
} else if (videoOptions.h264Level == "1.1") {
|
||||
h264Level = H264Level.LEVEL_1_1;
|
||||
} else if (videoOptions.h264Level == "1.2") {
|
||||
h264Level = H264Level.LEVEL_1_2;
|
||||
} else if (videoOptions.h264Level == "1.3") {
|
||||
h264Level = H264Level.LEVEL_1_3;
|
||||
} else if (videoOptions.h264Level == "1b") {
|
||||
h264Level = H264Level.LEVEL_1B;
|
||||
} else if (videoOptions.h264Level == "2") {
|
||||
h264Level = H264Level.LEVEL_2;
|
||||
} else if (videoOptions.h264Level == "2.1") {
|
||||
h264Level = H264Level.LEVEL_2_1;
|
||||
} else if (videoOptions.h264Level == "2.2") {
|
||||
h264Level = H264Level.LEVEL_2_2;
|
||||
} else if (videoOptions.h264Level == "3") {
|
||||
h264Level = H264Level.LEVEL_3;
|
||||
} else if (videoOptions.h264Level == "3.1") {
|
||||
h264Level = H264Level.LEVEL_3_1;
|
||||
} else if (videoOptions.h264Level == "3.2") {
|
||||
h264Level = H264Level.LEVEL_3_2;
|
||||
} else if (videoOptions.h264Level == "4") {
|
||||
h264Level = H264Level.LEVEL_4;
|
||||
} else if (videoOptions.h264Level == "4.1") {
|
||||
h264Level = H264Level.LEVEL_4_1;
|
||||
} else if (videoOptions.h264Level == "4.2") {
|
||||
h264Level = H264Level.LEVEL_4_2;
|
||||
} else if (videoOptions.h264Level == "5") {
|
||||
h264Level = H264Level.LEVEL_5;
|
||||
} else if (videoOptions.h264Level == "5.1") {
|
||||
h264Level = H264Level.LEVEL_5_1;
|
||||
}
|
||||
|
||||
LogUtil.info("Codec used: " + h264Level);
|
||||
|
||||
h264.setProfileLevel(h264profile, h264Level);
|
||||
ns.videoStreamSettings = h264;
|
||||
}
|
||||
|
||||
ns.publish(e.stream);
|
||||
}
|
||||
|
||||
public function stopBroadcasting():void{
|
||||
trace("Closing netstream for webcam publishing");
|
||||
|
||||
if (ns != null) {
|
||||
ns.attachCamera(null);
|
||||
ns.close();
|
||||
ns = null;
|
||||
ns = new NetStream(nc);
|
||||
}
|
||||
}
|
||||
|
||||
public function disconnect():void {
|
||||
trace("VideoProxy:: disconnecting from Video application");
|
||||
stopBroadcasting();
|
||||
if (nc != null) nc.close();
|
||||
}
|
||||
|
||||
public function onBWCheck(... rest):Number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function onBWDone(... rest):void {
|
||||
var p_bw:Number;
|
||||
if (rest.length > 0) p_bw = rest[0];
|
||||
// your application should do something here
|
||||
// when the bandwidth check is complete
|
||||
trace("bandwidth = " + p_bw + " Kbps.");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
nc.client = this;
|
||||
nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, onAsyncError);
|
||||
nc.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
|
||||
nc.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
|
||||
nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
|
||||
|
||||
}
|
||||
|
||||
public function connect():void {
|
||||
nc.connect(_url, UsersUtil.getInternalMeetingID(), UsersUtil.getMyUserID());
|
||||
}
|
||||
|
||||
private function onAsyncError(event:AsyncErrorEvent):void{
|
||||
}
|
||||
|
||||
private function onIOError(event:NetStatusEvent):void{
|
||||
}
|
||||
|
||||
private function onConnectedToVideoApp():void{
|
||||
dispatcher.dispatchEvent(new ConnectedEvent(ConnectedEvent.VIDEO_CONNECTED));
|
||||
}
|
||||
|
||||
private function onNetStatus(event:NetStatusEvent):void{
|
||||
trace(LOG + "[" + event.info.code + "] for [" + _url + "]");
|
||||
switch(event.info.code){
|
||||
case "NetConnection.Connect.Success":
|
||||
if (reconnecting) {
|
||||
dispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.SUCCESS_MESSAGE_EVENT,
|
||||
"Connection reestablished",
|
||||
"Video connection has been reestablished successfully"));
|
||||
reconnecting = false;
|
||||
}
|
||||
ns = new NetStream(nc);
|
||||
onConnectedToVideoApp();
|
||||
break;
|
||||
|
||||
case "NetConnection.Connect.Closed":
|
||||
if (!logoutOnUserCommand) {
|
||||
if (ns != null) {
|
||||
ns.attachCamera(null);
|
||||
ns.close();
|
||||
ns = null;
|
||||
}
|
||||
dispatcher.dispatchEvent(new StopBroadcastEvent());
|
||||
|
||||
dispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.WARNING_MESSAGE_EVENT,
|
||||
"Video connection dropped",
|
||||
"Attempting to reconnect"));
|
||||
reconnecting = true;
|
||||
reconnect.onDisconnect(connect);
|
||||
}
|
||||
break;
|
||||
|
||||
case "NetConnection.Connect.Failed":
|
||||
if (reconnecting) {
|
||||
reconnect.onConnectionAttemptFailed();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function onSecurityError(event:NetStatusEvent):void{
|
||||
}
|
||||
|
||||
public function get connection():NetConnection{
|
||||
return this.nc;
|
||||
}
|
||||
|
||||
public function startPublishing(e:StartBroadcastEvent):void{
|
||||
ns.addEventListener( NetStatusEvent.NET_STATUS, onNetStatus );
|
||||
ns.addEventListener( IOErrorEvent.IO_ERROR, onIOError );
|
||||
ns.addEventListener( AsyncErrorEvent.ASYNC_ERROR, onAsyncError );
|
||||
ns.client = this;
|
||||
ns.attachCamera(e.camera);
|
||||
// Uncomment if you want to build support for H264. But you need at least FP 11. (ralam july 23, 2011)
|
||||
// if (Capabilities.version.search("11,0") != -1) {
|
||||
if ((BBB.getFlashPlayerVersion() >= 11) && videoOptions.enableH264) {
|
||||
// if (BBB.getFlashPlayerVersion() >= 11) {
|
||||
LogUtil.info("Using H264 codec for video.");
|
||||
var h264:H264VideoStreamSettings = new H264VideoStreamSettings();
|
||||
var h264profile:String = H264Profile.MAIN;
|
||||
if (videoOptions.h264Profile != "main") {
|
||||
h264profile = H264Profile.BASELINE;
|
||||
}
|
||||
var h264Level:String = H264Level.LEVEL_4_1;
|
||||
if (videoOptions.h264Level == "1") {
|
||||
h264Level = H264Level.LEVEL_1;
|
||||
} else if (videoOptions.h264Level == "1.1") {
|
||||
h264Level = H264Level.LEVEL_1_1;
|
||||
} else if (videoOptions.h264Level == "1.2") {
|
||||
h264Level = H264Level.LEVEL_1_2;
|
||||
} else if (videoOptions.h264Level == "1.3") {
|
||||
h264Level = H264Level.LEVEL_1_3;
|
||||
} else if (videoOptions.h264Level == "1b") {
|
||||
h264Level = H264Level.LEVEL_1B;
|
||||
} else if (videoOptions.h264Level == "2") {
|
||||
h264Level = H264Level.LEVEL_2;
|
||||
} else if (videoOptions.h264Level == "2.1") {
|
||||
h264Level = H264Level.LEVEL_2_1;
|
||||
} else if (videoOptions.h264Level == "2.2") {
|
||||
h264Level = H264Level.LEVEL_2_2;
|
||||
} else if (videoOptions.h264Level == "3") {
|
||||
h264Level = H264Level.LEVEL_3;
|
||||
} else if (videoOptions.h264Level == "3.1") {
|
||||
h264Level = H264Level.LEVEL_3_1;
|
||||
} else if (videoOptions.h264Level == "3.2") {
|
||||
h264Level = H264Level.LEVEL_3_2;
|
||||
} else if (videoOptions.h264Level == "4") {
|
||||
h264Level = H264Level.LEVEL_4;
|
||||
} else if (videoOptions.h264Level == "4.1") {
|
||||
h264Level = H264Level.LEVEL_4_1;
|
||||
} else if (videoOptions.h264Level == "4.2") {
|
||||
h264Level = H264Level.LEVEL_4_2;
|
||||
} else if (videoOptions.h264Level == "5") {
|
||||
h264Level = H264Level.LEVEL_5;
|
||||
} else if (videoOptions.h264Level == "5.1") {
|
||||
h264Level = H264Level.LEVEL_5_1;
|
||||
}
|
||||
|
||||
LogUtil.info("Codec used: " + h264Level);
|
||||
|
||||
h264.setProfileLevel(h264profile, h264Level);
|
||||
ns.videoStreamSettings = h264;
|
||||
}
|
||||
|
||||
ns.publish(e.stream);
|
||||
}
|
||||
|
||||
public function stopBroadcasting():void{
|
||||
trace("Closing netstream for webcam publishing");
|
||||
|
||||
if (ns != null) {
|
||||
ns.attachCamera(null);
|
||||
ns.close();
|
||||
ns = null;
|
||||
ns = new NetStream(nc);
|
||||
}
|
||||
}
|
||||
|
||||
public function disconnect():void {
|
||||
logoutOnUserCommand = true;
|
||||
trace("VideoProxy:: disconnecting from Video application");
|
||||
stopBroadcasting();
|
||||
if (nc != null) nc.close();
|
||||
}
|
||||
|
||||
public function onBWCheck(... rest):Number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function onBWDone(... rest):void {
|
||||
var p_bw:Number;
|
||||
if (rest.length > 0) p_bw = rest[0];
|
||||
// your application should do something here
|
||||
// when the bandwidth check is complete
|
||||
trace("bandwidth = " + p_bw + " Kbps.");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -297,6 +297,10 @@ package org.bigbluebutton.modules.videoconf.maps
|
||||
}
|
||||
|
||||
private function openViewWindowFor(userID:String):void {
|
||||
if (!proxy.connection.connected) {
|
||||
return;
|
||||
}
|
||||
|
||||
trace("VideoEventMapDelegate:: [" + me + "] openViewWindowFor:: Opening VIEW window for [" + userID + "] [" + UsersUtil.getUserName(userID) + "]");
|
||||
|
||||
var window:VideoWindow = new VideoWindow();
|
||||
@ -334,7 +338,7 @@ package org.bigbluebutton.modules.videoconf.maps
|
||||
}
|
||||
|
||||
public function startPublishing(e:StartBroadcastEvent):void{
|
||||
LogUtil.debug("VideoEventMapDelegate:: [" + me + "] startPublishing:: Publishing stream to: " + proxy.connection.uri + "/" + e.stream);
|
||||
trace("VideoEventMapDelegate:: [" + me + "] startPublishing:: Publishing stream to: " + proxy.connection.uri + "/" + e.stream);
|
||||
streamName = e.stream;
|
||||
proxy.startPublishing(e);
|
||||
|
||||
|
@ -1,278 +1,289 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
|
||||
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
|
||||
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Lesser General Public License as published by the Free Software
|
||||
Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
-->
|
||||
|
||||
<viewVid:VideoWindowItf
|
||||
xmlns:viewVid="org.bigbluebutton.modules.videoconf.business.*"
|
||||
xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
creationComplete="onCreationComplete()"
|
||||
implements="org.bigbluebutton.common.IBbbModuleWindow"
|
||||
xmlns:mate="http://mate.asfusion.com/"
|
||||
styleNameFocus="videoViewStyleFocus"
|
||||
styleNameNoFocus="videoViewStyleNoFocus"
|
||||
horizontalScrollPolicy="off"
|
||||
verticalScrollPolicy="off"
|
||||
resize="onResize()"
|
||||
layout="absolute">
|
||||
|
||||
<mate:Listener type="{BBBEvent.USER_VOICE_MUTED}" method="handleUserVoiceMutedEvent" />
|
||||
<mate:Listener type="{EventConstants.USER_TALKING}" method="handleUserTalkingEvent" />
|
||||
<mate:Listener type="{SwitchedPresenterEvent.SWITCHED_PRESENTER}" method="handleSwitchedPresenterEvent" />
|
||||
<mate:Listener type="{MadePresenterEvent.SWITCH_TO_PRESENTER_MODE}" method="handleMadePresenterEvent" />
|
||||
<mate:Listener type="{BBBEvent.USER_VOICE_JOINED}" method="handleNewRoleEvent" />
|
||||
<mate:Listener type="{BBBEvent.USER_VOICE_LEFT}" method="handleNewRoleEvent" />
|
||||
<mate:Listener type="{CloseAllWindowsEvent.CLOSE_ALL_WINDOWS}" method="closeWindow" />
|
||||
|
||||
<mx:Script>
|
||||
<![CDATA[
|
||||
import com.asfusion.mate.events.Dispatcher;
|
||||
|
||||
import flexlib.mdi.events.MDIWindowEvent;
|
||||
|
||||
import mx.core.UIComponent;
|
||||
|
||||
import org.bigbluebutton.common.LogUtil;
|
||||
import org.bigbluebutton.common.Role;
|
||||
import org.bigbluebutton.common.events.CloseWindowEvent;
|
||||
import org.bigbluebutton.core.EventConstants;
|
||||
import org.bigbluebutton.core.events.CoreEvent;
|
||||
import org.bigbluebutton.core.managers.UserManager;
|
||||
import org.bigbluebutton.main.events.BBBEvent;
|
||||
import org.bigbluebutton.main.events.MadePresenterEvent;
|
||||
import org.bigbluebutton.main.events.StoppedViewingWebcamEvent;
|
||||
import org.bigbluebutton.main.events.SwitchedPresenterEvent;
|
||||
import org.bigbluebutton.main.views.MainCanvas;
|
||||
import org.bigbluebutton.modules.videoconf.business.TalkingButtonOverlay;
|
||||
import org.bigbluebutton.modules.videoconf.events.CloseAllWindowsEvent;
|
||||
import org.bigbluebutton.modules.videoconf.model.VideoConfOptions;
|
||||
|
||||
private var ns:NetStream;
|
||||
private var globalDispatcher:Dispatcher;
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
|
||||
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
|
||||
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Lesser General Public License as published by the Free Software
|
||||
Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
-->
|
||||
|
||||
<viewVid:VideoWindowItf
|
||||
xmlns:viewVid="org.bigbluebutton.modules.videoconf.business.*"
|
||||
xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
creationComplete="onCreationComplete()"
|
||||
implements="org.bigbluebutton.common.IBbbModuleWindow"
|
||||
xmlns:mate="http://mate.asfusion.com/"
|
||||
styleNameFocus="videoViewStyleFocus"
|
||||
styleNameNoFocus="videoViewStyleNoFocus"
|
||||
horizontalScrollPolicy="off"
|
||||
verticalScrollPolicy="off"
|
||||
resize="onResize()"
|
||||
layout="absolute">
|
||||
|
||||
<mate:Listener type="{BBBEvent.USER_VOICE_MUTED}" method="handleUserVoiceMutedEvent" />
|
||||
<mate:Listener type="{EventConstants.USER_TALKING}" method="handleUserTalkingEvent" />
|
||||
<mate:Listener type="{SwitchedPresenterEvent.SWITCHED_PRESENTER}" method="handleSwitchedPresenterEvent" />
|
||||
<mate:Listener type="{MadePresenterEvent.SWITCH_TO_PRESENTER_MODE}" method="handleMadePresenterEvent" />
|
||||
<mate:Listener type="{BBBEvent.USER_VOICE_JOINED}" method="handleNewRoleEvent" />
|
||||
<mate:Listener type="{BBBEvent.USER_VOICE_LEFT}" method="handleNewRoleEvent" />
|
||||
<mate:Listener type="{CloseAllWindowsEvent.CLOSE_ALL_WINDOWS}" method="closeWindow" />
|
||||
|
||||
<mx:Script>
|
||||
<![CDATA[
|
||||
import com.asfusion.mate.events.Dispatcher;
|
||||
|
||||
import flexlib.mdi.events.MDIWindowEvent;
|
||||
|
||||
import mx.core.UIComponent;
|
||||
|
||||
import org.bigbluebutton.common.LogUtil;
|
||||
import org.bigbluebutton.common.Role;
|
||||
import org.bigbluebutton.common.events.CloseWindowEvent;
|
||||
import org.bigbluebutton.core.EventConstants;
|
||||
import org.bigbluebutton.core.events.CoreEvent;
|
||||
import org.bigbluebutton.core.managers.UserManager;
|
||||
import org.bigbluebutton.main.events.BBBEvent;
|
||||
import org.bigbluebutton.main.events.MadePresenterEvent;
|
||||
import org.bigbluebutton.main.events.StoppedViewingWebcamEvent;
|
||||
import org.bigbluebutton.main.events.SwitchedPresenterEvent;
|
||||
import org.bigbluebutton.main.views.MainCanvas;
|
||||
import org.bigbluebutton.modules.videoconf.business.TalkingButtonOverlay;
|
||||
import org.bigbluebutton.modules.videoconf.events.CloseAllWindowsEvent;
|
||||
import org.bigbluebutton.modules.videoconf.model.VideoConfOptions;
|
||||
|
||||
[Bindable]
|
||||
public var videoOptions:VideoConfOptions = new VideoConfOptions();
|
||||
|
||||
private var windowType:String = "VideoWindowType";
|
||||
|
||||
[Bindable] public var glowColor:String = "";
|
||||
[Bindable] public var glowBlurSize:Number = 0;
|
||||
|
||||
override public function getWindowType():String {
|
||||
return windowType;
|
||||
}
|
||||
public static const LOG:String = "VideoWindow - ";
|
||||
|
||||
private var ns:NetStream;
|
||||
private var globalDispatcher:Dispatcher;
|
||||
|
||||
private function onCreationComplete():void{
|
||||
this.glowColor = videoOptions.glowColor;
|
||||
this.glowBlurSize = videoOptions.glowBlurSize;
|
||||
|
||||
LogUtil.debug("checking glow values: "+this.glowColor+" and "+this.glowBlurSize);
|
||||
|
||||
_videoHolder = new UIComponent();
|
||||
_videoHolder.addChild(_video);
|
||||
this.addChild(_videoHolder);
|
||||
|
||||
addEventListener(MDIWindowEvent.RESIZE_START, onResizeStart);
|
||||
addEventListener(MDIWindowEvent.RESIZE_END, onResizeEnd);
|
||||
addEventListener(MDIWindowEvent.CLOSE, onCloseEvent);
|
||||
|
||||
addEventListener(MouseEvent.MOUSE_OVER, showButtons);
|
||||
addEventListener(MouseEvent.MOUSE_OUT, hideButtons);
|
||||
addEventListener(MouseEvent.DOUBLE_CLICK, onDoubleClick);
|
||||
|
||||
createButtons();
|
||||
addControlButtons();
|
||||
|
||||
globalDispatcher = new Dispatcher();
|
||||
|
||||
this.minWidth = _minWidth;
|
||||
this.minHeight = _minHeight;
|
||||
maximizeRestoreBtn.visible = false;
|
||||
this.resizable = true;
|
||||
|
||||
/**
|
||||
* At this point, the function startVideo has been called, and
|
||||
* the video has the exactly dimensions of the original stream.
|
||||
* It's needed to call onResize() to fit the video window in the
|
||||
* main canvas in case that the video dimensions are larger than
|
||||
* the parent window.
|
||||
*/
|
||||
onResize();
|
||||
|
||||
if (videoOptions.viewerWindowMaxed)
|
||||
this.maximize();
|
||||
|
||||
this.showCloseButton = videoOptions.showCloseButton;
|
||||
}
|
||||
|
||||
private function handleMadePresenterEvent(event:MadePresenterEvent):void {
|
||||
trace("******** VideoWindow: HandleMadePresenter event *********");
|
||||
updateControlButtons();
|
||||
}
|
||||
|
||||
private function handleSwitchedPresenterEvent(event:SwitchedPresenterEvent):void {
|
||||
trace("******** VideoWindow: handleSwitchedPresenterEvent event *********");
|
||||
updateControlButtons();
|
||||
}
|
||||
|
||||
private function handleNewRoleEvent(event:Event):void {
|
||||
updateControlButtons();
|
||||
}
|
||||
|
||||
private function handleUserVoiceMutedEvent(event:BBBEvent):void {
|
||||
if (event.payload.userID == userID) {
|
||||
userMuted(event.payload.muted);
|
||||
}
|
||||
}
|
||||
|
||||
private var _closing:Boolean = false;
|
||||
|
||||
private function onCloseEvent(event:MDIWindowEvent = null):void {
|
||||
LogUtil.debug("ViewWindow closing " + streamName);
|
||||
if (!_closing) {
|
||||
_closing = true;
|
||||
var stopEvent:StoppedViewingWebcamEvent = new StoppedViewingWebcamEvent();
|
||||
stopEvent.webcamUserID = userID;
|
||||
globalDispatcher.dispatchEvent(stopEvent);
|
||||
|
||||
if (UserManager.getInstance().getConference().hasUser(userID)) {
|
||||
UserManager.getInstance().getConference().getUser(userID).viewingStream = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function handleUserTalkingEvent(event:CoreEvent):void {
|
||||
if (event.message.userID == userID) {
|
||||
if (event.message.talking) {
|
||||
notTalkingEffect.end();
|
||||
talkingEffect.play([this]);
|
||||
simulateClick();
|
||||
} else {
|
||||
talkingEffect.end();
|
||||
notTalkingEffect.play([this]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function startVideo(connection:NetConnection, stream:String):void{
|
||||
ns = new NetStream(connection);
|
||||
ns.addEventListener( NetStatusEvent.NET_STATUS, onNetStatus );
|
||||
ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, onAsyncError);
|
||||
ns.client = this;
|
||||
ns.bufferTime = 0;
|
||||
ns.receiveVideo(true);
|
||||
ns.receiveAudio(false);
|
||||
|
||||
var res:Array = getVideoResolution(stream);
|
||||
if (res == null) // error
|
||||
return;
|
||||
_video = new Video(Number(res[0]), Number(res[1]));
|
||||
_video.width = Number(res[0]);
|
||||
_video.height = Number(res[1]);
|
||||
_video.smoothing = true;
|
||||
setAspectRatio(Number(res[0]), Number(res[1]));
|
||||
_video.attachNetStream(ns);
|
||||
|
||||
|
||||
if (videoOptions.smoothVideo) {
|
||||
trace("Smoothing video.")
|
||||
_video.smoothing = true;
|
||||
}
|
||||
|
||||
if (videoOptions.applyConvolutionFilter) {
|
||||
var filter:ConvolutionFilter = new flash.filters.ConvolutionFilter();
|
||||
filter.matrixX = 3;
|
||||
filter.matrixY = 3;
|
||||
trace("Applying convolution filter =[" + videoOptions.convolutionFilter + "]");
|
||||
filter.matrix = videoOptions.convolutionFilter;
|
||||
filter.bias = videoOptions.filterBias;
|
||||
filter.divisor = videoOptions.filterDivisor;
|
||||
_video.filters = [filter];
|
||||
}
|
||||
|
||||
ns.play(stream);
|
||||
this.streamName = stream;
|
||||
|
||||
this.width = _video.width + paddingHorizontal;
|
||||
this.height = _video.height + paddingVertical;
|
||||
|
||||
if (UserManager.getInstance().getConference().hasUser(userID)) {
|
||||
UserManager.getInstance().getConference().getUser(userID).viewingStream = true;
|
||||
}
|
||||
}
|
||||
|
||||
private function onAsyncError(e:AsyncErrorEvent):void{
|
||||
LogUtil.debug("VideoWindow::asyncerror " + e.toString());
|
||||
}
|
||||
|
||||
public function onMetaData(info:Object):void{
|
||||
trace("metadata: width=" + info.width + " height=" + info.height);
|
||||
_video.width = info.width;
|
||||
_video.height = info.height;
|
||||
setAspectRatio(info.width, info.height);
|
||||
onResize();
|
||||
}
|
||||
|
||||
private function onNetStatus(e:NetStatusEvent):void{
|
||||
switch(e.info.code){
|
||||
case "NetStream.Publish.Start":
|
||||
LogUtil.debug("NetStream.Publish.Start for broadcast stream " + streamName);
|
||||
break;
|
||||
case "NetStream.Play.UnpublishNotify":
|
||||
ns.close();
|
||||
this.close();
|
||||
// shouldn't call onCloseEvent() here because of the viewer cam icon
|
||||
super.close();
|
||||
break;
|
||||
case "NetStream.Play.Start":
|
||||
LogUtil.debug("Netstatus: " + e.info.code);
|
||||
globalDispatcher.dispatchEvent(new BBBEvent(BBBEvent.VIDEO_STARTED));
|
||||
break;
|
||||
case "NetStream.Play.FileStructureInvalid":
|
||||
LogUtil.debug("The MP4's file structure is invalid.");
|
||||
break;
|
||||
case "NetStream.Play.NoSupportedTrackFound":
|
||||
LogUtil.debug("The MP4 doesn't contain any supported tracks");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
override public function close(event:MouseEvent=null):void{
|
||||
ns.close();
|
||||
onCloseEvent();
|
||||
super.close(event);
|
||||
}
|
||||
|
||||
private function closeWindow(e:CloseAllWindowsEvent):void{
|
||||
this.close();
|
||||
}
|
||||
|
||||
]]>
|
||||
</mx:Script>
|
||||
|
||||
<mx:Glow id="talkingEffect" duration="500" alphaFrom="1.0" alphaTo="0.3"
|
||||
blurXFrom="0.0" blurXTo="{glowBlurSize}" blurYFrom="0.0" blurYTo="{glowBlurSize}" color="{glowColor}"/>
|
||||
<mx:Glow id="notTalkingEffect" duration="500" alphaFrom="0.3" alphaTo="1.0"
|
||||
blurXFrom="{glowBlurSize}" blurXTo="0.0" blurYFrom="{glowBlurSize}" blurYTo="0.0" color="{glowColor}"/>
|
||||
|
||||
|
||||
</viewVid:VideoWindowItf>
|
||||
[Bindable]
|
||||
public var videoOptions:VideoConfOptions = new VideoConfOptions();
|
||||
|
||||
private var windowType:String = "VideoWindowType";
|
||||
|
||||
[Bindable] public var glowColor:String = "";
|
||||
[Bindable] public var glowBlurSize:Number = 0;
|
||||
|
||||
override public function getWindowType():String {
|
||||
return windowType;
|
||||
}
|
||||
|
||||
private function onCreationComplete():void{
|
||||
this.glowColor = videoOptions.glowColor;
|
||||
this.glowBlurSize = videoOptions.glowBlurSize;
|
||||
|
||||
LogUtil.debug("checking glow values: "+this.glowColor+" and "+this.glowBlurSize);
|
||||
|
||||
_videoHolder = new UIComponent();
|
||||
_videoHolder.addChild(_video);
|
||||
this.addChild(_videoHolder);
|
||||
|
||||
addEventListener(MDIWindowEvent.RESIZE_START, onResizeStart);
|
||||
addEventListener(MDIWindowEvent.RESIZE_END, onResizeEnd);
|
||||
addEventListener(MDIWindowEvent.CLOSE, onCloseEvent);
|
||||
|
||||
addEventListener(MouseEvent.MOUSE_OVER, showButtons);
|
||||
addEventListener(MouseEvent.MOUSE_OUT, hideButtons);
|
||||
addEventListener(MouseEvent.DOUBLE_CLICK, onDoubleClick);
|
||||
|
||||
createButtons();
|
||||
addControlButtons();
|
||||
|
||||
globalDispatcher = new Dispatcher();
|
||||
|
||||
this.minWidth = _minWidth;
|
||||
this.minHeight = _minHeight;
|
||||
maximizeRestoreBtn.visible = false;
|
||||
this.resizable = true;
|
||||
|
||||
/**
|
||||
* At this point, the function startVideo has been called, and
|
||||
* the video has the exactly dimensions of the original stream.
|
||||
* It's needed to call onResize() to fit the video window in the
|
||||
* main canvas in case that the video dimensions are larger than
|
||||
* the parent window.
|
||||
*/
|
||||
onResize();
|
||||
|
||||
if (videoOptions.viewerWindowMaxed)
|
||||
this.maximize();
|
||||
|
||||
this.showCloseButton = videoOptions.showCloseButton;
|
||||
}
|
||||
|
||||
private function handleMadePresenterEvent(event:MadePresenterEvent):void {
|
||||
trace("******** VideoWindow: HandleMadePresenter event *********");
|
||||
updateControlButtons();
|
||||
}
|
||||
|
||||
private function handleSwitchedPresenterEvent(event:SwitchedPresenterEvent):void {
|
||||
trace("******** VideoWindow: handleSwitchedPresenterEvent event *********");
|
||||
updateControlButtons();
|
||||
}
|
||||
|
||||
private function handleNewRoleEvent(event:Event):void {
|
||||
updateControlButtons();
|
||||
}
|
||||
|
||||
private function handleUserVoiceMutedEvent(event:BBBEvent):void {
|
||||
if (event.payload.userID == userID) {
|
||||
userMuted(event.payload.muted);
|
||||
}
|
||||
}
|
||||
|
||||
private var _closing:Boolean = false;
|
||||
|
||||
private function onCloseEvent(event:MDIWindowEvent = null):void {
|
||||
LogUtil.debug("ViewWindow closing " + streamName);
|
||||
if (!_closing) {
|
||||
_closing = true;
|
||||
var stopEvent:StoppedViewingWebcamEvent = new StoppedViewingWebcamEvent();
|
||||
stopEvent.webcamUserID = userID;
|
||||
globalDispatcher.dispatchEvent(stopEvent);
|
||||
|
||||
if (UserManager.getInstance().getConference().hasUser(userID)) {
|
||||
UserManager.getInstance().getConference().getUser(userID).viewingStream = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function handleUserTalkingEvent(event:CoreEvent):void {
|
||||
if (event.message.userID == userID) {
|
||||
if (event.message.talking) {
|
||||
notTalkingEffect.end();
|
||||
talkingEffect.play([this]);
|
||||
simulateClick();
|
||||
} else {
|
||||
talkingEffect.end();
|
||||
notTalkingEffect.play([this]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function onConnectionNetStatus(e:NetStatusEvent):void {
|
||||
trace(LOG + "onNetStatus code=" + e.info.code);
|
||||
|
||||
if (e.info.code == "NetConnection.Connect.Closed") {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public function startVideo(connection:NetConnection, stream:String):void{
|
||||
connection.addEventListener(NetStatusEvent.NET_STATUS, onConnectionNetStatus);
|
||||
|
||||
ns = new NetStream(connection);
|
||||
ns.addEventListener( NetStatusEvent.NET_STATUS, onNetStatus );
|
||||
ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, onAsyncError);
|
||||
ns.client = this;
|
||||
ns.bufferTime = 0;
|
||||
ns.receiveVideo(true);
|
||||
ns.receiveAudio(false);
|
||||
|
||||
var res:Array = getVideoResolution(stream);
|
||||
if (res == null) // error
|
||||
return;
|
||||
_video = new Video(Number(res[0]), Number(res[1]));
|
||||
_video.width = Number(res[0]);
|
||||
_video.height = Number(res[1]);
|
||||
_video.smoothing = true;
|
||||
setAspectRatio(Number(res[0]), Number(res[1]));
|
||||
_video.attachNetStream(ns);
|
||||
|
||||
|
||||
if (videoOptions.smoothVideo) {
|
||||
trace("Smoothing video.")
|
||||
_video.smoothing = true;
|
||||
}
|
||||
|
||||
if (videoOptions.applyConvolutionFilter) {
|
||||
var filter:ConvolutionFilter = new flash.filters.ConvolutionFilter();
|
||||
filter.matrixX = 3;
|
||||
filter.matrixY = 3;
|
||||
trace("Applying convolution filter =[" + videoOptions.convolutionFilter + "]");
|
||||
filter.matrix = videoOptions.convolutionFilter;
|
||||
filter.bias = videoOptions.filterBias;
|
||||
filter.divisor = videoOptions.filterDivisor;
|
||||
_video.filters = [filter];
|
||||
}
|
||||
|
||||
ns.play(stream);
|
||||
this.streamName = stream;
|
||||
|
||||
this.width = _video.width + paddingHorizontal;
|
||||
this.height = _video.height + paddingVertical;
|
||||
|
||||
if (UserManager.getInstance().getConference().hasUser(userID)) {
|
||||
UserManager.getInstance().getConference().getUser(userID).viewingStream = true;
|
||||
}
|
||||
}
|
||||
|
||||
private function onAsyncError(e:AsyncErrorEvent):void{
|
||||
LogUtil.debug("VideoWindow::asyncerror " + e.toString());
|
||||
}
|
||||
|
||||
public function onMetaData(info:Object):void{
|
||||
trace("metadata: width=" + info.width + " height=" + info.height);
|
||||
_video.width = info.width;
|
||||
_video.height = info.height;
|
||||
setAspectRatio(info.width, info.height);
|
||||
onResize();
|
||||
}
|
||||
|
||||
private function onNetStatus(e:NetStatusEvent):void{
|
||||
switch(e.info.code){
|
||||
case "NetStream.Publish.Start":
|
||||
LogUtil.debug("NetStream.Publish.Start for broadcast stream " + streamName);
|
||||
break;
|
||||
case "NetStream.Play.UnpublishNotify":
|
||||
ns.close();
|
||||
this.close();
|
||||
// shouldn't call onCloseEvent() here because of the viewer cam icon
|
||||
super.close();
|
||||
break;
|
||||
case "NetStream.Play.Start":
|
||||
LogUtil.debug("Netstatus: " + e.info.code);
|
||||
globalDispatcher.dispatchEvent(new BBBEvent(BBBEvent.VIDEO_STARTED));
|
||||
break;
|
||||
case "NetStream.Play.FileStructureInvalid":
|
||||
LogUtil.debug("The MP4's file structure is invalid.");
|
||||
break;
|
||||
case "NetStream.Play.NoSupportedTrackFound":
|
||||
LogUtil.debug("The MP4 doesn't contain any supported tracks");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
override public function close(event:MouseEvent=null):void{
|
||||
ns.close();
|
||||
onCloseEvent();
|
||||
super.close(event);
|
||||
}
|
||||
|
||||
private function closeWindow(e:CloseAllWindowsEvent):void{
|
||||
this.close();
|
||||
}
|
||||
|
||||
]]>
|
||||
</mx:Script>
|
||||
|
||||
<mx:Glow id="talkingEffect" duration="500" alphaFrom="1.0" alphaTo="0.3"
|
||||
blurXFrom="0.0" blurXTo="{glowBlurSize}" blurYFrom="0.0" blurYTo="{glowBlurSize}" color="{glowColor}"/>
|
||||
<mx:Glow id="notTalkingEffect" duration="500" alphaFrom="0.3" alphaTo="1.0"
|
||||
blurXFrom="{glowBlurSize}" blurXTo="0.0" blurYFrom="{glowBlurSize}" blurYTo="0.0" color="{glowColor}"/>
|
||||
|
||||
|
||||
</viewVid:VideoWindowItf>
|
||||
|
Loading…
Reference in New Issue
Block a user