[OPENMEETINGS-551] basic video support is added

Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/838bfbe3
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/838bfbe3
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/838bfbe3

Branch: refs/heads/master
Commit: 838bfbe3b9987bd4c9cfadb39cb08a3b79fff66c
Parents: e227dd4
Author: Maxim Solodovnik <[email protected]>
Authored: Thu Apr 13 16:29:41 2017 +0000
Committer: Maxim Solodovnik <[email protected]>
Committed: Thu Apr 13 16:29:41 2017 +0000

----------------------------------------------------------------------
 .../remote/red5/ScopeApplicationAdapter.java    |   6 +-
 .../openmeetings/db/entity/basic/Client.java    |  64 +++++++++-
 openmeetings-flash/src/main/flex/main.mxml      | 122 ++++++++++++-------
 .../flex/org/apache/openmeetings/OmVideo.as     |  44 ++++---
 .../openmeetings/web/app/Application.java       |   2 +-
 .../openmeetings/web/common/MainPanel.java      |  56 +++++----
 .../apache/openmeetings/web/pages/HashPage.java |   5 +-
 .../apache/openmeetings/web/room/RoomPanel.html |   5 +
 .../apache/openmeetings/web/room/RoomPanel.java |  20 ++-
 .../openmeetings/web/room/VideoSettings.java    |   6 +-
 .../org/apache/openmeetings/web/room/room.js    |  94 ++++++++++++++
 .../apache/openmeetings/web/room/settings.js    |   7 +-
 .../web/room/sidebar/RoomSidebar.java           |  14 ++-
 .../web/util/ExtendedClientProperties.java      |  27 +++-
 openmeetings-web/src/main/webapp/css/room.css   |  19 ++-
 pom.xml                                         |   2 +-
 16 files changed, 373 insertions(+), 120 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
----------------------------------------------------------------------
diff --git 
a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
 
b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
index ab9d5ab..f0e5db7 100644
--- 
a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
+++ 
b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
@@ -201,6 +201,9 @@ public class ScopeApplicationAdapter extends 
MultiThreadedApplicationAdapter imp
                String tcUrl = map.containsKey("tcUrl") ? 
(String)map.get("tcUrl") : "";
                Map<String, Object> connParams = getConnParams(params);
                String uid = (String)connParams.get("uid");
+               if ("noclient".equals(uid)) {
+                       return true;
+               }
                String securityCode = 
(String)connParams.get(SECURITY_CODE_PARAM);
                String parentSid = (String)map.get("parentSid");
                if (parentSid == null) {
@@ -249,9 +252,6 @@ public class ScopeApplicationAdapter extends 
MultiThreadedApplicationAdapter imp
                        log.warn("No UIDs are provided, client is rejected");
                        return rejectClient();
                }
-               if ("networktest".equals(uid)) {
-                       return true;
-               }
 
                if (map.containsKey("screenClient")) {
                        Client parent = 
sessionManager.getClientByPublicSID(parentSid, null);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
----------------------------------------------------------------------
diff --git 
a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
 
b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
index 8ec7b27..0f8fc82 100644
--- 
a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
+++ 
b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
@@ -28,6 +28,10 @@ import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.wicket.protocol.ws.api.registry.IKey;
+import org.apache.wicket.util.string.Strings;
+
+import com.github.openjson.JSONArray;
+import com.github.openjson.JSONObject;
 
 /**
  * Temporary class, later will be merged with {@link 
org.apache.openmeetings.db.entity.room.Client}
@@ -65,6 +69,7 @@ public class Client implements IClient {
        private int mic = -1;
        private int width = 0;
        private int height = 0;
+       private long broadcastId = -1;
 
        public Client(String sessionId, int pageId, Long userId, UserDao dao) {
                this.sessionId = sessionId;
@@ -157,6 +162,16 @@ public class Client implements IClient {
                return activities;
        }
 
+       public boolean hasAnyActivity(Activity... aa) {
+               boolean res = false;
+               if (aa != null) {
+                       for (Activity a : aa) {
+                               res |= activities.contains(a);
+                       }
+               }
+               return res;
+       }
+
        public boolean hasActivity(Activity a) {
                return activities.contains(a);
        }
@@ -243,8 +258,9 @@ public class Client implements IClient {
                return cam;
        }
 
-       public void setCam(int cam) {
+       public Client setCam(int cam) {
                this.cam = cam;
+               return this;
        }
 
        public boolean isMicEnabled() {
@@ -255,32 +271,45 @@ public class Client implements IClient {
                return mic;
        }
 
-       public void setMic(int mic) {
+       public Client setMic(int mic) {
                this.mic = mic;
+               return this;
        }
 
        public int getWidth() {
                return width;
        }
 
-       public void setWidth(int width) {
+       public Client setWidth(int width) {
                this.width = width;
+               return this;
        }
 
        public int getHeight() {
                return height;
        }
 
-       public void setHeight(int height) {
+       public Client setHeight(int height) {
                this.height = height;
+               return this;
        }
 
        public String getRemoteAddress() {
                return remoteAddress;
        }
 
-       public void setRemoteAddress(String remoteAddress) {
+       public Client setRemoteAddress(String remoteAddress) {
                this.remoteAddress = remoteAddress;
+               return this;
+       }
+
+       public long getBroadcastId() {
+               return broadcastId;
+       }
+
+       public Client setBroadcastId(long broadcastId) {
+               this.broadcastId = broadcastId;
+               return this;
        }
 
        @Override
@@ -313,6 +342,31 @@ public class Client implements IClient {
                return true;
        }
 
+       public JSONObject toJson() {
+               JSONObject u = new JSONObject();
+               if (user != null) {
+                       JSONObject a = new JSONObject();
+                       u.put("firstName", user.getFirstname())
+                               .put("lastName", user.getLastname())
+                               .put("address", a);
+                       if (user.getAddress() != null) {
+                               if (Strings.isEmpty(user.getFirstname()) && 
Strings.isEmpty(user.getLastname())) {
+                                       a.put("email", 
user.getAddress().getEmail());
+                               }
+                               a.put("country", 
user.getAddress().getCountry());
+                       }
+               }
+               return new JSONObject()
+                               .put("user", u)
+                               .put("uid", uid)
+                               .put("rights", new JSONArray(rights))
+                               .put("activities", new JSONArray(activities))
+                               .put("pod", pod)
+                               .put("broadcastId", broadcastId)
+                               .put("width", width)
+                               .put("height", height);
+       }
+
        @Override
        public String toString() {
                return "Client [uid=" + uid + ", sessionId=" + sessionId + ", 
pageId=" + pageId + ", userId=" + user.getId() + ", roomId=" + roomId

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-flash/src/main/flex/main.mxml
----------------------------------------------------------------------
diff --git a/openmeetings-flash/src/main/flex/main.mxml 
b/openmeetings-flash/src/main/flex/main.mxml
index 1e3867b..d731972 100644
--- a/openmeetings-flash/src/main/flex/main.mxml
+++ b/openmeetings-flash/src/main/flex/main.mxml
@@ -60,46 +60,72 @@
                }
 
                private function appInit(evt:Event):void {
-                       var tla:Object = FlexGlobals.topLevelApplication;
-                       debug("appInit()", tla.parameters);
-                       audioOnly = 'true' == tla.parameters['audioOnly'];
-                       interview = 'true' == tla.parameters['interview'];
-                       var _fps:int = parseInt(tla.parameters['fps']);
+                       var params:Object = 
FlexGlobals.topLevelApplication.parameters;
+                       debug("appInit()", params);
+                       audioOnly = 'true' == params.audioOnly;
+                       interview = 'true' == params.interview;
+                       var _fps:int = parseInt(params.fps);
                        FPS = (isNaN(_fps) || _fps < 1 ? 30 : _fps);
-                       video = new OmVideo(videoDisplay, tla.parameters);
-
-                       ExternalInterface.addCallback("getDevices", function 
():Object {
-                               return {
-                                       cams: Camera.names
-                                       , mics: Microphone.names
-                               };
-                       });
-                       ExternalInterface.addCallback("camChanged", function 
(val:int):void {
-                               selectedCam = val;
-                               camChanged(null);
-                       });
-                       ExternalInterface.addCallback("micChanged", function 
(val:int):void {
-                               selectedMic = val;
-                               camChanged(null);
-                       });
-                       ExternalInterface.addCallback("resChanged", function 
(width:int, height:int):void {
-                               setResolution(width, height, true);
-                       });
-                       ExternalInterface.addCallback("close", function ():void 
{
-                               video.reset();
-                       });
-                       ExternalInterface.addCallback("init", function 
(camIdx:int, micIdx:int, width:int, height:int):void {
-                               selectedCam = camIdx;
-                               selectedMic = micIdx;
-                               setResolution(width, height, true);
-                       });
-                       ExternalInterface.addCallback("startRec", function 
():void {
-                               startTestRecording();
-                       });
-                       ExternalInterface.addCallback("play", function ():void {
-                               playTestRecording();
-                       });
-                       ExternalInterface.call("VideoSettings.initSwf");
+                       video = new OmVideo(videoDisplay, params);
+                       switch (params.mode) {
+                               case 'settings':
+                               {
+                                       
ExternalInterface.addCallback("getDevices", function ():Object {
+                                               return {
+                                                       cams: Camera.names
+                                                       , mics: Microphone.names
+                                               };
+                                       });
+                                       
ExternalInterface.addCallback("camChanged", function (val:int):void {
+                                               selectedCam = val;
+                                               camChanged(null);
+                                       });
+                                       
ExternalInterface.addCallback("micChanged", function (val:int):void {
+                                               selectedMic = val;
+                                               camChanged(null);
+                                       });
+                                       
ExternalInterface.addCallback("resChanged", function (width:int, 
height:int):void {
+                                               setResolution(width, height, 
true);
+                                       });
+                                       ExternalInterface.addCallback("close", 
function ():void {
+                                               video.reset();
+                                       });
+                                       ExternalInterface.addCallback("init", 
function (camIdx:int, micIdx:int, width:int, height:int):void {
+                                               selectedCam = camIdx;
+                                               selectedMic = micIdx;
+                                               setResolution(width, height, 
true);
+                                       });
+                                       
ExternalInterface.addCallback("startRec", function ():void {
+                                               startTestRecording();
+                                       });
+                                       ExternalInterface.addCallback("play", 
function ():void {
+                                               playTestRecording();
+                                       });
+                                       
ExternalInterface.call("VideoSettings.initSwf");
+                               }
+                                       break;
+                               case OmVideo.BROADCAST:
+                               {
+                                       selectedCam = params.cam;
+                                       selectedMic = params.mic;
+                                       video.resize(Math.max(300, 
params.width), Math.max(200, params.height));
+                                       attachCamera(function():void {
+                                               video.resize(params.width, 
params.height);
+                                               video.reset();
+                                               var cam:Camera = getCam();
+                                               video.attachCamera(cam);
+                                               
video.broadcast(params.broadcastId, cam, getMic());
+                                               
ExternalInterface.call("VideoManager.resetSize", params.uid);
+                                       });
+                               }
+                                       break;
+                               case OmVideo.PLAY:
+                               {
+                                       video.resize(params.width, 
params.height);
+                                       video.play(params.broadcastId); // TODO 
audio/video
+                               }
+                                       break;
+                       }
                }
 
                private function uncaughtError(e:UncaughtErrorEvent):void {
@@ -160,7 +186,7 @@
                        return _camera;
                }
 
-               private function attachCamera():void {
+               private function attachCamera(callback:Function):void {
                        if (!camAvail()) {
                                return;
                        }
@@ -179,13 +205,12 @@
                                                                debug("Unable 
to connect to active camera.");
                                                                break;
                                                        case 'Camera.Unmuted':
-                                                               
ExternalInterface.call("VideoSettings.allowRec", true);
-                                                               
_attachCamera(getCam());
+                                                               callback();
                                                                break;
                                                }
                                        });
                                } else {
-                                       _attachCamera(cam);
+                                       callback();
                                }
                        } else {
                                var _mic:Microphone = getMic();
@@ -226,6 +251,11 @@
                        }
                }
 
+               private function settingsCameraCallback():void {
+                       ExternalInterface.call("VideoSettings.allowRec", true);
+                       _attachCamera(getCam());
+               }
+
                private function setResolution(width:int, height:int, 
attach:Boolean):void {
                        if (!interview) {
                                debug("onselect WxH :: " + width + "x" + 
height);
@@ -233,17 +263,17 @@
                                video.resize(width, height);
 
                                if (attach) {
-                                       attachCamera();
+                                       attachCamera(settingsCameraCallback);
                                }
                        }
                }
 
                private function camChanged(e:Event):void {
-                       attachCamera();
+                       attachCamera(settingsCameraCallback);
                }
 
                private function playTestRecording():void {
-                       video.play(recName);
+                       video.play(recName + ".flv");
                }
 
                private function startTestRecording():void {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as
----------------------------------------------------------------------
diff --git 
a/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as 
b/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as
index cbc0ffe..e23e1ac 100644
--- a/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as
+++ b/openmeetings-flash/src/main/flex/org/apache/openmeetings/OmVideo.as
@@ -145,7 +145,7 @@ public class OmVideo {
                        }
                        videoStreamSettings.setQuality(cam.bandwidth, 
cam.quality);
                        
videoStreamSettings.setKeyFrameInterval(cam.keyFrameInterval);
-                       debug("::keyFrameInterval " + cam.keyFrameInterval);
+                       debug("::camera settings ", cam.keyFrameInterval, 
cam.width, cam.height, cam.fps);
                        videoStreamSettings.setMode(cam.width, cam.height, 
cam.fps);
                        ns.videoStreamSettings = videoStreamSettings;
                }
@@ -160,7 +160,7 @@ public class OmVideo {
                }
        }
 
-       private function publish(mode:String, name:String, cam:Camera, 
mic:Microphone, f:Function):void {
+       private function connect(callback:Function):void {
                if (nc == null || !nc.connected) {
                        var url:String = params.url;  //TODO fallback
                        debug("NetConnection is not connected", url);
@@ -168,7 +168,7 @@ public class OmVideo {
                        nc.addEventListener(NetStatusEvent.NET_STATUS, function 
onConnectionStatus(e:NetStatusEvent):void {
                                debug("ConnectionStatus: " + e.info.code);
                                if (e.info.code == 
"NetConnection.Connect.Success") {
-                                       _publish(mode, name, cam, mic, f);
+                                       callback();
                                } else {
                                        //TODO
                                }
@@ -197,27 +197,37 @@ public class OmVideo {
                                , nativeSsl: 'best' == params.proxyType
                        });
                } else {
-                       _publish(mode, name, cam, mic, f);
+                       callback();
                }
        }
 
+       public function broadcast(name:String, cam:Camera, mic:Microphone):void 
{
+               connect(function():void {
+                       _publish(BROADCAST, name, cam, mic, null);
+               });
+       }
+
        public function record(name:String, cam:Camera, mic:Microphone, 
f:Function):void {
-               publish(RECORD, name, cam, mic, f);
+               connect(function():void {
+                       _publish(RECORD, name, cam, mic, f);
+               });
        }
 
        public function play(name:String):void {
-               debug("PLAY::", name);
-               if (ns != null){
-                       reset();
-               }
-               mode = PLAY;
-               createStream();
-               //invokes Method in baseVideoView which shows the stream
-               getVideo().attachNetStream(ns);
-               //FIXME: Commented out, cause this leads to 
Buffer-Full/Buffer-Empty Events
-               //after re-syncing the stream
-               //this.setBuffer(0.1);
-               ns.play(name + ".flv");
+               connect(function():void {
+                       debug("PLAY::", name);
+                       if (ns != null){
+                               reset();
+                       }
+                       mode = PLAY;
+                       createStream();
+                       //invokes Method in baseVideoView which shows the stream
+                       getVideo().attachNetStream(ns);
+                       //FIXME: Commented out, cause this leads to 
Buffer-Full/Buffer-Empty Events
+                       //after re-syncing the stream
+                       //this.setBuffer(0.1);
+                       ns.play(name);
+               });
        }
 
        public function reset():void {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
----------------------------------------------------------------------
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
index 0f361dd..271f119 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
@@ -137,7 +137,7 @@ public class Application extends 
AuthenticatedWebApplication implements IApplica
                //chain of Resource Loaders, if not found it will search in 
Wicket's internal
                //Resource Loader for a the property key
                getResourceSettings().getStringResourceLoaders().add(0, new 
LabelResourceLoader());
-               
getJavaScriptLibrarySettings().setJQueryReference(JQueryResourceReference.getV3());
+               
getJavaScriptLibrarySettings().setJQueryReference(JQueryResourceReference.getV2());
 
                super.init();
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
----------------------------------------------------------------------
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
index 3055c86..b4da5e9 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
@@ -63,6 +63,7 @@ import org.apache.openmeetings.web.user.UserInfoDialog;
 import org.apache.openmeetings.web.user.chat.ChatPanel;
 import org.apache.openmeetings.web.user.rooms.RoomEnterBehavior;
 import org.apache.openmeetings.web.util.ContactsHelper;
+import org.apache.openmeetings.web.util.ExtendedClientProperties;
 import org.apache.openmeetings.web.util.OmUrlFragment;
 import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
@@ -127,10 +128,29 @@ public class MainPanel extends Panel {
                super(id);
                this.panel = _panel;
                setOutputMarkupId(true);
-               
add(topControls.setOutputMarkupPlaceholderTag(true).setMarkupId("topControls"));
                menu = new MenuPanel("menu", getMainMenu());
                contents = new WebMarkupContainer("contents");
-               add(contents.add(client == null ? EMPTY : 
_panel).setOutputMarkupId(true).setMarkupId("contents"));
+               add(chat = new ChatPanel("chatPanel"));
+               add(newMessage = new MessageDialog("newMessageDialog", new 
CompoundPropertyModel<>(new PrivateMessage())) {
+                       private static final long serialVersionUID = 1L;
+
+                       @Override
+                       public void onClose(IPartialPageRequestHandler handler, 
DialogButton button) {
+                               BasePanel bp = getCurrentPanel();
+                               if (send.equals(button) && bp != null) {
+                                       bp.onNewMessageClose(handler);
+                               }
+                       }
+               });
+               add(userInfo = new UserInfoDialog("userInfoDialog", 
newMessage));
+               add(new OmAjaxClientInfoBehavior());
+       }
+
+       @Override
+       protected void onInitialize() {
+               super.onInitialize();
+               
add(topControls.setOutputMarkupPlaceholderTag(true).setMarkupId("topControls"));
+               add(contents.add(client == null ? EMPTY : 
panel).setOutputMarkupId(true).setMarkupId("contents"));
                topControls.add(menu.setVisible(false), 
topLinks.setVisible(false).setOutputMarkupPlaceholderTag(true).setMarkupId("topLinks"));
                topLinks.add(new AjaxLink<Void>("messages") {
                        private static final long serialVersionUID = 1L;
@@ -157,24 +177,21 @@ public class MainPanel extends Panel {
                                about.open(target);
                        }
                });
+               add(about);
                if 
(getApplication().getDebugSettings().isDevelopmentUtilitiesEnabled()) {
                        add(new DebugBar("dev").setOutputMarkupId(true));
                } else {
                        add(new EmptyPanel("dev").setVisible(false));
                }
-               add(about, chat = new ChatPanel("chatPanel"));
-               add(newMessage = new MessageDialog("newMessageDialog", new 
CompoundPropertyModel<>(new PrivateMessage())) {
+               topLinks.add(new ConfirmableAjaxBorder("logout", 
getString("310"), getString("634")) {
                        private static final long serialVersionUID = 1L;
 
                        @Override
-                       public void onClose(IPartialPageRequestHandler handler, 
DialogButton button) {
-                               BasePanel bp = getCurrentPanel();
-                               if (send.equals(button) && bp != null) {
-                                       bp.onNewMessageClose(handler);
-                               }
+                       protected void onSubmit(AjaxRequestTarget target) {
+                               getSession().invalidate();
+                               
setResponsePage(Application.get().getSignInPageClass());
                        }
                });
-               add(userInfo = new UserInfoDialog("userInfoDialog", 
newMessage));
                add(new AbstractDefaultAjaxBehavior() {
                        private static final long serialVersionUID = 1L;
 
@@ -224,9 +241,9 @@ public class MainPanel extends Panel {
                        @Override
                        protected void onConnect(ConnectedMessage msg) {
                                super.onConnect(msg);
+                               ExtendedClientProperties cp = 
WebSession.get().getExtendedProperties();
                                client = new Client(getSession().getId(), 
msg.getKey().hashCode(), getUserId(), getBean(UserDao.class));
-                               
client.setRemoteAddress(WebSession.get().getClientInfo().getProperties().getRemoteAddress());
-                               addOnlineUser(client);
+                               addOnlineUser(cp.update(client));
                                log.debug("WebSocketBehavior::onConnect [uid: 
{}, session: {}, key: {}]", client.getUid(), msg.getSessionId(), msg.getKey());
                        }
 
@@ -268,21 +285,6 @@ public class MainPanel extends Panel {
                                }
                        }
                });
-               add(new OmAjaxClientInfoBehavior());
-       }
-
-       @Override
-       protected void onInitialize() {
-               super.onInitialize();
-               topLinks.add(new ConfirmableAjaxBorder("logout", 
getString("310"), getString("634")) {
-                       private static final long serialVersionUID = 1L;
-
-                       @Override
-                       protected void onSubmit(AjaxRequestTarget target) {
-                               getSession().invalidate();
-                               
setResponsePage(Application.get().getSignInPageClass());
-                       }
-               });
        }
 
        private static int getLevel() {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java
----------------------------------------------------------------------
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java
index 9ec4dea..8e4f8c6 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java
@@ -153,9 +153,10 @@ public class HashPage extends BaseInitedPage implements 
IUpdatable {
                                        @Override
                                        protected void 
onClientInfo(AjaxRequestTarget target, WebClientInfo info) {
                                                super.onClientInfo(target, 
info);
+                                               ExtendedClientProperties cp = 
(ExtendedClientProperties)info.getProperties();
                                                target.appendJavaScript(
-                                                               
VideoSettings.getInitScript((ExtendedClientProperties)info.getProperties(), 
"hibernate", "networktest")
-                                                               
.append("VideoSettings.open();"));
+                                                               
String.format("VideoSettings.init(%s);VideoSettings.open();"
+                                                                               
, VideoSettings.getInitJson(cp, "hibernate", "noclient")));
                                        }
                                }));
                                error = false;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html
----------------------------------------------------------------------
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html
index 80fae9f..87afb87 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html
@@ -42,5 +42,10 @@
        <div id="disconnected-dlg" wicket:message="title:204, data-reload:753" 
style="display:none">
                <wicket:message key="556"/>
        </div>
+       <div style="display:none">
+               <div id="user-video">
+                       <div class="video"></div>
+               </div>
+       </div>
 </wicket:panel>
 </html>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
----------------------------------------------------------------------
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
index c4d9728..abb98dc 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
@@ -25,6 +25,7 @@ import static 
org.apache.openmeetings.web.app.Application.getBean;
 import static org.apache.openmeetings.web.app.Application.getOnlineClient;
 import static org.apache.openmeetings.web.app.Application.getRoomClients;
 import static org.apache.openmeetings.web.app.WebSession.getDateFormat;
+import static org.apache.openmeetings.web.app.WebSession.getSid;
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
 
 import java.util.Calendar;
@@ -81,6 +82,7 @@ import org.apache.wicket.request.resource.ResourceReference;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 
+import com.github.openjson.JSONObject;
 import com.googlecode.wicket.jquery.core.JQueryBehavior;
 import com.googlecode.wicket.jquery.core.Options;
 import com.googlecode.wicket.jquery.ui.interaction.droppable.Droppable;
@@ -115,7 +117,10 @@ public class RoomPanel extends BasePanel {
                                        , getUserId(), "0", r.getId()
                                        , cp.getRemoteAddress()
                                        , "" + r.getId());
-                       target.appendJavaScript(VideoSettings.getInitScript(cp, 
"" + r.getId(), getClient().getUid()));
+                       //TODO add all broadcasting clients
+                       JSONObject options = VideoSettings.getInitJson(cp, "" + 
r.getId(), getClient().getUid());
+                       options.put("interview", Room.Type.interview == 
r.getType());
+                       
target.appendJavaScript(String.format("VideoManager.init(%s);", options));
                        WebSocketHelper.sendRoom(new RoomMessage(r.getId(), 
getUserId(), RoomMessage.Type.roomEnter));
                        getMainPanel().getChat().roomEnter(r, target);
                        if (r.isFilesOpened()) {
@@ -354,9 +359,14 @@ public class RoomPanel extends BasePanel {
                                                }
                                                break;
                                        case rightUpdated:
-                                               sidebar.update(handler);
-                                               menu.update(handler);
-                                               wb.update(handler);
+                                               {
+                                                       Client c = 
getOnlineClient(((TextRoomMessage)m).getText());
+                                                       
handler.appendJavaScript(String.format("VideoManager.update(%s);"
+                                                                       , 
c.toJson().put("sid", getSid()).put("self", 
getClient().getUid().equals(c.getUid()))));
+                                                       sidebar.update(handler);
+                                                       menu.update(handler);
+                                                       wb.update(handler);
+                                               }
                                                break;
                                        case roomEnter:
                                                sidebar.update(handler);
@@ -581,7 +591,7 @@ public class RoomPanel extends BasePanel {
        }
 
        public void broadcast(Client client) {
-               WebSocketHelper.sendRoom(new RoomMessage(getRoom().getId(), 
getUserId(), RoomMessage.Type.rightUpdated));
+               WebSocketHelper.sendRoom(new TextRoomMessage(getRoom().getId(), 
getUserId(), RoomMessage.Type.rightUpdated, client.getUid()));
                RoomBroadcaster.sendUpdatedClient(client);
        }
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java
----------------------------------------------------------------------
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java
index 98319fc..0b9a08c 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/VideoSettings.java
@@ -65,12 +65,12 @@ public class VideoSettings extends Panel {
                return String.format("%s://%s:%s/%s", protocol, host, port, 
app);
        }
 
-       public static StringBuilder getInitScript(ExtendedClientProperties cp, 
String scope, String uid) {
+       public static JSONObject getInitJson(ExtendedClientProperties cp, 
String scope, String uid) {
                JSONObject gs = 
getBean(ScopeApplicationAdapter.class).getFlashSettings();
                JSONObject s = new JSONObject()
                                .put(FLASH_VIDEO_CODEC, 
gs.get(FLASH_VIDEO_CODEC))
                                .put(FLASH_FPS, gs.get(FLASH_FPS))
-                               .put("SID", WebSession.getSid())
+                               .put("sid", WebSession.getSid())
                                .put("wmode", cp.isBrowserInternetExplorer() && 
cp.getBrowserVersionMajor() == 11 ? "opaque" : "direct");
                if (!Strings.isEmpty(uid)) {
                        s.put("uid", uid);
@@ -90,6 +90,6 @@ public class VideoSettings extends Panel {
                } catch (Exception e) {
                        log.error("Error while constructing video settings 
parameters", e);
                }
-               return new 
StringBuilder("VideoSettings.init(").append(s.toString()).append(");");
+               return s;
        }
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
----------------------------------------------------------------------
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
index 989aa20..ffbfc79 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/room.js
@@ -16,6 +16,99 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+var Video = (function() {
+       var self = {}, c, box, v, vc, t, swf;
+
+       function _getName() {
+               return c.user.firstName + ' ' + c.user.lastName;
+       }
+       function _resetSize() {
+               v.dialog("option", "width", c.width).dialog("option", "height", 
t.height() + c.height + 2);
+               vc.width(c.width).height(c.height);
+               swf.attr('width', c.width).attr('height', c.height);
+       }
+       function _init(_box, _c) {
+               c = _c;
+               box = _box;
+               var _id = "video" + c.uid, name = _getName()
+                       , w = c.self ? Math.max(300, c.width) : c.width
+                       , h = c.self ? Math.max(200, c.height) : c.height;
+               box.append($('#user-video').clone().attr('id', 
_id).attr('title', name).data(self));
+               v = $('#' + _id);
+               v.dialog({
+                       classes: {
+                               'ui-dialog': 'ui-corner-all video user-video'
+                               , 'ui-dialog-titlebar': 'ui-corner-all no-close'
+                       }
+                       , width: w
+                       , minWidth: 40
+                       , minHeight: 50
+                       , autoOpen: true
+                       , modal: false
+                       //resizeStop
+               });
+               t = v.parent().find('.ui-dialog-titlebar').attr('title', name);
+               vc = v.find('.video');
+               vc.width(w).height(h);
+               //broadcast
+               var o = VideoManager.getOptions();
+               if (c.self) {
+                       o.cam = c.cam;
+                       o.mic = c.mic;
+                       o.mode = 'broadcast';
+               } else {
+                       o.mode = 'play';
+               }
+               o.width = c.width;
+               o.height = c.height;
+               o.uid = c.uid;
+               o.sid = c.sid;
+               o.broadcastId = c.broadcastId;
+               swf = initVideo(vc, _id + '-swf', o);
+               swf.attr('width', w).attr('height', h);
+       }
+       function _update(_c) {
+               // TODO check, update video
+               c = _c;
+       }
+
+       self.update = _update;
+       self.init = _init;
+       self.resetSize = _resetSize;
+       return self;
+});
+var VideoManager = (function() {
+       var self = {}, box, options;
+
+       function _init(_options) {
+               options = _options;
+               VideoSettings.init(self.getOptions());
+               box = $('.room.box');
+       }
+       function _getVid(uid) {
+               return "video" + uid;
+       }
+       function _update(o) {
+               var _id = _getVid(o.uid)
+                       , video = o.activities.indexOf('broadcastV') > -1
+                       , audio = o.activities.indexOf('broadcastA') > -1
+                       , av = audio || video
+                       , v = $('#' + _id);
+               if (av && v.length != 1) {
+                       Video().init(box, o);
+               } else if (av && v.length == 1) {
+                       v.data().update(o);
+               } else if (!av && v.length == 1) {
+                       v.remove();
+               }
+       }
+
+       self.getOptions = function() { return 
JSON.parse(JSON.stringify(options)); };
+       self.init = _init;
+       self.update = _update;
+       self.resetSize = function(uid) { $('#' + 
_getVid(uid)).data().resetSize(); };
+       return self;
+})();
 function setRoomSizes() {
        var sb = $(".room.sidebar.left")
                , w = $(window).width() - sb.width() - 5
@@ -73,6 +166,7 @@ function roomUnload() {
                WbArea.destroy();
        }
        VideoSettings.close();
+       $('.ui-dialog.user-video').remove();
 }
 function startPrivateChat(el) {
        Chat.addTab('chatTab-u' + el.parent().parent().data("userid"), 
el.parent().parent().find('.user.name').text());

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/settings.js
----------------------------------------------------------------------
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/settings.js 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/settings.js
index 9c96224..0a46761 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/settings.js
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/settings.js
@@ -41,7 +41,11 @@ var VideoSettings = (function() {
                }
        }
        function _save() {
-               localStorage.setItem('openmeetings', JSON.stringify(s));
+               var _s = JSON.stringify(s);
+               localStorage.setItem('openmeetings', _s);
+               if (typeof avSettings === 'function') {
+                       avSettings(_s);
+               }
        }
        function _init(options) {
                vs = $('#video-settings');
@@ -85,6 +89,7 @@ var VideoSettings = (function() {
                lm.progressbar({ value: 0 });
                options.width = 300;
                options.height = 200;
+               options.mode = 'settings';
                swf = initVideo(vidScroll, 'video-settings-swf', options)[0];
                vs.find('input, button').prop('disabled', true);
                vs.find('button').button();

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
----------------------------------------------------------------------
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
index ffa6ba1..62aaf2d 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
@@ -27,6 +27,7 @@ import static 
org.apache.wicket.ajax.attributes.CallbackParameter.explicit;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter;
 import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.openmeetings.db.entity.basic.Client.Activity;
 import org.apache.openmeetings.db.entity.basic.Client.Pod;
@@ -34,6 +35,7 @@ import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
 import org.apache.openmeetings.web.app.Application;
+import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder;
 import 
org.apache.openmeetings.web.common.ConfirmableAjaxBorder.ConfirmableBorderDialog;
 import org.apache.openmeetings.web.common.NameDialog;
@@ -41,6 +43,7 @@ import org.apache.openmeetings.web.room.RoomBroadcaster;
 import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.openmeetings.web.room.RoomPanel.Action;
 import org.apache.openmeetings.web.room.VideoSettings;
+import org.apache.openmeetings.web.util.ExtendedClientProperties;
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -212,13 +215,9 @@ public class RoomSidebar extends Panel {
                protected void respond(AjaxRequestTarget target) {
                        StringValue s = 
getRequest().getRequestParameters().getParameterValue(PARAM_SETTINGS);
                        if (!s.isEmpty()) {
-                               JSONObject o = new JSONObject(s.toString());
+                               ExtendedClientProperties cp = 
WebSession.get().getExtendedProperties();
                                Client c = room.getClient();
-                               c.setCam(o.optInt("cam", -1));
-                               c.setMic(o.optInt("mic", -1));
-                               boolean interview = Room.Type.interview == 
room.getRoom().getType();
-                               c.setWidth(interview ? 320 : o.optInt("width"));
-                               c.setHeight(interview ? 260 : 
o.optInt("height"));
+                               cp.setSettings(new 
JSONObject(s.toString())).update(c, Room.Type.interview == 
room.getRoom().getType());
                                if (!avInited) {
                                        avInited = true;
                                        if (Room.Type.conference == 
room.getRoom().getType()) {
@@ -419,6 +418,9 @@ public class RoomSidebar extends Panel {
                                //pod has changed, no need to toggle
                                c.set(a);
                        } else {
+                               if (!c.hasActivity(Activity.broadcastV) && 
Activity.broadcastV == a) {
+                                       
c.setBroadcastId(ScopeApplicationAdapter.nextBroadCastId());
+                               }
                                c.toggle(a);
                        }
                        room.broadcast(c);

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/ExtendedClientProperties.java
----------------------------------------------------------------------
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/ExtendedClientProperties.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/ExtendedClientProperties.java
index 1e339ae..a59cbbf 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/ExtendedClientProperties.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/ExtendedClientProperties.java
@@ -22,6 +22,8 @@ import static 
org.apache.openmeetings.web.app.Application.HASH_MAPPING;
 import static org.apache.openmeetings.web.app.Application.NOTINIT_MAPPING;
 import static org.apache.openmeetings.web.app.Application.SIGNIN_MAPPING;
 
+import org.apache.directory.api.util.Strings;
+import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.wicket.protocol.http.ClientProperties;
 import org.apache.wicket.request.IRequestParameters;
 
@@ -29,6 +31,10 @@ import com.github.openjson.JSONObject;
 
 public class ExtendedClientProperties extends ClientProperties {
        private static final long serialVersionUID = 1L;
+       public static final String CAM = "cam";
+       public static final String MIC = "mic";
+       public static final String WIDTH = "width";
+       public static final String HEIGHT = "height";
        private String baseUrl;
        private String codebase;
        private String settings;
@@ -41,13 +47,14 @@ public class ExtendedClientProperties extends 
ClientProperties {
                return baseUrl;
        }
 
-       public void setSettings(JSONObject s) {
+       public ExtendedClientProperties setSettings(JSONObject s) {
                settings = s.toString();
+               return this;
        }
 
        public JSONObject getSettings() {
                try {
-                       return settings == null ? new JSONObject() : new 
JSONObject(settings.toString());
+                       return Strings.isEmpty(settings) ? new JSONObject() : 
new JSONObject(settings.toString());
                } catch (Exception e) {
                        //can throw, no op
                }
@@ -81,4 +88,20 @@ public class ExtendedClientProperties extends 
ClientProperties {
                codebase = sb.append("screenshare").toString();
                settings = 
parameters.getParameterValue("settings").toString("{}");
        }
+
+       public Client update(Client c) {
+               return update(c, false);
+       }
+
+       public Client update(Client c, boolean interview) {
+               JSONObject s = getSettings().optJSONObject("video");
+               if (s == null) {
+                       s = new JSONObject();
+               }
+               return c.setRemoteAddress(getRemoteAddress())
+                               .setCam(s.optInt(CAM, -1))
+                               .setMic(s.optInt(MIC, -1))
+                               .setWidth(interview ? 320 : s.optInt(WIDTH, 0))
+                               .setHeight(interview ? 260 : s.optInt(HEIGHT, 
0));
+       }
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/openmeetings-web/src/main/webapp/css/room.css
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/css/room.css 
b/openmeetings-web/src/main/webapp/css/room.css
index 36fab21..04d3a2b 100644
--- a/openmeetings-web/src/main/webapp/css/room.css
+++ b/openmeetings-web/src/main/webapp/css/room.css
@@ -352,7 +352,7 @@
        font-weight: bold;
        background-color: #00FF00;
 }
-.ui-dialog.video, .ui-dialog.video .ui-dialog-titlebar, .ui-dialog.video 
.video.ui-dialog-content {
+.ui-dialog.video, .ui-dialog.video .ui-dialog-titlebar, .ui-dialog.video 
.ui-dialog-content {
        padding: 0;
        overflow: hidden;
 }
@@ -574,3 +574,20 @@
        border: 1px solid #888888;
        box-shadow: 5px 5px 5px #888888;
 }
+.room.box .user-video {
+       display: inline-block !important;
+}
+.room.box .user-video .header {
+       height: 20px;
+       text-overflow: ellipsis;
+       white-space: nowrap;
+       overflow: hidden;
+}
+.room.box .user-video .header .ui-dialog-title {
+       padding-left: 5px;
+}
+.room.box .user-video .video {
+       min-width: 40px;
+       min-height: 30px;
+       overflow: hidden;
+}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/838bfbe3/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index bbcf269..48faea7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -38,7 +38,7 @@
                <db>derby</db>
                <junit.version>4.12</junit.version>
                <maven.javadoc.version>2.10.3</maven.javadoc.version>
-               <maven.surefire.version>2.19.1</maven.surefire.version>
+               <maven.surefire.version>2.20</maven.surefire.version>
                <maven-site.version>3.3</maven-site.version>
                <wicket.version>8.0.0-SNAPSHOT</wicket.version>
                <wicketju.version>8.0.0-M5</wicketju.version>

Reply via email to