Merge pull request #679 from ritzalam/reconnect-to-bbb-video
Reconnect to bbb video
This commit is contained in:
commit
2eb1de6cab
@ -50,7 +50,7 @@ libraryDependencies ++= {
|
||||
"com.google.code.gson" % "gson" % "1.7.1",
|
||||
"redis.clients" % "jedis" % "2.1.0",
|
||||
"org.apache.commons" % "commons-lang3" % "3.2",
|
||||
"org.bigbluebutton" % "bbb-common-message" % "0.0.5"
|
||||
"org.bigbluebutton" % "bbb-common-message" % "0.0.6"
|
||||
)}
|
||||
|
||||
|
||||
|
@ -50,7 +50,7 @@ libraryDependencies ++= {
|
||||
"com.google.code.gson" % "gson" % "1.7.1",
|
||||
"redis.clients" % "jedis" % "2.1.0",
|
||||
"org.apache.commons" % "commons-lang3" % "3.2",
|
||||
"org.bigbluebutton" % "bbb-common-message" % "0.0.5",
|
||||
"org.bigbluebutton" % "bbb-common-message" % "0.0.6",
|
||||
"org.bigbluebutton" % "bbb-fsesl-client" % "0.0.2"
|
||||
)}
|
||||
|
||||
|
@ -4,7 +4,7 @@ name := "bbb-common-message"
|
||||
|
||||
organization := "org.bigbluebutton"
|
||||
|
||||
version := "0.0.5"
|
||||
version := "0.0.6"
|
||||
|
||||
// We want to have our jar files in lib_managed dir.
|
||||
// This way we'll have the right path when we import
|
||||
|
@ -30,6 +30,7 @@ public class GetUsersReplyMessage implements ISubscribedMessage {
|
||||
|
||||
return MessageBuilder.buildJson(header, payload);
|
||||
}
|
||||
|
||||
public static GetUsersReplyMessage fromJson(String message) {
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonObject obj = (JsonObject) parser.parse(message);
|
||||
|
@ -73,7 +73,7 @@ public class Util {
|
||||
&& user.has(Constants.RAISE_HAND) && user.has(Constants.PHONE_USER)
|
||||
&& user.has(Constants.PRESENTER) && user.has(Constants.LOCKED)
|
||||
&& user.has(Constants.EXTERN_USERID) && user.has(Constants.ROLE)
|
||||
&& user.has(Constants.VOICEUSER)){
|
||||
&& user.has(Constants.VOICEUSER) && user.has(Constants.WEBCAM_STREAM)){
|
||||
|
||||
Map<String, Object> userMap = new HashMap<String, Object>();
|
||||
|
||||
@ -87,11 +87,15 @@ public class Util {
|
||||
Boolean locked = user.get(Constants.LOCKED).getAsBoolean();
|
||||
String extUserId = user.get(Constants.EXTERN_USERID).getAsString();
|
||||
String role = user.get(Constants.ROLE).getAsString();
|
||||
|
||||
|
||||
JsonArray webcamStreamJArray = user.get(Constants.WEBCAM_STREAM).getAsJsonArray();
|
||||
ArrayList<String> webcamStreams = extractWebcamStreams(webcamStreamJArray);
|
||||
|
||||
userMap.put("userId", userid);
|
||||
userMap.put("name", username);
|
||||
userMap.put("listenOnly", listenOnly);
|
||||
userMap.put("hasStream", hasStream);
|
||||
userMap.put("webcamStream", webcamStreams);
|
||||
userMap.put("raiseHand", raiseHand);
|
||||
userMap.put("externUserID", extUserId);
|
||||
userMap.put("phoneUser", phoneUser);
|
||||
@ -169,6 +173,19 @@ public class Util {
|
||||
return collection;
|
||||
|
||||
}
|
||||
|
||||
public ArrayList<String> extractWebcamStreams(JsonArray webcamStreams) {
|
||||
ArrayList<String> collection = new ArrayList<String>();
|
||||
|
||||
Iterator<JsonElement> webcamStreamsIter = webcamStreams.iterator();
|
||||
while (webcamStreamsIter.hasNext()){
|
||||
JsonElement stream = webcamStreamsIter.next();
|
||||
collection.add(stream.getAsString());
|
||||
}
|
||||
|
||||
return collection;
|
||||
|
||||
}
|
||||
|
||||
public ArrayList<String> extractUserids(JsonArray users) {
|
||||
ArrayList<String> collection = new ArrayList<String>();
|
||||
|
@ -204,7 +204,7 @@ public class VideoApplication extends MultiThreadedApplicationAdapter {
|
||||
scopeName = stream.getScope().getName();
|
||||
}
|
||||
|
||||
log.info("streamBroadcastClose " + stream.getPublishedName() + " " + System.currentTimeMillis() + " " + conn.getScope().getName());
|
||||
log.info("Stream broadcast closed for stream=[{}] meeting=[{}]", stream.getPublishedName(), scopeName);
|
||||
|
||||
String userId = getUserId();
|
||||
String meetingId = conn.getScope().getName();
|
||||
@ -214,13 +214,13 @@ public class VideoApplication extends MultiThreadedApplicationAdapter {
|
||||
|
||||
IStreamListener listener = streamListeners.remove(scopeName + "-" + stream.getPublishedName());
|
||||
if (listener != null) {
|
||||
stream.removeStreamListener(listener);
|
||||
((VideoStreamListener) listener).streamStopped();
|
||||
stream.removeStreamListener(listener);
|
||||
}
|
||||
|
||||
if (recordVideoStream) {
|
||||
|
||||
if (recordVideoStream) {
|
||||
long publishDuration = (System.currentTimeMillis() - stream.getCreationTime()) / 1000;
|
||||
log.info("streamBroadcastClose " + stream.getPublishedName() + " " + System.currentTimeMillis() + " " + scopeName);
|
||||
log.info("Stop recording event for stream=[{}] meeting=[{}]", stream.getPublishedName(), scopeName);
|
||||
Map<String, String> event = new HashMap<String, String>();
|
||||
event.put("module", "WEBCAM");
|
||||
event.put("timestamp", genTimestamp().toString());
|
||||
|
@ -75,6 +75,8 @@ public class VideoStreamListener implements IStreamListener {
|
||||
// Event queue worker job name
|
||||
private String timeoutJobName;
|
||||
|
||||
private volatile boolean publishing = false;
|
||||
|
||||
private IScope scope;
|
||||
|
||||
public VideoStreamListener(IScope scope, IBroadcastStream stream, Boolean record) {
|
||||
@ -107,11 +109,12 @@ public class VideoStreamListener implements IStreamListener {
|
||||
|
||||
if (! firstPacketReceived) {
|
||||
firstPacketReceived = true;
|
||||
// start the worker
|
||||
publishing = true;
|
||||
|
||||
// start the worker to monitor if we are still receiving video packets
|
||||
timeoutJobName = scheduler.addScheduledJob(videoTimeout, new TimeoutJob());
|
||||
|
||||
if (record) {
|
||||
IConnection conn = Red5.getConnectionLocal();
|
||||
Map<String, String> event = new HashMap<String, String>();
|
||||
event.put("module", "WEBCAM");
|
||||
event.put("timestamp", genTimestamp().toString());
|
||||
@ -119,7 +122,7 @@ public class VideoStreamListener implements IStreamListener {
|
||||
event.put("stream", stream.getPublishedName());
|
||||
event.put("eventName", "StartWebcamShareEvent");
|
||||
|
||||
recordingService.record(conn.getScope().getName(), event);
|
||||
recordingService.record(scope.getName(), event);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -129,15 +132,27 @@ public class VideoStreamListener implements IStreamListener {
|
||||
recordingService = s;
|
||||
}
|
||||
|
||||
public void streamStopped() {
|
||||
this.publishing = false;
|
||||
}
|
||||
|
||||
private class TimeoutJob implements IScheduledJob {
|
||||
|
||||
private boolean streamStopped = false;
|
||||
|
||||
public void execute(ISchedulingService service) {
|
||||
if ((System.currentTimeMillis() - lastVideoTime) > videoTimeout) {
|
||||
log.warn("No data received for stream[{}] in the last few seconds. Close stream.", stream.getPublishedName());
|
||||
// remove the scheduled job
|
||||
scheduler.removeScheduledJob(timeoutJobName);
|
||||
// stop / clean up
|
||||
stream.stop();
|
||||
|
||||
if (!streamStopped) {
|
||||
streamStopped = true;
|
||||
// remove the scheduled job
|
||||
scheduler.removeScheduledJob(timeoutJobName);
|
||||
// stop / clean up
|
||||
if (publishing) {
|
||||
stream.stop();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ dependencies {
|
||||
compile 'com.google.code.gson:gson:1.7.1'
|
||||
providedCompile 'org.apache.commons:commons-lang3:3.2'
|
||||
|
||||
compile 'org.bigbluebutton:bbb-common-message:0.0.5'
|
||||
compile 'org.bigbluebutton:bbb-common-message:0.0.6'
|
||||
}
|
||||
|
||||
test {
|
||||
|
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* 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.events
|
||||
{
|
||||
import flash.events.Event;
|
||||
|
||||
public class StreamStoppedEvent extends Event
|
||||
{
|
||||
public static const STREAM_STOPPED:String = "webcam stream stopped";
|
||||
|
||||
public var streamId:String;
|
||||
public var userId:String
|
||||
|
||||
public function StreamStoppedEvent(userId:String, streamId:String)
|
||||
{
|
||||
this.userId = userId;
|
||||
this.streamId = streamId;
|
||||
super(STREAM_STOPPED, true, false);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -42,6 +42,8 @@ package org.bigbluebutton.modules.users.services
|
||||
import org.bigbluebutton.main.model.users.Conference;
|
||||
import org.bigbluebutton.main.model.users.IMessageListener;
|
||||
import org.bigbluebutton.main.model.users.events.RoleChangeEvent;
|
||||
import org.bigbluebutton.main.model.users.events.StreamStartedEvent;
|
||||
import org.bigbluebutton.main.model.users.events.StreamStoppedEvent;
|
||||
import org.bigbluebutton.main.model.users.events.UsersConnectionEvent;
|
||||
import org.bigbluebutton.modules.present.events.CursorEvent;
|
||||
import org.bigbluebutton.modules.present.events.NavigationEvent;
|
||||
@ -517,7 +519,13 @@ package org.bigbluebutton.modules.users.services
|
||||
trace(LOG + "*** handleUserUnsharedWebcam " + msg.msg + " **** \n");
|
||||
var map:Object = JSON.parse(msg.msg);
|
||||
UserManager.getInstance().getConference().unsharedWebcam(map.userId, map.webcamStream);
|
||||
sendStreamStoppedEvent(map.userId, map.webcamStream);
|
||||
}
|
||||
|
||||
private function sendStreamStoppedEvent(userId: String, streamId: String):void{
|
||||
var dispatcher:Dispatcher = new Dispatcher();
|
||||
dispatcher.dispatchEvent(new StreamStoppedEvent(userId, streamId));
|
||||
}
|
||||
|
||||
public function participantStatusChange(userID:String, status:String, value:Object):void {
|
||||
trace(LOG + "Received status change [" + userID + "," + status + "," + value + "]")
|
||||
|
@ -23,22 +23,23 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
<EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/">
|
||||
<mx:Script>
|
||||
<![CDATA[
|
||||
import org.bigbluebutton.core.events.ConnectAppEvent;
|
||||
import org.bigbluebutton.main.events.BBBEvent;
|
||||
import org.bigbluebutton.main.events.MadePresenterEvent;
|
||||
import org.bigbluebutton.main.events.StoppedViewingWebcamEvent;
|
||||
import org.bigbluebutton.main.events.UserJoinedEvent;
|
||||
import org.bigbluebutton.main.events.UserLeftEvent;
|
||||
import org.bigbluebutton.main.model.users.events.StreamStartedEvent;
|
||||
import org.bigbluebutton.modules.users.events.ViewCameraEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.ClosePublishWindowEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.ConnectedEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.ShareCameraRequestEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.StartBroadcastEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.StopBroadcastEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.StopShareCameraRequestEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.VideoModuleStartEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.VideoModuleStopEvent;
|
||||
import org.bigbluebutton.core.events.ConnectAppEvent;
|
||||
import org.bigbluebutton.main.events.BBBEvent;
|
||||
import org.bigbluebutton.main.events.MadePresenterEvent;
|
||||
import org.bigbluebutton.main.events.StoppedViewingWebcamEvent;
|
||||
import org.bigbluebutton.main.events.UserJoinedEvent;
|
||||
import org.bigbluebutton.main.events.UserLeftEvent;
|
||||
import org.bigbluebutton.main.model.users.events.StreamStartedEvent;
|
||||
import org.bigbluebutton.main.model.users.events.StreamStoppedEvent;
|
||||
import org.bigbluebutton.modules.users.events.ViewCameraEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.ClosePublishWindowEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.ConnectedEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.ShareCameraRequestEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.StartBroadcastEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.StopBroadcastEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.StopShareCameraRequestEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.VideoModuleStartEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.VideoModuleStopEvent;
|
||||
]]>
|
||||
</mx:Script>
|
||||
|
||||
@ -85,6 +86,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
<MethodInvoker generator="{VideoEventMapDelegate}" method="viewCamera" arguments="{[event.userID, event.stream, event.user]}" />
|
||||
</EventHandlers>
|
||||
|
||||
<EventHandlers type="{StreamStoppedEvent.STREAM_STOPPED}">
|
||||
<MethodInvoker generator="{VideoEventMapDelegate}" method="handleStreamStoppedEvent" arguments="{event}" />
|
||||
</EventHandlers>
|
||||
|
||||
<EventHandlers type="{ViewCameraEvent.VIEW_CAMERA_EVENT}">
|
||||
<MethodInvoker generator="{VideoEventMapDelegate}" method="viewCamera" arguments="{[event.userID, event.stream, event.viewedName]}" />
|
||||
</EventHandlers>
|
||||
|
@ -18,23 +18,17 @@
|
||||
*/
|
||||
package org.bigbluebutton.modules.videoconf.maps
|
||||
{
|
||||
import com.asfusion.mate.utils.debug.Debugger;
|
||||
import com.asfusion.mate.utils.debug.DebuggerUtil;
|
||||
|
||||
import flash.events.IEventDispatcher;
|
||||
import flash.external.ExternalInterface;
|
||||
import flash.media.Camera;
|
||||
|
||||
|
||||
import mx.collections.ArrayCollection;
|
||||
import mx.collections.ArrayList;
|
||||
|
||||
|
||||
import org.bigbluebutton.common.LogUtil;
|
||||
import org.bigbluebutton.common.events.CloseWindowEvent;
|
||||
import org.bigbluebutton.common.events.OpenWindowEvent;
|
||||
import org.bigbluebutton.common.events.ToolbarButtonEvent;
|
||||
import org.bigbluebutton.core.BBB;
|
||||
import org.bigbluebutton.core.UsersUtil;
|
||||
import org.bigbluebutton.core.events.ConnectAppEvent;
|
||||
import org.bigbluebutton.core.managers.UserManager;
|
||||
import org.bigbluebutton.core.model.VideoProfile;
|
||||
import org.bigbluebutton.core.vo.CameraSettingsVO;
|
||||
@ -46,27 +40,18 @@ package org.bigbluebutton.modules.videoconf.maps
|
||||
import org.bigbluebutton.main.model.users.BBBUser;
|
||||
import org.bigbluebutton.main.model.users.events.BroadcastStartedEvent;
|
||||
import org.bigbluebutton.main.model.users.events.BroadcastStoppedEvent;
|
||||
import org.bigbluebutton.main.model.users.events.StreamStartedEvent;
|
||||
import org.bigbluebutton.main.model.users.events.StreamStoppedEvent;
|
||||
import org.bigbluebutton.modules.videoconf.business.VideoProxy;
|
||||
import org.bigbluebutton.modules.videoconf.events.CloseAllWindowsEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.ClosePublishWindowEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.ConnectedEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.OpenVideoWindowEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.ShareCameraRequestEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.StartBroadcastEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.StopBroadcastEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.StopShareCameraRequestEvent;
|
||||
import org.bigbluebutton.modules.videoconf.events.WebRTCWebcamRequestEvent;
|
||||
import org.bigbluebutton.modules.videoconf.model.VideoConfOptions;
|
||||
import org.bigbluebutton.modules.videoconf.views.AvatarWindow;
|
||||
import org.bigbluebutton.modules.videoconf.views.GraphicsWrapper;
|
||||
import org.bigbluebutton.modules.videoconf.views.ToolbarPopupButton;
|
||||
import org.bigbluebutton.modules.videoconf.views.UserAvatar;
|
||||
import org.bigbluebutton.modules.videoconf.views.UserGraphic;
|
||||
import org.bigbluebutton.modules.videoconf.views.UserGraphicHolder;
|
||||
import org.bigbluebutton.modules.videoconf.views.UserVideo;
|
||||
import org.bigbluebutton.modules.videoconf.views.VideoDock;
|
||||
import org.flexunit.runner.manipulation.filters.IncludeAllFilter;
|
||||
|
||||
public class VideoEventMapDelegate
|
||||
{
|
||||
@ -121,6 +106,14 @@ package org.bigbluebutton.modules.videoconf.maps
|
||||
}
|
||||
}
|
||||
|
||||
public function handleStreamStoppedEvent(event:StreamStoppedEvent):void {
|
||||
if (UserManager.getInstance().getConference().amIThisUser(event.userId)) {
|
||||
closePublishWindowWithStream(event.userId, event.streamId);
|
||||
} else {
|
||||
closeViewWindowWithStream(event.userId, event.streamId);
|
||||
}
|
||||
}
|
||||
|
||||
public function handleUserLeftEvent(event:UserLeftEvent):void {
|
||||
trace("VideoEventMapDelegate:: [" + me + "] handleUserLeftEvent. ready = [" + _ready + "]");
|
||||
|
||||
@ -288,7 +281,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);
|
||||
proxy.startPublishing(e);
|
||||
|
||||
_isWaitingActivation = false;
|
||||
|
1
bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/views/UserGraphicHolder.mxml
Normal file → Executable file
1
bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/views/UserGraphicHolder.mxml
Normal file → Executable file
@ -134,7 +134,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
}
|
||||
|
||||
public function shutdown():void {
|
||||
trace("[UserGraphicHolder:shutdown]");
|
||||
video.shutdown();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user