Merge remote-tracking branch 'upstream/master' into html5-stun-audio

This commit is contained in:
Matthew Marangoni 2016-10-24 09:08:13 -07:00
commit 0d3f231ac1
194 changed files with 2797 additions and 7385 deletions

View File

@ -55,7 +55,7 @@ libraryDependencies ++= {
"org.pegdown" % "pegdown" % "1.4.0",
"junit" % "junit" % "4.11",
"com.etaty.rediscala" %% "rediscala" % "1.4.0",
"commons-codec" % "commons-codec" % "1.8",
"commons-codec" % "commons-codec" % "1.10",
"joda-time" % "joda-time" % "2.3",
"com.google.code.gson" % "gson" % "2.5",
"redis.clients" % "jedis" % "2.7.2",

View File

@ -35,7 +35,7 @@ public class MeetingMessageReceiver implements MessageHandler {
public void handleMessage(String pattern, String channel, String message) {
if (channel.equalsIgnoreCase(MessagingConstants.TO_MEETING_CHANNEL)) {
System.out.println("Meeting message: " + channel + " " + message);
System.out.println("Meeting message: " + channel + " " + message);
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
@ -45,8 +45,8 @@ public class MeetingMessageReceiver implements MessageHandler {
String messageName = header.get("name").getAsString();
if (CreateMeetingRequest.NAME.equals(messageName)) {
Gson gson = new Gson();
CreateMeetingRequest msg = gson.fromJson(message,
CreateMeetingRequest.class);
CreateMeetingRequest msg = gson.fromJson(message,
CreateMeetingRequest.class);
bbbGW.handleBigBlueButtonMessage(msg);
}
}
@ -59,49 +59,50 @@ public class MeetingMessageReceiver implements MessageHandler {
EndMeetingMessage emm = (EndMeetingMessage) msg;
bbbGW.endMeeting(emm.meetingId);
} else if (msg instanceof RegisterUserMessage) {
RegisterUserMessage emm = (RegisterUserMessage) msg;
bbbGW.registerUser(emm.meetingID, emm.internalUserId, emm.fullname, emm.role, emm.externUserID, emm.authToken, emm.avatarURL);
RegisterUserMessage rum = (RegisterUserMessage) msg;
bbbGW.registerUser(rum.meetingID, rum.internalUserId, rum.fullname, rum.role, rum.externUserID, rum.authToken, rum.avatarURL);
} else if (msg instanceof DestroyMeetingMessage) {
DestroyMeetingMessage emm = (DestroyMeetingMessage) msg;
bbbGW.destroyMeeting(emm.meetingId);
DestroyMeetingMessage dmm = (DestroyMeetingMessage) msg;
bbbGW.destroyMeeting(dmm.meetingId);
} else if (msg instanceof ValidateAuthTokenMessage) {
ValidateAuthTokenMessage emm = (ValidateAuthTokenMessage) msg;
ValidateAuthTokenMessage vam = (ValidateAuthTokenMessage) msg;
String sessionId = "tobeimplemented";
bbbGW.validateAuthToken(emm.meetingId, emm.userId, emm.token, emm.replyTo, sessionId);
bbbGW.validateAuthToken(vam.meetingId, vam.userId, vam.token, vam.replyTo, sessionId);
} else if (msg instanceof UserConnectedToGlobalAudio) {
UserConnectedToGlobalAudio emm = (UserConnectedToGlobalAudio) msg;
UserConnectedToGlobalAudio ustga = (UserConnectedToGlobalAudio) msg;
Map<String, Object> logData = new HashMap<String, Object>();
logData.put("voiceConf", emm.voiceConf);
logData.put("userId", emm.userid);
logData.put("username", emm.name);
logData.put("voiceConf", ustga.voiceConf);
logData.put("userId", ustga.userid);
logData.put("username", ustga.name);
logData.put("event", "user_connected_to_global_audio");
logData.put("description", "User connected to global audio.");
/*
Gson gson = new Gson();
String logStr = gson.toJson(logData);
//System.out.println("User connected to global audio: data={}", logStr);
bbbGW.userConnectedToGlobalAudio(emm.voiceConf, emm.userid, emm.name);
System.out.println("User connected to global audio: data={}", logStr);
*/
bbbGW.userConnectedToGlobalAudio(ustga.voiceConf, ustga.userid, ustga.name);
} else if (msg instanceof UserDisconnectedFromGlobalAudio) {
UserDisconnectedFromGlobalAudio emm = (UserDisconnectedFromGlobalAudio) msg;
UserDisconnectedFromGlobalAudio udfga = (UserDisconnectedFromGlobalAudio) msg;
Map<String, Object> logData = new HashMap<String, Object>();
logData.put("voiceConf", emm.voiceConf);
logData.put("userId", emm.userid);
logData.put("username", emm.name);
logData.put("voiceConf", udfga.voiceConf);
logData.put("userId", udfga.userid);
logData.put("username", udfga.name);
logData.put("event", "user_disconnected_from_global_audio");
logData.put("description", "User disconnected from global audio.");
/*
Gson gson = new Gson();
String logStr = gson.toJson(logData);
//System.out.println("User disconnected from global audio: data={}", logStr);
bbbGW.userDisconnectedFromGlobalAudio(emm.voiceConf, emm.userid, emm.name);
System.out.println("User disconnected from global audio: data={}", logStr);
*/
bbbGW.userDisconnectedFromGlobalAudio(udfga.voiceConf, udfga.userid, udfga.name);
}
else if (msg instanceof GetAllMeetingsRequest) {
GetAllMeetingsRequest emm = (GetAllMeetingsRequest) msg;
GetAllMeetingsRequest gamr = (GetAllMeetingsRequest) msg;
bbbGW.getAllMeetings("no_need_of_a_meeting_id");
} else {
System.out.println("Unknown message: [" + message + "]");
@ -126,8 +127,8 @@ public class MeetingMessageReceiver implements MessageHandler {
if (msg != null) {
if (msg instanceof KeepAliveMessage) {
KeepAliveMessage emm = (KeepAliveMessage) msg;
bbbGW.isAliveAudit(emm.keepAliveId);
KeepAliveMessage kam = (KeepAliveMessage) msg;
bbbGW.isAliveAudit(kam.keepAliveId);
}
} else {
System.out.println("Unknown message: [" + message + "]");

View File

@ -28,6 +28,10 @@ public class ParticipantJoinRecordEvent extends AbstractParticipantRecordEvent {
public void setUserId(String userId) {
eventMap.put("userId", userId);
}
public void setExternalUserId(String externalUserId) {
eventMap.put("externalUserId", externalUserId);
}
public void setName(String name){
eventMap.put("name",name);

View File

@ -21,6 +21,7 @@ package org.bigbluebutton.core.recorders.events;
public class PublicChatRecordEvent extends AbstractChatRecordEvent {
private static final String SENDER = "sender";
private static final String SENDERID = "senderId";
private static final String MESSAGE = "message";
private static final String COLOR = "color";
@ -32,6 +33,10 @@ public class PublicChatRecordEvent extends AbstractChatRecordEvent {
public void setSender(String sender) {
eventMap.put(SENDER, sender);
}
public void setSenderId(String senderId) {
eventMap.put(SENDERID, senderId);
}
public void setMessage(String message) {
eventMap.put(MESSAGE, message);

View File

@ -43,7 +43,6 @@ http {
services {
bbbWebAPI = "http://192.168.23.33/bigbluebutton/api"
sharedSecret = "changeme"
defaultPresentationURL = "http://localhost/default.pdf"
}
red5 {

View File

@ -18,7 +18,6 @@ trait SystemConfiguration {
lazy val bbbWebSharedSecret = Try(config.getString("services.sharedSecret")).getOrElse("changeme")
lazy val bbbWebModeratorPassword = Try(config.getString("services.moderatorPassword")).getOrElse("changeme")
lazy val bbbWebViewerPassword = Try(config.getString("services.viewerPassword")).getOrElse("changeme")
lazy val bbbWebDefaultPresentationURL = Try(config.getString("services.defaultPresentationURL")).getOrElse("changeme")
lazy val keysExpiresInSec = Try(config.getInt("redis.keyExpiry")).getOrElse(14 * 86400) // 14 days
lazy val red5DeskShareIP = Try(config.getString("red5.deskshareip")).getOrElse("127.0.0.1")
lazy val red5DeskShareApp = Try(config.getString("red5.deskshareapp")).getOrElse("")

View File

@ -11,13 +11,13 @@ import org.bigbluebutton.SystemConfiguration
object BigBlueButtonActor extends SystemConfiguration {
def props(system: ActorSystem,
eventBus: IncomingEventBus,
outGW: OutMessageGateway): Props =
eventBus: IncomingEventBus,
outGW: OutMessageGateway): Props =
Props(classOf[BigBlueButtonActor], system, eventBus, outGW)
}
class BigBlueButtonActor(val system: ActorSystem,
eventBus: IncomingEventBus, outGW: OutMessageGateway) extends Actor with ActorLogging {
eventBus: IncomingEventBus, outGW: OutMessageGateway) extends Actor with ActorLogging {
implicit def executionContext = system.dispatcher
implicit val timeout = Timeout(5 seconds)
@ -25,19 +25,19 @@ class BigBlueButtonActor(val system: ActorSystem,
private var meetings = new collection.immutable.HashMap[String, RunningMeeting]
def receive = {
case msg: CreateMeeting => handleCreateMeeting(msg)
case msg: DestroyMeeting => handleDestroyMeeting(msg)
case msg: KeepAliveMessage => handleKeepAliveMessage(msg)
case msg: PubSubPing => handlePubSubPingMessage(msg)
case msg: ValidateAuthToken => handleValidateAuthToken(msg)
case msg: GetAllMeetingsRequest => handleGetAllMeetingsRequest(msg)
case msg: UserJoinedVoiceConfMessage => handleUserJoinedVoiceConfMessage(msg)
case msg: UserLeftVoiceConfMessage => handleUserLeftVoiceConfMessage(msg)
case msg: UserLockedInVoiceConfMessage => handleUserLockedInVoiceConfMessage(msg)
case msg: UserMutedInVoiceConfMessage => handleUserMutedInVoiceConfMessage(msg)
case msg: UserTalkingInVoiceConfMessage => handleUserTalkingInVoiceConfMessage(msg)
case msg: CreateMeeting => handleCreateMeeting(msg)
case msg: DestroyMeeting => handleDestroyMeeting(msg)
case msg: KeepAliveMessage => handleKeepAliveMessage(msg)
case msg: PubSubPing => handlePubSubPingMessage(msg)
case msg: ValidateAuthToken => handleValidateAuthToken(msg)
case msg: GetAllMeetingsRequest => handleGetAllMeetingsRequest(msg)
case msg: UserJoinedVoiceConfMessage => handleUserJoinedVoiceConfMessage(msg)
case msg: UserLeftVoiceConfMessage => handleUserLeftVoiceConfMessage(msg)
case msg: UserLockedInVoiceConfMessage => handleUserLockedInVoiceConfMessage(msg)
case msg: UserMutedInVoiceConfMessage => handleUserMutedInVoiceConfMessage(msg)
case msg: UserTalkingInVoiceConfMessage => handleUserTalkingInVoiceConfMessage(msg)
case msg: VoiceConfRecordingStartedMessage => handleVoiceConfRecordingStartedMessage(msg)
case _ => // do nothing
case _ => // do nothing
}
private def findMeetingWithVoiceConfId(voiceConfId: String): Option[RunningMeeting] = {
@ -117,9 +117,9 @@ class BigBlueButtonActor(val system: ActorSystem,
meetings -= msg.meetingID
log.info("Kick everyone out on meetingId={}", msg.meetingID)
if (m.mProps.isBreakout) {
log.info("Informing parent meeting {} that a breakout room has been ended {}", m.mProps.externalMeetingID, m.mProps.meetingID)
eventBus.publish(BigBlueButtonEvent(m.mProps.externalMeetingID,
BreakoutRoomEnded(m.mProps.externalMeetingID, m.mProps.meetingID)))
log.info("Informing parent meeting {} that a breakout room has been ended {}", m.mProps.parentMeetingID, m.mProps.meetingID)
eventBus.publish(BigBlueButtonEvent(m.mProps.parentMeetingID,
BreakoutRoomEnded(m.mProps.parentMeetingID, m.mProps.meetingID)))
}
outGW.send(new EndAndKickAll(msg.meetingID, m.mProps.recorded))
outGW.send(new DisconnectAllUsers(msg.meetingID))
@ -149,9 +149,9 @@ class BigBlueButtonActor(val system: ActorSystem,
eventBus.subscribe(m.actorRef, m.mProps.deskshareBridge)
meetings += m.mProps.meetingID -> m
outGW.send(new MeetingCreated(m.mProps.meetingID, m.mProps.externalMeetingID, m.mProps.recorded, m.mProps.meetingName,
m.mProps.voiceBridge, msg.mProps.duration, msg.mProps.moderatorPass,
msg.mProps.viewerPass, msg.mProps.createTime, msg.mProps.createDate))
outGW.send(new MeetingCreated(m.mProps.meetingID, m.mProps.externalMeetingID, m.mProps.parentMeetingID,
m.mProps.recorded, m.mProps.meetingName, m.mProps.voiceBridge, msg.mProps.duration, msg.mProps.moderatorPass,
msg.mProps.viewerPass, msg.mProps.createTime, msg.mProps.createDate, msg.mProps.isBreakout))
m.actorRef ! new InitializeMeeting(m.mProps.meetingID, m.mProps.recorded)
}

View File

@ -57,6 +57,7 @@ class BigBlueButtonInGW(
val mProps = new MeetingProperties(
msg.payload.id,
msg.payload.externalId,
msg.payload.parentId,
msg.payload.name,
msg.payload.record,
msg.payload.voiceConfId,
@ -69,7 +70,8 @@ class BigBlueButtonInGW(
msg.payload.createTime,
msg.payload.createDate,
red5DeskShareIP, red5DeskShareApp,
msg.payload.isBreakout)
msg.payload.isBreakout,
msg.payload.sequence)
eventBus.publish(BigBlueButtonEvent("meeting-manager", new CreateMeeting(msg.payload.id, mProps)))
}

View File

@ -51,7 +51,7 @@ object JsonMessageDecoder {
def decode(json: String): Option[InMessage] = {
unmarshall(json) match {
case Success(validMsg) => Some(validMsg)
case Failure(ex) => None
case Failure(ex) => None
}
}
@ -75,4 +75,4 @@ object JsonMessageDecoder {
case _ => throw MessageProcessException("Cannot parse JSON message: [" + msg + "]")
}
}
}
}

View File

@ -38,27 +38,27 @@ class JsonMessageSenderActor(val service: MessageSender)
def receive = {
// Breakout
case msg: CreateBreakoutRoom => handleCreateBreakoutRoom(msg)
case msg: EndBreakoutRoom => handleEndBreakoutRoom(msg)
case msg: BreakoutRoomsListOutMessage => handleBreakoutRoomsList(msg)
case msg: CreateBreakoutRoom => handleCreateBreakoutRoom(msg)
case msg: EndBreakoutRoom => handleEndBreakoutRoom(msg)
case msg: BreakoutRoomsListOutMessage => handleBreakoutRoomsList(msg)
case msg: BreakoutRoomJoinURLOutMessage => handleBreakoutRoomJoinURL(msg)
case msg: BreakoutRoomStartedOutMessage => handleBreakoutRoomStarted(msg)
case msg: BreakoutRoomEndedOutMessage => handleBreakoutRoomEnded(msg)
case msg: BreakoutRoomEndedOutMessage => handleBreakoutRoomEnded(msg)
case msg: UpdateBreakoutUsersOutMessage => handleUpdateBreakoutUsers(msg)
case msg: MeetingTimeRemainingUpdate => handleMeetingTimeRemainingUpdate(msg)
case msg: MeetingTimeRemainingUpdate => handleMeetingTimeRemainingUpdate(msg)
case _ => // do nothing
case _ => // do nothing
}
// Breakout
private def handleBreakoutRoomStarted(msg: BreakoutRoomStartedOutMessage) {
val payload = new BreakoutRoomPayload(msg.meetingId, msg.breakout.breakoutId, msg.breakout.name)
val payload = new BreakoutRoomPayload(msg.parentMeetingId, msg.breakout.meetingId, msg.breakout.externalMeetingId, msg.breakout.name, msg.breakout.sequence)
val request = new BreakoutRoomStarted(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson)
}
private def handleBreakoutRoomEnded(msg: BreakoutRoomEndedOutMessage) {
val payload = new BreakoutRoomPayload(msg.meetingId, msg.breakoutId, "")
val payload = new BreakoutRoomPayload(msg.parentMeetingId, msg.meetingId, "", "", 0)
val request = new BreakoutRoomClosed(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson)
}
@ -66,7 +66,7 @@ class JsonMessageSenderActor(val service: MessageSender)
private def handleUpdateBreakoutUsers(msg: UpdateBreakoutUsersOutMessage) {
val users = new java.util.ArrayList[BreakoutUserPayload]()
msg.users.foreach(x => users.add(new BreakoutUserPayload(x.id, x.name)))
val payload = new UpdateBreakoutUsersPayload(msg.meetingId, msg.breakoutId, users)
val payload = new UpdateBreakoutUsersPayload(msg.parentMeetingId, msg.breakoutMeetingId, users)
val request = new UpdateBreakoutUsers(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson())
}
@ -85,29 +85,29 @@ class JsonMessageSenderActor(val service: MessageSender)
private def handleBreakoutRoomsList(msg: BreakoutRoomsListOutMessage) {
val rooms = new java.util.ArrayList[BreakoutRoomPayload]()
msg.rooms.foreach(r => rooms.add(new BreakoutRoomPayload(msg.meetingId, r.breakoutId, r.name)))
msg.rooms.foreach(r => rooms.add(new BreakoutRoomPayload(msg.meetingId, r.meetingId, r.externalMeetingId, r.name, r.sequence)))
val payload = new BreakoutRoomsListPayload(msg.meetingId, rooms, msg.roomsReady)
val request = new BreakoutRoomsList(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson())
}
private def handleCreateBreakoutRoom(msg: CreateBreakoutRoom) {
val payload = new CreateBreakoutRoomRequestPayload(msg.room.breakoutId, msg.room.parentId, msg.room.name,
msg.room.voiceConfId, msg.room.viewerPassword, msg.room.moderatorPassword,
msg.room.durationInMinutes, msg.room.defaultPresentationURL, msg.room.record)
val payload = new CreateBreakoutRoomRequestPayload(msg.room.breakoutMeetingId, msg.room.parentId, msg.room.name,
msg.room.sequence, msg.room.voiceConfId, msg.room.viewerPassword, msg.room.moderatorPassword,
msg.room.durationInMinutes, msg.room.sourcePresentationId, msg.room.sourcePresentationSlide, msg.room.record)
val request = new CreateBreakoutRoomRequest(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson())
}
private def handleEndBreakoutRoom(msg: EndBreakoutRoom) {
val payload = new EndBreakoutRoomRequestPayload(msg.breakoutId)
val payload = new EndBreakoutRoomRequestPayload(msg.breakoutMeetingId)
val request = new EndBreakoutRoomRequest(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson())
}
def handleBreakoutRoomJoinURL(msg: BreakoutRoomJoinURLOutMessage) {
val payload = new BreakoutRoomJoinURLPayload(msg.meetingId,
msg.breakoutId, msg.userId, msg.joinURL)
val payload = new BreakoutRoomJoinURLPayload(msg.parentMeetingId,
msg.breakoutMeetingId, msg.userId, msg.joinURL)
val request = new BreakoutRoomJoinURL(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson)
}

View File

@ -12,17 +12,17 @@ import org.bigbluebutton.core.apps.CaptionApp
import org.bigbluebutton.core.apps.CaptionModel
class LiveMeeting(val mProps: MeetingProperties,
val eventBus: IncomingEventBus,
val outGW: OutMessageGateway,
val chatModel: ChatModel,
val layoutModel: LayoutModel,
val meetingModel: MeetingModel,
val usersModel: UsersModel,
val pollModel: PollModel,
val wbModel: WhiteboardModel,
val presModel: PresentationModel,
val breakoutModel: BreakoutRoomModel,
val captionModel: CaptionModel)(implicit val context: ActorContext)
val eventBus: IncomingEventBus,
val outGW: OutMessageGateway,
val chatModel: ChatModel,
val layoutModel: LayoutModel,
val meetingModel: MeetingModel,
val usersModel: UsersModel,
val pollModel: PollModel,
val wbModel: WhiteboardModel,
val presModel: PresentationModel,
val breakoutModel: BreakoutRoomModel,
val captionModel: CaptionModel)(implicit val context: ActorContext)
extends UsersApp with PresentationApp
with LayoutApp with ChatApp with WhiteboardApp with PollApp
with BreakoutRoomApp with CaptionApp {
@ -56,7 +56,7 @@ class LiveMeeting(val mProps: MeetingProperties,
}
def startCheckingIfWeNeedToEndVoiceConf() {
if (usersModel.numWebUsers == 0) {
if (usersModel.numWebUsers == 0 && !mProps.isBreakout) {
meetingModel.lastWebUserLeft()
log.debug("MonitorNumberOfWebUsers started for meeting [" + mProps.meetingID + "]")
}
@ -117,7 +117,7 @@ class LiveMeeting(val mProps: MeetingProperties,
meetingModel.meetingHasEnded
/**
* See if this meeting has breakout rooms. If so, we also need to end them.
* Check if this meeting has breakout rooms. If so, we also need to end them.
*/
handleEndAllBreakoutRooms(new EndAllBreakoutRooms(msg.meetingId))

View File

@ -37,8 +37,8 @@ class MeetingActorInternal(val mProps: MeetingProperties,
if (mProps.isBreakout) {
// This is a breakout room. Inform our parent meeting that we have been successfully created.
eventBus.publish(BigBlueButtonEvent(
mProps.externalMeetingID,
BreakoutRoomCreated(mProps.externalMeetingID, mProps.meetingID)))
mProps.parentMeetingID,
BreakoutRoomCreated(mProps.parentMeetingID, mProps.meetingID)))
}
def receive = {

View File

@ -4,14 +4,15 @@ import org.bigbluebutton.core.api.Permissions
import java.util.concurrent.TimeUnit
case object StopMeetingActor
case class MeetingProperties(meetingID: String, externalMeetingID: String, meetingName: String, recorded: Boolean,
voiceBridge: String, deskshareBridge: String, duration: Int, autoStartRecording: Boolean,
allowStartStopRecording: Boolean, moderatorPass: String, viewerPass: String, createTime: Long,
createDate: String, red5DeskShareIP: String, red5DeskShareApp: String, isBreakout: Boolean)
case class MeetingProperties(meetingID: String, externalMeetingID: String, parentMeetingID: String, meetingName: String,
recorded: Boolean, voiceBridge: String, deskshareBridge: String, duration: Int,
autoStartRecording: Boolean, allowStartStopRecording: Boolean, moderatorPass: String,
viewerPass: String, createTime: Long, createDate: String,
red5DeskShareIP: String, red5DeskShareApp: String, isBreakout: Boolean, sequence: Int)
case class MeetingExtensionProp(maxExtensions: Int = 2, numExtensions: Int = 0, extendByMinutes: Int = 20,
sendNotice: Boolean = true, sent15MinNotice: Boolean = false,
sent10MinNotice: Boolean = false, sent5MinNotice: Boolean = false)
sendNotice: Boolean = true, sent15MinNotice: Boolean = false,
sent10MinNotice: Boolean = false, sent5MinNotice: Boolean = false)
class MeetingModel {
private var audioSettingsInited = false

View File

@ -44,7 +44,6 @@ class MessageSenderActor(val service: MessageSender)
extends Actor with ActorLogging {
val encoder = new ToJsonEncoder()
def receive = {
case msg: UserEjectedFromMeeting => handleUserEjectedFromMeeting(msg)
case msg: GetChatHistoryReply => handleGetChatHistoryReply(msg)

View File

@ -4,7 +4,7 @@ import spray.json.{ DefaultJsonProtocol, JsValue, JsString, DeserializationExcep
import org.bigbluebutton.core.api._
object UserMessagesProtocol extends DefaultJsonProtocol {
/*
/*
implicit object RoleJsonFormat extends JsonFormat[Role.RoleType] {
def write(obj: Role.RoleType): JsValue = JsString(obj.toString)
@ -20,21 +20,20 @@ object UserMessagesProtocol extends DefaultJsonProtocol {
def read(json: JsValue): MessageType.MessageType = json match {
case JsString(str) => MessageType.withName(str)
case _ => throw new DeserializationException("Enum string expected")
case _ => throw new DeserializationException("Enum string expected")
}
}
implicit val breakoutRoomInPayloadFormat = jsonFormat2(BreakoutRoomInPayload)
implicit val createBreakoutRoomsFormat = jsonFormat4(CreateBreakoutRooms)
implicit val breakoutRoomInPayloadFormat = jsonFormat3(BreakoutRoomInPayload)
implicit val createBreakoutRoomsFormat = jsonFormat5(CreateBreakoutRooms)
implicit val breakoutRoomsListMessageFormat = jsonFormat1(BreakoutRoomsListMessage)
implicit val requestBreakoutJoinURLInMessageFormat = jsonFormat3(RequestBreakoutJoinURLInMessage)
implicit val requestBreakoutJoinURLInMessageFormat = jsonFormat4(RequestBreakoutJoinURLInMessage)
implicit val transferUserToMeetingRequestFormat = jsonFormat3(TransferUserToMeetingRequest)
implicit val endBreakoutRoomsFormat = jsonFormat1(EndAllBreakoutRooms)
implicit val inMsgHeaderFormat = jsonFormat1(InMessageHeader)
implicit val outMsgHeaderFormat = jsonFormat1(OutMsgHeader)
implicit val outMsgEnvelopeHeaderFormat = jsonFormat2(OutMsgEnvelopeHeader)
implicit val createBreakoutRoomOutMsgPayloadFormat = jsonFormat8(CreateBreakoutRoomOutMsgPayload)
implicit val createBreakoutRoomOutMsgPayloadFormat = jsonFormat11(CreateBreakoutRoomOutMsgPayload)
implicit val createBreakoutRoomOutMsgEnvelopePayloadFormat = jsonFormat2(CreateBreakoutRoomOutMsgEnvelopePayload)
implicit val createBreakoutRoomOutMsgEnvelopeFormat = jsonFormat2(CreateBreakoutRoomOutMsgEnvelope)
}

View File

@ -5,12 +5,9 @@ case class OutMsgEnvelopeHeader(`type`: MessageType.MessageType, address: String
trait OutMessage
case class CreateBreakoutRoomOutMsgEnvelope(header: OutMsgEnvelopeHeader,
payload: CreateBreakoutRoomOutMsgEnvelopePayload)
case class CreateBreakoutRoomOutMsgEnvelopePayload(header: OutMsgHeader,
payload: CreateBreakoutRoomOutMsgPayload)
case class CreateBreakoutRoomOutMsgPayload(breakoutId: String, name: String, parentId: String,
voiceConfId: String, durationInMinutes: Int,
moderatorPassword: String, viewerPassword: String,
defaultPresentationUrl: String)
case class CreateBreakoutRoomOutMsgEnvelope(header: OutMsgEnvelopeHeader, payload: CreateBreakoutRoomOutMsgEnvelopePayload)
case class CreateBreakoutRoomOutMsgEnvelopePayload(header: OutMsgHeader, payload: CreateBreakoutRoomOutMsgPayload)
case class CreateBreakoutRoomOutMsgPayload(meetingId: String, parentId: String, name: String,
voiceConfId: String, moderatorPassword: String, viewerPassword: String,
durationInMinutes: Int, sourcePresentationId: String, sourcePresentationSlide: Int,
record: Boolean, sequence: Int)

View File

@ -86,6 +86,7 @@ class RecorderActor(val recorder: RecorderApplication)
ev.setTimestamp(TimestampGenerator.generateTimestamp);
ev.setMeetingId(msg.meetingID);
ev.setSender(message.get("fromUsername"));
ev.setSenderId(message.get("fromUserID"));
ev.setMessage(message.get("message"));
ev.setColor(message.get("fromColor"));
recorder.record(msg.meetingID, ev);
@ -196,6 +197,7 @@ class RecorderActor(val recorder: RecorderApplication)
val ev = new ParticipantJoinRecordEvent();
ev.setTimestamp(TimestampGenerator.generateTimestamp);
ev.setUserId(msg.user.userID);
ev.setExternalUserId(msg.user.externUserID);
ev.setName(msg.user.name);
ev.setMeetingId(msg.meetingID);
ev.setRole(msg.user.role.toString());

View File

@ -6,6 +6,8 @@ object Constants {
val PAYLOAD = "payload"
val MEETING_ID = "meeting_id"
val EXTERNAL_MEETING_ID = "external_meeting_id"
val PARENT_MEETING_ID = "parent_meeting_id"
val IS_BREAKOUT = "is_breakout";
val TIMESTAMP = "timestamp"
val CURRENT_TIME = "current_time"
val USER_ID = "userid"

View File

@ -42,17 +42,14 @@ case class LockSetting(meetingID: String, locked: Boolean, settings: Map[String,
// Sent by user to request the breakout rooms list of a room
case class BreakoutRoomsListMessage(meetingId: String) extends InMessage
// Sent by user to request creation of breakout rooms
case class CreateBreakoutRooms(meetingId: String, durationInMinutes: Int, record: Boolean,
rooms: Vector[BreakoutRoomInPayload]) extends InMessage
case class BreakoutRoomInPayload(name: String, users: Vector[String])
case class CreateBreakoutRooms(meetingId: String, durationInMinutes: Int, record: Boolean, redirectOnJoin: Boolean, rooms: Vector[BreakoutRoomInPayload]) extends InMessage
case class BreakoutRoomInPayload(name: String, sequence: Int, users: Vector[String])
// Sent by user to request for a join URL in order to be able to join a breakout room
case class RequestBreakoutJoinURLInMessage(meetingId: String, breakoutId: String,
userId: String) extends InMessage
case class RequestBreakoutJoinURLInMessage(meetingId: String, breakoutMeetingId: String, userId: String, redirect: Boolean) extends InMessage
// Sent by breakout actor to tell meeting actor that breakout room has been created.
case class BreakoutRoomCreated(meetingId: String, breakoutRoomId: String) extends InMessage
// Sent by breakout actor to tell meeting actor the list of users in the breakout room.
case class BreakoutRoomUsersUpdate(meetingId: String, breakoutId: String,
users: Vector[BreakoutUser]) extends InMessage
case class BreakoutRoomUsersUpdate(meetingId: String, breakoutMeetingId: String, users: Vector[BreakoutUser]) extends InMessage
// Send by internal actor to tell the breakout actor to send it's list of users to the main meeting actor.
case class SendBreakoutUsersUpdate(meetingId: String) extends InMessage
// Sent by user to request ending all the breakout rooms
@ -76,9 +73,9 @@ case class GetLockSettings(meetingID: String, userId: String) extends InMessage
/////////////////////////////////////////////////////////////////////////////////
case class ValidateAuthToken(meetingID: String, userId: String, token: String,
correlationId: String, sessionId: String) extends InMessage
correlationId: String, sessionId: String) extends InMessage
case class RegisterUser(meetingID: String, userID: String, name: String, role: Role,
extUserID: String, authToken: String, avatarURL: String) extends InMessage
extUserID: String, authToken: String, avatarURL: String) extends InMessage
case class UserJoining(meetingID: String, userID: String, authToken: String) extends InMessage
case class UserLeaving(meetingID: String, userID: String, sessionId: String) extends InMessage
case class GetUsers(meetingID: String, requesterID: String) extends InMessage
@ -100,9 +97,9 @@ case class GetChatHistoryRequest(meetingID: String, requesterID: String, replyTo
case class SendPublicMessageRequest(meetingID: String, requesterID: String, message: Map[String, String]) extends InMessage
case class SendPrivateMessageRequest(meetingID: String, requesterID: String, message: Map[String, String]) extends InMessage
case class UserConnectedToGlobalAudio(meetingID: String, /** Not used. Just to satisfy trait **/ voiceConf: String,
userid: String, name: String) extends InMessage
userid: String, name: String) extends InMessage
case class UserDisconnectedFromGlobalAudio(meetingID: String, /** Not used. Just to satisfy trait **/ voiceConf: String,
userid: String, name: String) extends InMessage
userid: String, name: String) extends InMessage
///////////////////////////////////////////////////////////////////////////////////////
// Layout
@ -111,7 +108,7 @@ case class UserDisconnectedFromGlobalAudio(meetingID: String, /** Not used. Just
case class GetCurrentLayoutRequest(meetingID: String, requesterID: String) extends InMessage
case class SetLayoutRequest(meetingID: String, requesterID: String, layoutID: String) extends InMessage
case class LockLayoutRequest(meetingID: String, setById: String, lock: Boolean, viewersOnly: Boolean,
layout: Option[String]) extends InMessage
layout: Option[String]) extends InMessage
case class BroadcastLayoutRequest(meetingID: String, requesterID: String, layout: String) extends InMessage
//////////////////////////////////////////////////////////////////////////////////////
@ -123,19 +120,19 @@ case class RemovePresentation(meetingID: String, presentationID: String) extends
case class GetPresentationInfo(meetingID: String, requesterID: String, replyTo: String) extends InMessage
case class SendCursorUpdate(meetingID: String, xPercent: Double, yPercent: Double) extends InMessage
case class ResizeAndMoveSlide(meetingID: String, xOffset: Double, yOffset: Double,
widthRatio: Double, heightRatio: Double) extends InMessage
widthRatio: Double, heightRatio: Double) extends InMessage
case class GotoSlide(meetingID: String, page: String) extends InMessage
case class SharePresentation(meetingID: String, presentationID: String, share: Boolean) extends InMessage
case class GetSlideInfo(meetingID: String, requesterID: String, replyTo: String) extends InMessage
case class PreuploadedPresentations(meetingID: String, presentations: Seq[Presentation]) extends InMessage
case class PresentationConversionUpdate(meetingID: String, messageKey: String, code: String,
presentationId: String, presName: String) extends InMessage
presentationId: String, presName: String) extends InMessage
case class PresentationPageCountError(meetingID: String, messageKey: String, code: String, presentationId: String,
numberOfPages: Int, maxNumberPages: Int, presName: String) extends InMessage
numberOfPages: Int, maxNumberPages: Int, presName: String) extends InMessage
case class PresentationSlideGenerated(meetingID: String, messageKey: String, code: String, presentationId: String,
numberOfPages: Int, pagesCompleted: Int, presName: String) extends InMessage
numberOfPages: Int, pagesCompleted: Int, presName: String) extends InMessage
case class PresentationConversionCompleted(meetingID: String, messageKey: String, code: String,
presentation: Presentation) extends InMessage
presentation: Presentation) extends InMessage
/////////////////////////////////////////////////////////////////////////////////////
// Polling
@ -164,9 +161,9 @@ case class MuteUserRequest(meetingID: String, requesterID: String, userID: Strin
case class LockUserRequest(meetingID: String, requesterID: String, userID: String, lock: Boolean) extends InMessage
case class EjectUserFromVoiceRequest(meetingID: String, userId: String, ejectedBy: String) extends InMessage
case class VoiceUserJoinedMessage(meetingID: String, user: String, voiceConfId: String,
callerIdNum: String, callerIdName: String, muted: Boolean, talking: Boolean) extends InMessage
callerIdNum: String, callerIdName: String, muted: Boolean, talking: Boolean) extends InMessage
case class UserJoinedVoiceConfMessage(voiceConfId: String, voiceUserId: String, userId: String, externUserId: String,
callerIdName: String, callerIdNum: String, muted: Boolean, talking: Boolean, avatarURL: String, listenOnly: Boolean) extends InMessage
callerIdName: String, callerIdNum: String, muted: Boolean, talking: Boolean, avatarURL: String, listenOnly: Boolean) extends InMessage
case class UserLeftVoiceConfMessage(voiceConfId: String, voiceUserId: String) extends InMessage
case class UserLockedInVoiceConfMessage(voiceConfId: String, voiceUserId: String, locked: Boolean) extends InMessage
case class UserMutedInVoiceConfMessage(voiceConfId: String, voiceUserId: String, muted: Boolean) extends InMessage

View File

@ -14,8 +14,8 @@ case class VoiceRecordingStarted(meetingID: String, recorded: Boolean, recording
case class VoiceRecordingStopped(meetingID: String, recorded: Boolean, recordingFile: String, timestamp: String, confNum: String) extends IOutMessage
case class RecordingStatusChanged(meetingID: String, recorded: Boolean, userId: String, recording: Boolean) extends IOutMessage
case class GetRecordingStatusReply(meetingID: String, recorded: Boolean, userId: String, recording: Boolean) extends IOutMessage
case class MeetingCreated(meetingID: String, externalMeetingID: String, recorded: Boolean, name: String,
voiceBridge: String, duration: Int, moderatorPass: String, viewerPass: String, createTime: Long, createDate: String) extends IOutMessage
case class MeetingCreated(meetingID: String, externalMeetingID: String, parentMeetingID: String, recorded: Boolean, name: String,
voiceBridge: String, duration: Int, moderatorPass: String, viewerPass: String, createTime: Long, createDate: String, isBreakout: Boolean) extends IOutMessage
case class MeetingMuted(meetingID: String, recorded: Boolean, meetingMuted: Boolean) extends IOutMessage
case class MeetingEnded(meetingID: String, recorded: Boolean, voiceBridge: String) extends IOutMessage
case class MeetingState(meetingID: String, recorded: Boolean, userId: String, permissions: Permissions, meetingMuted: Boolean) extends IOutMessage
@ -30,17 +30,17 @@ case object IsAliveMessage extends IOutMessage
// Breakout Rooms
case class BreakoutRoomsListOutMessage(meetingId: String, rooms: Vector[BreakoutRoomBody], roomsReady: Boolean) extends IOutMessage
case class CreateBreakoutRoom(meetingId: String, room: BreakoutRoomOutPayload) extends IOutMessage
case class EndBreakoutRoom(breakoutId: String) extends IOutMessage
case class BreakoutRoomOutPayload(breakoutId: String, name: String, parentId: String,
case class EndBreakoutRoom(breakoutMeetingId: String) extends IOutMessage
case class BreakoutRoomOutPayload(breakoutMeetingId: String, name: String, parentId: String, sequence: Integer,
voiceConfId: String, durationInMinutes: Int, moderatorPassword: String, viewerPassword: String,
defaultPresentationURL: String, record: Boolean)
case class BreakoutRoomJoinURLOutMessage(meetingId: String, recorded: Boolean, breakoutId: String, userId: String, joinURL: String) extends IOutMessage
case class BreakoutRoomStartedOutMessage(meetingId: String, recorded: Boolean, breakout: BreakoutRoomBody) extends IOutMessage
case class BreakoutRoomBody(name: String, breakoutId: String)
case class UpdateBreakoutUsersOutMessage(meetingId: String, recorded: Boolean, breakoutId: String, users: Vector[BreakoutUser]) extends IOutMessage
sourcePresentationId: String, sourcePresentationSlide: Int, record: Boolean)
case class BreakoutRoomJoinURLOutMessage(parentMeetingId: String, recorded: Boolean, breakoutMeetingId: String, userId: String, joinURL: String) extends IOutMessage
case class BreakoutRoomStartedOutMessage(parentMeetingId: String, recorded: Boolean, breakout: BreakoutRoomBody) extends IOutMessage
case class BreakoutRoomBody(name: String, externalMeetingId: String, meetingId: String, sequence: Int)
case class UpdateBreakoutUsersOutMessage(parentMeetingId: String, recorded: Boolean, breakoutMeetingId: String, users: Vector[BreakoutUser]) extends IOutMessage
case class MeetingTimeRemainingUpdate(meetingId: String, recorded: Boolean, timeRemaining: Int) extends IOutMessage
case class BreakoutRoomsTimeRemainingUpdateOutMessage(meetingId: String, recorded: Boolean, timeRemaining: Int) extends IOutMessage
case class BreakoutRoomEndedOutMessage(meetingId: String, breakoutId: String) extends IOutMessage
case class BreakoutRoomEndedOutMessage(parentMeetingId: String, meetingId: String) extends IOutMessage
// Permissions
case class PermissionsSettingInitialized(meetingID: String, permissions: Permissions, applyTo: Array[UserVO]) extends IOutMessage

View File

@ -20,18 +20,11 @@ trait BreakoutRoomApp extends SystemConfiguration {
val outGW: OutMessageGateway
val eventBus: IncomingEventBus
def getDefaultPresentationURL(): String = {
var presURL = bbbWebDefaultPresentationURL
val page = presModel.getCurrentPage()
page foreach { p =>
presURL = BreakoutRoomsUtil.fromSWFtoPDF(p.swfUri)
}
presURL
}
def handleBreakoutRoomsList(msg: BreakoutRoomsListMessage) {
val breakoutRooms = breakoutModel.getRooms().toVector map { r => new BreakoutRoomBody(r.name, r.id) }
outGW.send(new BreakoutRoomsListOutMessage(mProps.meetingID, breakoutRooms, breakoutModel.pendingRoomsNumber == 0 && breakoutRooms.length > 0));
val breakoutRooms = breakoutModel.getRooms().toVector map { r => new BreakoutRoomBody(r.name, r.externalMeetingId, r.id, r.sequence) }
val roomsReady = breakoutModel.pendingRoomsNumber == 0 && breakoutRooms.length > 0
log.info("Sending breakout rooms list to {} with containing {} room(s)", mProps.meetingID, breakoutRooms.length)
outGW.send(new BreakoutRoomsListOutMessage(mProps.meetingID, breakoutRooms, roomsReady))
}
def handleCreateBreakoutRooms(msg: CreateBreakoutRooms) {
@ -40,53 +33,65 @@ trait BreakoutRoomApp extends SystemConfiguration {
log.warning("CreateBreakoutRooms event received while {} are pending to be created for meeting {}", breakoutModel.pendingRoomsNumber, mProps.meetingID)
return
}
if (breakoutModel.getNumberOfRooms() > 0) {
log.warning("CreateBreakoutRooms event received while {} breakout rooms running for meeting {}", breakoutModel.getNumberOfRooms(), mProps.meetingID)
return
}
var i = 0
// in very rare cases the presentation conversion generates an error, what should we do?
// those cases where default.pdf is deleted from the whiteboard
val sourcePresentationId = if (!presModel.getCurrentPresentation().isEmpty) presModel.getCurrentPresentation().get.id else "blank"
val sourcePresentationSlide = if (!presModel.getCurrentPage().isEmpty) presModel.getCurrentPage().get.num else 0
breakoutModel.pendingRoomsNumber = msg.rooms.length;
breakoutModel.redirectOnJoin = msg.redirectOnJoin;
for (room <- msg.rooms) {
i += 1
val presURL = bbbWebDefaultPresentationURL
val breakoutMeetingId = BreakoutRoomsUtil.createMeetingId(mProps.meetingID, i)
val breakoutMeetingId = BreakoutRoomsUtil.createMeetingIds(mProps.meetingID, i)
val voiceConfId = BreakoutRoomsUtil.createVoiceConfId(mProps.voiceBridge, i)
val r = breakoutModel.createBreakoutRoom(breakoutMeetingId, room.name, voiceConfId, room.users, presURL)
val p = new BreakoutRoomOutPayload(r.id, r.name, mProps.meetingID,
val r = breakoutModel.createBreakoutRoom(mProps.meetingID, breakoutMeetingId._1, breakoutMeetingId._2, room.name,
room.sequence, voiceConfId, room.users)
val p = new BreakoutRoomOutPayload(r.id, r.name, mProps.meetingID, r.sequence,
r.voiceConfId, msg.durationInMinutes, mProps.moderatorPass, mProps.viewerPass,
r.defaultPresentationURL, msg.record)
sourcePresentationId, sourcePresentationSlide, msg.record)
outGW.send(new CreateBreakoutRoom(mProps.meetingID, p))
}
meetingModel.breakoutRoomsdurationInMinutes = msg.durationInMinutes;
meetingModel.breakoutRoomsStartedOn = timeNowInSeconds;
}
def sendJoinURL(userId: String, breakoutId: String) {
def sendJoinURL(userId: String, externalMeetingId: String, redirect: Boolean) {
log.debug("Sending breakout meeting {} Join URL for user: {}", externalMeetingId, userId);
for {
user <- usersModel.getUser(userId)
apiCall = "join"
params = BreakoutRoomsUtil.joinParams(user.name, userId, true, breakoutId, mProps.moderatorPass, true)
params = BreakoutRoomsUtil.joinParams(user.name, userId, true, externalMeetingId, mProps.moderatorPass, redirect)
baseString = BreakoutRoomsUtil.createBaseString(params)
checksum = BreakoutRoomsUtil.calculateChecksum(apiCall, baseString, bbbWebSharedSecret)
joinURL = BreakoutRoomsUtil.createJoinURL(bbbWebAPI, apiCall, baseString, checksum)
} yield outGW.send(new BreakoutRoomJoinURLOutMessage(mProps.meetingID, mProps.recorded, breakoutId, userId, joinURL))
} yield outGW.send(new BreakoutRoomJoinURLOutMessage(mProps.meetingID, mProps.recorded, externalMeetingId, userId, joinURL))
}
def handleRequestBreakoutJoinURL(msg: RequestBreakoutJoinURLInMessage) {
sendJoinURL(msg.userId, msg.breakoutId)
sendJoinURL(msg.userId, msg.breakoutMeetingId, msg.redirect)
}
def handleBreakoutRoomCreated(msg: BreakoutRoomCreated) {
breakoutModel.pendingRoomsNumber -= 1
val room = breakoutModel.getBreakoutRoom(msg.breakoutRoomId)
room foreach { room =>
sendBreakoutRoomStarted(mProps.meetingID, room.name, room.id, room.voiceConfId)
sendBreakoutRoomStarted(room.parentRoomId, room.name, room.externalMeetingId, room.id, room.sequence, room.voiceConfId)
}
// We avoid sending invitation
// We postpone sending invitation until all breakout rooms have been created
if (breakoutModel.pendingRoomsNumber == 0) {
log.info("All breakout rooms created for meetingId={}", mProps.meetingID)
breakoutModel.getRooms().foreach { room =>
breakoutModel.getAssignedUsers(room.id) foreach { users =>
users.foreach { u =>
log.debug("## Sending Join URL for users: {}", u);
sendJoinURL(u, room.id)
log.debug("Sending Join URL for users");
sendJoinURL(u, room.externalMeetingId, breakoutModel.redirectOnJoin)
}
}
}
@ -94,8 +99,9 @@ trait BreakoutRoomApp extends SystemConfiguration {
}
}
def sendBreakoutRoomStarted(meetingId: String, breakoutName: String, breakoutId: String, voiceConfId: String) {
outGW.send(new BreakoutRoomStartedOutMessage(meetingId, mProps.recorded, new BreakoutRoomBody(breakoutName, breakoutId)))
def sendBreakoutRoomStarted(meetingId: String, breakoutName: String, externalMeetingId: String, breakoutMeetingId: String, sequence: Int, voiceConfId: String) {
log.info("Sending breakout room started {} for parent meeting {} ", breakoutMeetingId, meetingId);
outGW.send(new BreakoutRoomStartedOutMessage(meetingId, mProps.recorded, new BreakoutRoomBody(breakoutName, externalMeetingId, breakoutMeetingId, sequence)))
}
def handleBreakoutRoomEnded(msg: BreakoutRoomEnded) {
@ -104,16 +110,16 @@ trait BreakoutRoomApp extends SystemConfiguration {
}
def handleBreakoutRoomUsersUpdate(msg: BreakoutRoomUsersUpdate) {
breakoutModel.updateBreakoutUsers(msg.breakoutId, msg.users) foreach { room =>
outGW.send(new UpdateBreakoutUsersOutMessage(mProps.meetingID, mProps.recorded, msg.breakoutId, room.users))
breakoutModel.updateBreakoutUsers(msg.breakoutMeetingId, msg.users) foreach { room =>
outGW.send(new UpdateBreakoutUsersOutMessage(mProps.meetingID, mProps.recorded, msg.breakoutMeetingId, room.users))
}
}
def handleSendBreakoutUsersUpdate(msg: SendBreakoutUsersUpdate) {
val users = usersModel.getUsers().toVector
val breakoutUsers = users map { u => new BreakoutUser(u.externUserID, u.name) }
eventBus.publish(BigBlueButtonEvent(mProps.externalMeetingID,
new BreakoutRoomUsersUpdate(mProps.externalMeetingID, mProps.meetingID, breakoutUsers)))
eventBus.publish(BigBlueButtonEvent(mProps.parentMeetingID,
new BreakoutRoomUsersUpdate(mProps.parentMeetingID, mProps.meetingID, breakoutUsers)))
}
def handleTransferUserToMeeting(msg: TransferUserToMeetingRequest) {
@ -152,18 +158,18 @@ trait BreakoutRoomApp extends SystemConfiguration {
}
object BreakoutRoomsUtil {
def createMeetingId(id: String, index: Int): String = {
id.concat("-").concat(index.toString())
def createMeetingIds(id: String, index: Int): (String, String) = {
val timeStamp = System.currentTimeMillis()
val externalHash = DigestUtils.sha1Hex(id.concat("-").concat(timeStamp.toString()).concat("-").concat(index.toString()))
val externalId = externalHash.concat("-").concat(timeStamp.toString())
val internalId = DigestUtils.sha1Hex(externalId).concat("-").concat(timeStamp.toString())
(internalId, externalId)
}
def createVoiceConfId(id: String, index: Int): String = {
id.concat(index.toString())
}
def fromSWFtoPDF(swfURL: String): String = {
swfURL.replace("swf", "pdf")
}
def createJoinURL(webAPI: String, apiCall: String, baseString: String, checksum: String): String = {
var apiURL = if (webAPI.endsWith("/")) webAPI else webAPI.concat("/")
apiURL.concat(apiCall).concat("?").concat(baseString).concat("&checksum=").concat(checksum)
@ -180,13 +186,13 @@ object BreakoutRoomsUtil {
checksum(apiCall.concat(baseString).concat(sharedSecret))
}
def joinParams(username: String, userId: String, isBreakout: Boolean, breakoutId: String,
password: String, redirect: Boolean): mutable.Map[String, String] = {
def joinParams(username: String, userId: String, isBreakout: Boolean, breakoutMeetingId: String,
password: String, redirect: Boolean): mutable.Map[String, String] = {
val params = new collection.mutable.HashMap[String, String]
params += "fullName" -> urlEncode(username)
params += "userID" -> urlEncode(userId + "-" + breakoutId.substring(breakoutId.lastIndexOf("-") + 1));
params += "userID" -> urlEncode(userId + "-" + breakoutMeetingId.substring(breakoutMeetingId.lastIndexOf("-") + 1));
params += "isBreakout" -> urlEncode(isBreakout.toString())
params += "meetingID" -> urlEncode(breakoutId)
params += "meetingID" -> urlEncode(breakoutMeetingId)
params += "password" -> urlEncode(password)
params += "redirect" -> urlEncode(redirect.toString())
@ -224,18 +230,4 @@ object BreakoutRoomsUtil {
def urlEncode(s: String): String = {
URLEncoder.encode(s, "UTF-8");
}
//
//encodeURIComponent() -- Java encoding similiar to JavaScript encodeURIComponent
//
def encodeURIComponent(component: String): String = {
URLEncoder.encode(component, "UTF-8")
.replaceAll("\\%28", "(")
.replaceAll("\\%29", ")")
.replaceAll("\\+", "%20")
.replaceAll("\\%27", "'")
.replaceAll("\\%21", "!")
.replaceAll("\\%7E", "~")
}
}

View File

@ -1,16 +1,16 @@
package org.bigbluebutton.core.apps
import scala.collection.mutable.ArrayBuffer
import scala.collection.immutable.HashMap
import scala.Vector
case class BreakoutUser(id: String, name: String)
case class BreakoutRoom(id: String, name: String, voiceConfId: String,
assignedUsers: Vector[String], users: Vector[BreakoutUser], defaultPresentationURL: String)
case class BreakoutRoom(id: String, externalMeetingId: String, name: String, parentRoomId: String, sequence: Integer, voiceConfId: String,
assignedUsers: Vector[String], users: Vector[BreakoutUser])
class BreakoutRoomModel {
private var rooms = new collection.immutable.HashMap[String, BreakoutRoom]
var pendingRoomsNumber: Integer = 0
var redirectOnJoin: Boolean = false
def add(room: BreakoutRoom): BreakoutRoom = {
rooms += room.id -> room
@ -21,9 +21,9 @@ class BreakoutRoomModel {
rooms -= id
}
def createBreakoutRoom(id: String, name: String, voiceConfId: String,
assignedUsers: Vector[String], defaultPresentationURL: String): BreakoutRoom = {
val room = new BreakoutRoom(id, name, voiceConfId, assignedUsers, Vector(), defaultPresentationURL)
def createBreakoutRoom(parentRoomId: String, id: String, externalMeetingId: String, name: String, sequence: Integer, voiceConfId: String,
assignedUsers: Vector[String]): BreakoutRoom = {
val room = new BreakoutRoom(id, externalMeetingId, name, parentRoomId, sequence, voiceConfId, assignedUsers, Vector())
add(room)
}
@ -35,18 +35,21 @@ class BreakoutRoomModel {
rooms.values.toArray
}
def getAssignedUsers(breakoutId: String): Option[Vector[String]] = {
def getNumberOfRooms(): Int = {
rooms.size
}
def getAssignedUsers(breakoutMeetingId: String): Option[Vector[String]] = {
for {
room <- rooms.get(breakoutId)
room <- rooms.get(breakoutMeetingId)
} yield room.assignedUsers
}
def updateBreakoutUsers(breakoutId: String, users: Vector[BreakoutUser]): Option[BreakoutRoom] = {
def updateBreakoutUsers(breakoutMeetingId: String, users: Vector[BreakoutUser]): Option[BreakoutRoom] = {
for {
room <- rooms.get(breakoutId)
room <- rooms.get(breakoutMeetingId)
newroom = room.copy(users = users)
room2 = add(newroom)
} yield room2
}
}

View File

@ -94,16 +94,10 @@ trait PresentationApp {
}
def handleGotoSlide(msg: GotoSlide) {
// println("Received GotoSlide for meeting=[" + msg.meetingID + "] page=[" + msg.page + "]")
// println("*** Before change page ****")
// printPresentations
presModel.changePage(msg.page) foreach { page =>
// println("Switching page for meeting=[" + msg.meetingID + "] page=[" + page.id + "]")
log.debug("Switching page for meeting=[{}] page=[{}]", msg.meetingID, page.num);
outGW.send(new GotoSlideOutMsg(mProps.meetingID, mProps.recorded, page))
}
// println("*** After change page ****")
// printPresentations
usersModel.getCurrentPresenter() foreach { pres =>
handleStopPollRequest(StopPollRequest(mProps.meetingID, pres.userID))

View File

@ -29,6 +29,8 @@ object MeetingMessageToJsonConverter {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.EXTERNAL_MEETING_ID, msg.externalMeetingID)
payload.put(Constants.PARENT_MEETING_ID, msg.parentMeetingID)
payload.put(Constants.IS_BREAKOUT, msg.isBreakout)
payload.put(Constants.NAME, msg.name)
payload.put(Constants.RECORDED, msg.recorded)
payload.put(Constants.VOICE_CONF, msg.voiceBridge)
@ -145,8 +147,10 @@ object MeetingMessageToJsonConverter {
def breakoutRoomStartedOutMessageToJson(msg: BreakoutRoomStartedOutMessage): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put("meetingId", msg.meetingId)
payload.put("breakoutId", msg.breakout.breakoutId)
payload.put("meetingId", msg.breakout.meetingId)
payload.put("externalMeetingId", msg.breakout.externalMeetingId)
payload.put("parentMeetingId", msg.parentMeetingId)
payload.put("sequence", msg.breakout.sequence)
payload.put("name", msg.breakout.name)
val header = Util.buildHeader(BreakoutRoomStarted.NAME, None)
@ -155,8 +159,8 @@ object MeetingMessageToJsonConverter {
def breakoutRoomEndedOutMessageToJson(msg: BreakoutRoomEndedOutMessage): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put("parentMeetingId", msg.parentMeetingId)
payload.put("meetingId", msg.meetingId)
payload.put("breakoutId", msg.breakoutId)
val header = Util.buildHeader(BreakoutRoomClosed.NAME, None)
Util.buildJson(header, payload)
@ -164,8 +168,8 @@ object MeetingMessageToJsonConverter {
def breakoutRoomJoinURLOutMessageToJson(msg: BreakoutRoomJoinURLOutMessage): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put("meetingId", msg.meetingId)
payload.put("breakoutId", msg.breakoutId)
payload.put("parentMeetingId", msg.parentMeetingId)
payload.put("breakoutMeetingId", msg.breakoutMeetingId)
payload.put("userId", msg.userId)
payload.put("joinURL", msg.joinURL)
@ -175,8 +179,8 @@ object MeetingMessageToJsonConverter {
def updateBreakoutUsersOutMessageToJson(msg: UpdateBreakoutUsersOutMessage): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put("meetingId", msg.meetingId)
payload.put("breakoutId", msg.breakoutId)
payload.put("parentMeetingId", msg.parentMeetingId)
payload.put("breakoutMeetingId", msg.breakoutMeetingId)
payload.put("recorded", msg.recorded)
payload.put("users", msg.users.toArray)

View File

@ -4,6 +4,8 @@ trait AppsTestFixtures {
val meetingId = "testMeetingId"
val externalMeetingId = "testExternalMeetingId"
val parentMeetingId = "testParentMeetingId"
val sequence = 4
val meetingName = "test meeting"
val record = false
val voiceConfId = "85115"
@ -16,13 +18,15 @@ trait AppsTestFixtures {
val createTime = System.currentTimeMillis
val createDate = "Oct 26, 2015"
val isBreakout = false
val red5DeskShareIP = "127.0.0.1"
val red5DeskShareApp = "red5App"
val mProps = new MeetingProperties(meetingId, externalMeetingId,
val mProps = new MeetingProperties(meetingId, externalMeetingId, parentMeetingId,
meetingName, record,
voiceConfId, deskshareConfId,
durationInMinutes,
autoStartRecording, allowStartStopRecording,
moderatorPassword, viewerPassword,
createTime, createDate, isBreakout)
}
createTime, createDate, red5DeskShareIP, red5DeskShareApp,
isBreakout, sequence)
}

View File

@ -6,18 +6,11 @@ import org.bigbluebutton.core.UnitSpec
class BreakoutRoomsUtilSpec extends UnitSpec {
it should "return a pdfURL" in {
val baseURL = "http://localhost/pre1/page1."
val swfURL = baseURL + "swf"
val pdfURL = BreakoutRoomsUtil.fromSWFtoPDF(swfURL)
assert(pdfURL == baseURL + "pdf")
}
it should "return a meetingId" in {
val mainMeetingId = "abc-123"
val index = 1
val result = mainMeetingId.concat("-").concat(index.toString())
val breakoutMeetingId = BreakoutRoomsUtil.createMeetingId(mainMeetingId, index)
val breakoutMeetingId = BreakoutRoomsUtil.createMeetingIds(mainMeetingId, index)
assert(breakoutMeetingId == result)
}

View File

@ -47,7 +47,7 @@ libraryDependencies ++= {
"org.pegdown" % "pegdown" % "1.4.0",
"junit" % "junit" % "4.11",
"com.etaty.rediscala" %% "rediscala" % "1.4.0",
"commons-codec" % "commons-codec" % "1.8",
"commons-codec" % "commons-codec" % "1.10",
"joda-time" % "joda-time" % "2.3",
"com.google.code.gson" % "gson" % "1.7.1",
"redis.clients" % "jedis" % "2.1.0",

View File

@ -3,48 +3,54 @@ package org.bigbluebutton.messages;
import org.bigbluebutton.common.messages.IBigBlueButtonMessage;
public class CreateMeetingRequest implements IBigBlueButtonMessage {
public final static String NAME = "CreateMeetingRequest";
public final Header header;
public final CreateMeetingRequestPayload payload;
public CreateMeetingRequest(CreateMeetingRequestPayload payload) {
this.header = new Header(NAME);
this.payload = payload;
}
public static class CreateMeetingRequestPayload {
public final String id;
public final String externalId;
public final String name;
public final Boolean record;
public final String voiceConfId;
public final Integer durationInMinutes;
public final Boolean autoStartRecording;
public final Boolean allowStartStopRecording;
public final String moderatorPassword;
public final String viewerPassword;
public final Long createTime;
public final String createDate;
public final Boolean isBreakout;
public CreateMeetingRequestPayload(String id, String externalId, String name, Boolean record, String voiceConfId,
Integer duration, Boolean autoStartRecording,
Boolean allowStartStopRecording, String moderatorPass,
String viewerPass, Long createTime, String createDate, Boolean isBreakout) {
this.id = id;
this.externalId = externalId;
this.name = name;
this.record = record;
this.voiceConfId = voiceConfId;
this.durationInMinutes = duration;
this.autoStartRecording = autoStartRecording;
this.allowStartStopRecording = allowStartStopRecording;
this.moderatorPassword = moderatorPass;
this.viewerPassword = viewerPass;
this.createTime = createTime;
this.createDate = createDate;
this.isBreakout = isBreakout;
public final static String NAME = "CreateMeetingRequest";
public final Header header;
public final CreateMeetingRequestPayload payload;
public CreateMeetingRequest(CreateMeetingRequestPayload payload) {
this.header = new Header(NAME);
this.payload = payload;
}
public static class CreateMeetingRequestPayload {
public final String id;
public final String externalId;
public final String parentId;
public final String name;
public final Boolean record;
public final String voiceConfId;
public final Integer durationInMinutes;
public final Boolean autoStartRecording;
public final Boolean allowStartStopRecording;
public final String moderatorPassword;
public final String viewerPassword;
public final Long createTime;
public final String createDate;
public final Boolean isBreakout;
public final Integer sequence;
public CreateMeetingRequestPayload(String id, String externalId,
String parentId, String name, Boolean record,
String voiceConfId, Integer duration,
Boolean autoStartRecording, Boolean allowStartStopRecording,
String moderatorPass, String viewerPass, Long createTime,
String createDate, Boolean isBreakout, Integer sequence) {
this.id = id;
this.externalId = externalId;
this.parentId = parentId;
this.name = name;
this.record = record;
this.voiceConfId = voiceConfId;
this.durationInMinutes = duration;
this.autoStartRecording = autoStartRecording;
this.allowStartStopRecording = allowStartStopRecording;
this.moderatorPassword = moderatorPass;
this.viewerPassword = viewerPass;
this.createTime = createTime;
this.createDate = createDate;
this.isBreakout = isBreakout;
this.sequence = sequence;
}
}
}
}

View File

@ -20,14 +20,14 @@ package org.bigbluebutton.messages.payload;
public class BreakoutRoomJoinURLPayload {
public final String meetingId;
public final String breakoutId;
public final String parentMeetingId;
public final String breakoutMeetingId;
public final String userId;
public final String joinURL;
public BreakoutRoomJoinURLPayload(String meetingId, String breakoutId, String userId, String joinURL) {
this.meetingId = meetingId;
this.breakoutId = breakoutId;
public BreakoutRoomJoinURLPayload(String parentMeetingId, String breakoutMeetingId, String userId, String joinURL) {
this.parentMeetingId = parentMeetingId;
this.breakoutMeetingId = breakoutMeetingId;
this.userId = userId;
this.joinURL = joinURL;
}

View File

@ -2,13 +2,18 @@ package org.bigbluebutton.messages.payload;
public class BreakoutRoomPayload {
public final String meetingId;
public final String breakoutId;
public final String name;
public final String parentMeetingId;
public final String meetingId;
public final String externalMeetingId;
public final String name;
public final Integer sequence;
public BreakoutRoomPayload(String meetingId, String breakoutId, String name) {
this.meetingId = meetingId;
this.breakoutId = breakoutId;
this.name = name;
}
public BreakoutRoomPayload(String parentMeetingId, String meetingId,
String externalMeetingId, String name, Integer sequence) {
this.parentMeetingId = parentMeetingId;
this.meetingId = meetingId;
this.externalMeetingId = externalMeetingId;
this.name = name;
this.sequence = sequence;
}
}

View File

@ -3,13 +3,16 @@ package org.bigbluebutton.messages.payload;
import java.util.ArrayList;
public class BreakoutRoomRequestPayload {
// Name of the breakout room
public final String name;
// List of user ids to assign to the breakout room
public final ArrayList<String> users;
public BreakoutRoomRequestPayload(String name, ArrayList<String> users) {
this.name = name;
this.users = users;
}
// Name of the breakout room
public final String name;
// Sequence of the breakout room
public final Integer sequence;
// List of user ids to assign to the breakout room
public final ArrayList<String> users;
public BreakoutRoomRequestPayload(String name, Integer sequence, ArrayList<String> users) {
this.name = name;
this.sequence = sequence;
this.users = users;
}
}

View File

@ -1,27 +1,33 @@
package org.bigbluebutton.messages.payload;
public class CreateBreakoutRoomRequestPayload {
public final String breakoutId;
public final String parentId; // The main meeting internal id
public final String name; // The name of the breakout room
public final String voiceConfId; // The voice conference id
public final String viewerPassword;
public final String moderatorPassword;
public final Integer durationInMinutes; // The duration of the breakout room
public final String defaultPresentationURL;
public final Boolean record;
public CreateBreakoutRoomRequestPayload(String breakoutId, String parentId, String name,
String voiceConfId, String viewerPassword, String moderatorPassword,
Integer duration, String defaultPresentationURL, Boolean record) {
this.breakoutId = breakoutId;
this.parentId = parentId;
this.name = name;
this.voiceConfId = voiceConfId;
this.viewerPassword = viewerPassword;
this.moderatorPassword = moderatorPassword;
this.durationInMinutes = duration;
this.defaultPresentationURL = defaultPresentationURL;
this.record = record;
}
public final String breakoutMeetingId;
public final String parentMeetingId; // The main meeting internal id
public final String name; // The name of the breakout room
public final Integer sequence; // The sequnce number of the breakout room
public final String voiceConfId; // The voice conference id
public final String viewerPassword;
public final String moderatorPassword;
public final Integer durationInMinutes; // The duration of the breakout room
public final String sourcePresentationId;
public final Integer sourcePresentationSlide;
public final Boolean record;
public CreateBreakoutRoomRequestPayload(String meetingMeetingId, String parentMeetingId,
String name, Integer sequence, String voiceConfId, String viewerPassword,
String moderatorPassword, Integer duration,
String sourcePresentationId, Integer sourcePresentationSlide,
Boolean record) {
this.breakoutMeetingId = meetingMeetingId;
this.parentMeetingId = parentMeetingId;
this.name = name;
this.sequence = sequence;
this.voiceConfId = voiceConfId;
this.viewerPassword = viewerPassword;
this.moderatorPassword = moderatorPassword;
this.durationInMinutes = duration;
this.sourcePresentationId = sourcePresentationId;
this.sourcePresentationSlide = sourcePresentationSlide;
this.record = record;
}
}

View File

@ -3,21 +3,24 @@ package org.bigbluebutton.messages.payload;
import java.util.ArrayList;
public class CreateBreakoutRoomsRequestPayload {
// The main meeting internal id
public final String meetingId;
// The list of breakout rooms
public final ArrayList<BreakoutRoomRequestPayload> rooms;
// The duration of the breakout room
public final Integer durationInMinutes;
// Breakout rooms recording option
public final Boolean record;
// The main meeting internal id
public final String meetingId;
// The list of breakout rooms
public final ArrayList<BreakoutRoomRequestPayload> rooms;
// The duration of the breakout room
public final Integer durationInMinutes;
// Breakout rooms recording option
public final Boolean record;
// Creates join URL with redirect value true or false
public final Boolean redirectOnJoin;
public CreateBreakoutRoomsRequestPayload(String meetingId,
ArrayList<BreakoutRoomRequestPayload> breakoutRooms,
Integer duration, Boolean record) {
this.meetingId = meetingId;
this.rooms = breakoutRooms;
this.durationInMinutes = duration;
this.record = record;
}
public CreateBreakoutRoomsRequestPayload(String meetingId,
ArrayList<BreakoutRoomRequestPayload> breakoutRooms,
Integer duration, Boolean record, Boolean redirectOnJoin) {
this.meetingId = meetingId;
this.rooms = breakoutRooms;
this.durationInMinutes = duration;
this.record = record;
this.redirectOnJoin = redirectOnJoin;
}
}

View File

@ -2,14 +2,14 @@ package org.bigbluebutton.messages.payload;
public class ListenInOnBreakoutPayload {
public final String meetingId;
public final String targetMeetingId;
public final String userId;
public final String meetingId;
public final String targetMeetingId;
public final String userId;
public ListenInOnBreakoutPayload(String meetingId, String breakoutId,
String userId) {
this.meetingId = meetingId;
this.targetMeetingId = breakoutId;
this.userId = userId;
}
public ListenInOnBreakoutPayload(String meetingId, String targetMeetingId,
String userId) {
this.meetingId = meetingId;
this.targetMeetingId = targetMeetingId;
this.userId = userId;
}
}

View File

@ -2,13 +2,16 @@ package org.bigbluebutton.messages.payload;
public class RequestBreakoutJoinURLPayload {
public final String meetingId;
public final String breakoutId;
public final String userId;
public RequestBreakoutJoinURLPayload(String meetingId, String breakoutId, String userId) {
this.meetingId = meetingId;
this.breakoutId = breakoutId;
this.userId = userId;
}
public final String meetingId;
public final String breakoutMeetingId;
public final String userId;
public final Boolean redirect;
public RequestBreakoutJoinURLPayload(String meetingId,
String breakoutMeetingId, String userId, Boolean redirect) {
this.meetingId = meetingId;
this.breakoutMeetingId = breakoutMeetingId;
this.userId = userId;
this.redirect = redirect;
}
}

View File

@ -5,12 +5,12 @@ import java.util.ArrayList;
public class UpdateBreakoutUsersPayload {
public final ArrayList<BreakoutUserPayload> users;
public final String breakoutId;
public final String meetingId;
public final String breakoutMeetingId;
public final String parentMeetingId;
public UpdateBreakoutUsersPayload(String meetingId, String breakoutId, ArrayList<BreakoutUserPayload> users) {
this.meetingId = meetingId;
this.breakoutId = breakoutId;
public UpdateBreakoutUsersPayload(String meetingParentId, String breakoutMeetingId, ArrayList<BreakoutUserPayload> users) {
this.parentMeetingId = meetingParentId;
this.breakoutMeetingId = breakoutMeetingId;
this.users = users;
}
}

View File

@ -9,19 +9,22 @@ import com.google.gson.Gson;
public class CreateBreakoutRoomRequestTest {
@Test
public void testCreateBreakoutRoomRequest() {
String breakoutId = "abc123";
String breakoutId = "183f0bf3a0982a127bdb8161e0c44eb696b3e75c-1474984695664";
String parentId = "abc-123";
Integer durationInMinutes = 20;
String name = "Breakout room 1";
Integer sequence = 3;
String voiceConfId = "851153";
String viewerPassword = "vp";
String moderatorPassword = "mp";
String defaultPresentationURL = "http://localhost/foo.pdf";
String sourcePresentationId = "d2d9a672040fbde2a47a10bf6c37b6a4b5ae187f-1474984695907";
Integer sourePresentationSlide = 5;
Boolean record = false;
CreateBreakoutRoomRequestPayload payload =
new CreateBreakoutRoomRequestPayload(breakoutId, parentId, name, voiceConfId,
viewerPassword, moderatorPassword, durationInMinutes, defaultPresentationURL, record);
CreateBreakoutRoomRequestPayload payload = new CreateBreakoutRoomRequestPayload(
breakoutId, parentId, name, sequence, voiceConfId,
viewerPassword, moderatorPassword, durationInMinutes,
sourcePresentationId, sourePresentationSlide, record);
CreateBreakoutRoomRequest msg = new CreateBreakoutRoomRequest(payload);
Gson gson = new Gson();
String json = gson.toJson(msg);
@ -30,13 +33,15 @@ public class CreateBreakoutRoomRequestTest {
CreateBreakoutRoomRequest rxMsg = gson.fromJson(json, CreateBreakoutRoomRequest.class);
Assert.assertEquals(rxMsg.header.name, CreateBreakoutRoomRequest.NAME);
Assert.assertEquals(rxMsg.payload.breakoutId, breakoutId);
Assert.assertEquals(rxMsg.payload.breakoutMeetingId, breakoutId);
Assert.assertEquals(rxMsg.payload.name, name);
Assert.assertEquals(rxMsg.payload.sequence, sequence);
Assert.assertEquals(rxMsg.payload.voiceConfId, voiceConfId);
Assert.assertEquals(rxMsg.payload.viewerPassword, viewerPassword);
Assert.assertEquals(rxMsg.payload.moderatorPassword, moderatorPassword);
Assert.assertEquals(rxMsg.payload.durationInMinutes, durationInMinutes);
Assert.assertEquals(rxMsg.payload.defaultPresentationURL, defaultPresentationURL);
Assert.assertEquals(rxMsg.payload.sourcePresentationId, sourcePresentationId);
Assert.assertEquals(rxMsg.payload.sourcePresentationSlide, sourePresentationSlide);
Assert.assertEquals(rxMsg.payload.record, record);
}
}

View File

@ -15,23 +15,24 @@ public class CreateBreakoutRoomsRequestTest {
String meetingId = "abc123";
Integer durationInMinutes = 20;
Boolean record = true;
Boolean redirectOnJoin = false;
ArrayList<String> room1Users = new ArrayList<String>();
room1Users.add("Tidora"); room1Users.add("Nidora"); room1Users.add("Tinidora");
BreakoutRoomRequestPayload room1 = new BreakoutRoomRequestPayload("room1", room1Users);
BreakoutRoomRequestPayload room1 = new BreakoutRoomRequestPayload("room1", 1, room1Users);
ArrayList<String> room2Users = new ArrayList<String>();
room2Users.add("Jose"); room2Users.add("Wally"); room2Users.add("Paolo");
BreakoutRoomRequestPayload room2= new BreakoutRoomRequestPayload("room2", room2Users);
BreakoutRoomRequestPayload room2= new BreakoutRoomRequestPayload("room2", 2, room2Users);
ArrayList<String> room3Users = new ArrayList<String>();
room3Users.add("Alden"); room3Users.add("Yaya Dub");
BreakoutRoomRequestPayload room3= new BreakoutRoomRequestPayload("room3", room3Users);
BreakoutRoomRequestPayload room3= new BreakoutRoomRequestPayload("room3", 3, room3Users);
ArrayList<BreakoutRoomRequestPayload> rooms = new ArrayList<BreakoutRoomRequestPayload>();
rooms.add(room1); rooms.add(room2); rooms.add(room3);
CreateBreakoutRoomsRequestPayload payload = new CreateBreakoutRoomsRequestPayload(meetingId, rooms, durationInMinutes, record);
CreateBreakoutRoomsRequestPayload payload = new CreateBreakoutRoomsRequestPayload(meetingId, rooms, durationInMinutes, record, redirectOnJoin);
CreateBreakoutRoomsRequest msg = new CreateBreakoutRoomsRequest(payload);
Gson gson = new Gson();
String json = gson.toJson(msg);

View File

@ -12,6 +12,7 @@ public class CreateMeetingRequestTest {
public void testCreateMeetingRequest() {
String meetingId = "abc123";
String externalId = "extabc123";
String parentId = "";
Boolean record = false;
Integer durationInMinutes = 20;
String name = "Breakout room 1";
@ -19,16 +20,17 @@ public class CreateMeetingRequestTest {
Boolean autoStartRecording = false;
Boolean allowStartStopRecording = false;
Boolean isBreakout = true;
Integer sequence = 4;
String viewerPassword = "vp";
String moderatorPassword = "mp";
long createTime = System.currentTimeMillis();
String createDate = new Date(createTime).toString();
CreateMeetingRequestPayload payload =
new CreateMeetingRequestPayload(meetingId, externalId, name, record, voiceConfId,
durationInMinutes, autoStartRecording,
allowStartStopRecording, moderatorPassword,
viewerPassword, createTime, createDate, isBreakout);
CreateMeetingRequestPayload payload = new CreateMeetingRequestPayload(
meetingId, externalId, parentId, name, record, voiceConfId,
durationInMinutes, autoStartRecording, allowStartStopRecording,
moderatorPassword, viewerPassword, createTime, createDate,
isBreakout, sequence);
CreateMeetingRequest msg = new CreateMeetingRequest(payload);
Gson gson = new Gson();
String json = gson.toJson(msg);
@ -38,11 +40,14 @@ public class CreateMeetingRequestTest {
Assert.assertEquals(rxMsg.header.name, CreateMeetingRequest.NAME);
Assert.assertEquals(rxMsg.payload.id, meetingId);
Assert.assertEquals(rxMsg.payload.externalId, externalId);
Assert.assertEquals(rxMsg.payload.parentId, parentId);
Assert.assertEquals(rxMsg.payload.name, name);
Assert.assertEquals(rxMsg.payload.voiceConfId, voiceConfId);
Assert.assertEquals(rxMsg.payload.viewerPassword, viewerPassword);
Assert.assertEquals(rxMsg.payload.moderatorPassword, moderatorPassword);
Assert.assertEquals(rxMsg.payload.durationInMinutes, durationInMinutes);
Assert.assertEquals(rxMsg.payload.isBreakout, isBreakout);
Assert.assertEquals(rxMsg.payload.sequence, sequence);
}
}

View File

@ -44,7 +44,7 @@ libraryDependencies ++= {
// "org.pegdown" % "pegdown" % "1.4.0",
// "junit" % "junit" % "4.11",
// "com.etaty.rediscala" %% "rediscala" % "1.4.0",
"commons-codec" % "commons-codec" % "1.8",
"commons-codec" % "commons-codec" % "1.10",
"redis.clients" % "jedis" % "2.7.2",
// "org.apache.commons" % "commons-lang3" % "3.2",
"org.apache.commons" % "commons-pool2" % "2.3",

View File

@ -3,12 +3,11 @@ package org.bigbluebutton.red5.client;
import java.util.HashMap;
import java.util.Map;
import org.bigbluebutton.common.messages.ChatKeyUtil;
import org.bigbluebutton.common.messages.DeskShareNotifyViewersRTMPEventMessage;
import org.bigbluebutton.common.messages.DeskShareNotifyASingleViewerEventMessage;
import org.bigbluebutton.common.messages.DeskShareNotifyViewersRTMPEventMessage;
import org.bigbluebutton.red5.client.messaging.BroadcastClientMessage;
import org.bigbluebutton.red5.client.messaging.DirectClientMessage;
import org.bigbluebutton.red5.client.messaging.ConnectionInvokerService;
import org.bigbluebutton.red5.client.messaging.DirectClientMessage;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

View File

@ -44,7 +44,6 @@ import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class UserClientMessageSender {
private static Logger log = Red5LoggerFactory.getLogger(UserClientMessageSender.class, "bigbluebutton");
@ -543,8 +542,8 @@ public class UserClientMessageSender {
private void processBreakoutRoomJoinURL(BreakoutRoomJoinURL msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("meetingId", msg.payload.meetingId);
args.put("breakoutId", msg.payload.breakoutId);
args.put("parentMeetingId", msg.payload.parentMeetingId);
args.put("breakoutMeetingId", msg.payload.breakoutMeetingId);
args.put("userId", msg.payload.userId);
args.put("joinURL", msg.payload.joinURL);
@ -552,7 +551,7 @@ public class UserClientMessageSender {
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
DirectClientMessage m = new DirectClientMessage(msg.payload.meetingId, msg.payload.userId, "breakoutRoomJoinURL", message);
DirectClientMessage m = new DirectClientMessage(msg.payload.parentMeetingId, msg.payload.userId, "breakoutRoomJoinURL", message);
service.sendMessage(m);
}
@ -584,42 +583,44 @@ public class UserClientMessageSender {
private void processUpdateBreakoutUsers(UpdateBreakoutUsers msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("meetingId", msg.payload.meetingId);
args.put("breakoutId", msg.payload.breakoutId);
args.put("parentMeetingId", msg.payload.parentMeetingId);
args.put("breakoutMeetingId", msg.payload.breakoutMeetingId);
args.put("users", msg.payload.users);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
BroadcastClientMessage m = new BroadcastClientMessage(msg.payload.meetingId, "updateBreakoutUsers", message);
BroadcastClientMessage m = new BroadcastClientMessage(msg.payload.parentMeetingId, "updateBreakoutUsers", message);
service.sendMessage(m);
}
private void processBreakoutRoomStarted(BreakoutRoomStarted msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("breakoutId", msg.payload.breakoutId);
args.put("meetingId", msg.payload.meetingId);
args.put("breakoutMeetingId", msg.payload.meetingId);
args.put("parentMeetingId", msg.payload.parentMeetingId);
args.put("externalMeetingId", msg.payload.externalMeetingId);
args.put("sequence", msg.payload.sequence);
args.put("name", msg.payload.name);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
BroadcastClientMessage m = new BroadcastClientMessage(msg.payload.meetingId, "breakoutRoomStarted", message);
BroadcastClientMessage m = new BroadcastClientMessage(msg.payload.parentMeetingId, "breakoutRoomStarted", message);
service.sendMessage(m);
}
private void processBreakoutRoomClosed(BreakoutRoomClosed msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("breakoutId", msg.payload.breakoutId);
args.put("meetingId", msg.payload.meetingId);
args.put("breakoutMeetingId", msg.payload.meetingId);
args.put("parentMeetingId", msg.payload.parentMeetingId);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
BroadcastClientMessage m = new BroadcastClientMessage(msg.payload.meetingId, "breakoutRoomClosed", message);
BroadcastClientMessage m = new BroadcastClientMessage(msg.payload.parentMeetingId, "breakoutRoomClosed", message);
service.sendMessage(m);
}
}

View File

@ -1,6 +1,5 @@
package org.bigbluebutton.red5.client;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

View File

@ -18,9 +18,6 @@
*/
package org.bigbluebutton.red5.service;
import java.util.HashMap;
import java.util.Map;
import org.bigbluebutton.red5.BigBlueButtonSession;
import org.bigbluebutton.red5.Constants;
import org.bigbluebutton.red5.pubsub.MessagePublisher;

View File

@ -1061,6 +1061,10 @@ EmojiGrid {
horizontalGap: 6;
}
.breakoutRoomUserWindowHeadingStyle {
fontWeight: bold;
}
.breakoutRoomSettingTitleStyle {
fontFamily: Arial;
fontSize: 20;

View File

@ -23,8 +23,6 @@
<property name="BROADCAST" value="BroadcastModule" />
<property name="CHAT" value="ChatModule" />
<property name="PRESENT" value="PresentModule" />
<property name="DESKSHARE" value="DeskShareModule" />
<property name="DESKSHARE_SA" value="DeskshareStandalone" />
<property name="SCREENSHARE" value="ScreenshareModule" />
<property name="SCREENSHARE_SA" value="ScreenshareStandalone" />
<property name="CAM_PREVIEW_SA" value="WebcamPreviewStandalone" />
@ -211,16 +209,6 @@
<build-module src="${SRC_DIR}" target="${PRESENT}" />
</target>
<target name="build-deskshare-standalone" depends="build-deskshare-no-linker" description="Compile Deskshare Standalone Application">
<echo message="Compiling deskshare standalone without optimization." />
<build-module-no-link src="${SRC_DIR}" target="${DESKSHARE_SA}" />
</target>
<target name="build-deskshare-no-linker" description="Compile Deskshare Module without the linker">
<echo message="Compiling deskshare without optimization." />
<build-module-no-link src="${SRC_DIR}" target="${DESKSHARE}" />
</target>
<target name="build-screenshare-standalone" depends="build-screenshare-no-linker" description="Compile Screenshare Standalone Application">
<echo message="Compiling screenshare standalone without optimization." />
<build-module-no-link src="${SRC_DIR}" target="${SCREENSHARE_SA}" />
@ -255,13 +243,6 @@
<echo message="Compiling Connection Check Application." />
<build-module-no-link src="${SRC_DIR}" target="${CONNECTION_CHECK}" />
</target>
<target name="build-deskshare" description="Compile Deskshare Module">
<build-module src="${SRC_DIR}" target="${DESKSHARE}" />
<echo message="Copying deskshare applet for Deskshare Module" />
<copy file="${PROD_RESOURCES_DIR}/bbb-deskshare-applet-unsigned-0.9.0.jar" todir="${OUTPUT_DIR}"/>
<copy file="${PROD_RESOURCES_DIR}/bbb-deskshare-applet-0.9.0.jar" todir="${OUTPUT_DIR}"/>
</target>
<target name="build-screenshare" description="Compile Screenshare Module">
<build-module src="${SRC_DIR}" target="${SCREENSHARE}" />
@ -304,9 +285,9 @@
</target>
<!-- just a grouping of modules to compile -->
<target name="build-deskshare-phone-video-whiteboard-dyn"
depends="build-deskshare, build-screenshare, build-phone, build-video, build-whiteboard, build-notes, build-polling"
description="Compile deskshare, phone, video, whiteboard modules">
<target name="build-screenshare-phone-video-whiteboard-dyn"
depends="build-screenshare, build-phone, build-video, build-whiteboard, build-notes, build-polling"
description="Compile screenshare, phone, video, whiteboard modules">
</target>
<macrodef name="build-main">
@ -402,17 +383,12 @@
</sequential>
</macrodef>
<target name="compile-deskshare-standalone" depends="build-deskshare-standalone"
description="Compiling standalone desktop sharing">
<echo message="Deskshare standalone built without optimization." />
</target>
<target name="compile-screenshare-standalone" depends="build-screenshare-standalone"
description="Compiling standalone screen sharing">
<echo message="Screenshare standalone built without optimization." />
</target>
<target name="compile-bbb" depends="build-main-chat-present, build-deskshare-phone-video-whiteboard-dyn, copy-resource-files"
<target name="compile-bbb" depends="build-main-chat-present, build-screenshare-phone-video-whiteboard-dyn, copy-resource-files"
description="Compiling the BBB without copying config.xml">
</target>
@ -446,7 +422,7 @@
</copy>
<copy file="${PROD_RESOURCES_DIR}/BigBlueButtonTest.html" todir="${OUTPUT_DIR}" overwrite="true"/>
<copy file="${PROD_RESOURCES_DIR}/BigBlueButton.html" todir="${OUTPUT_DIR}" overwrite="true"/>
<copy file="${PROD_RESOURCES_DIR}/DeskshareStandalone.html" todir="${OUTPUT_DIR}" overwrite="true"/>
<copy file="${PROD_RESOURCES_DIR}/ScreenshareStandalone.html" todir="${OUTPUT_DIR}" overwrite="true"/>
<copy file="${PROD_RESOURCES_DIR}/get_flash_player.gif" todir="${OUTPUT_DIR}" overwrite="true"/>
<copy file="${PROD_RESOURCES_DIR}/bbb.gif" todir="${OUTPUT_DIR}" overwrite="true"/>
<copy file="${PROD_RESOURCES_DIR}/avatar.png" todir="${OUTPUT_DIR}" overwrite="true"/>
@ -534,19 +510,17 @@
</if>
</target>
<!-- NOTE: compile-deskshare-standalone MUST come first before compile-bbb as we need the deskshare-standalone
to be compiled withouth being optimized by using the linker -->
<target name="clean-build-bbb" depends="clean, init-ant-contrib, generate-html-wrapper, compile-deskshare-standalone,
compile-screenshare-standalone,
<!-- NOTE: compile-screenshare-standalone MUST come first before compile-bbb as we need the screenshare-standalone
to be compiled without being optimized by using the linker -->
<target name="clean-build-bbb" depends="clean, init-ant-contrib, generate-html-wrapper, compile-screenshare-standalone,
build-webcam-preview-standalone, build-webcam-view-standalone, compile-bbb"
description="Build BBB client skipping compiling of locales"/>
<target name="clean-build-all" depends="clean, init-ant-contrib, generate-html-wrapper, compile-deskshare-standalone,
<target name="clean-build-all" depends="clean, init-ant-contrib, generate-html-wrapper,
compile-screenshare-standalone, build-mic-check,
build-cam-check, build-conn-check, build-webcam-preview-standalone, build-webcam-view-standalone,
compile-bbb, branding, branding-black"
description="Build BBB client including locales"/>
<target name="modules" depends="init-ant-contrib, generate-html-wrapper, compile-deskshare-standalone,
compile-screenshare-standalone,
<target name="modules" depends="init-ant-contrib, generate-html-wrapper, compile-screenshare-standalone,
build-webcam-preview-standalone, build-webcam-view-standalone, compile-bbb"
description="Build BBB client without locales"/>
<target name="cleanandmake" depends="clean-build-all" description="Build BBB client including locales"/>

View File

@ -114,10 +114,6 @@ bbb.clientstatus.flash.title = Flash Player
bbb.clientstatus.flash.message = Your Flash Player plugin ({0}) is out-of-date. Recommend updating to the latest version.
bbb.clientstatus.webrtc.title = Audio
bbb.clientstatus.webrtc.message = Recommend using either Firefox or Chrome for better audio.
bbb.clientstatus.java.title = Java
bbb.clientstatus.java.notdetected = Java version not detected.
bbb.clientstatus.java.notinstalled = You have no Java installed, please click <font color='#0a4a7a'><a href='http://www.java.com/download/' target='_blank'>HERE</a></font> to install the latest Java to use the desktop sharing feature.
bbb.clientstatus.java.oldversion = You have an old Java installed, please click <font color='#0a4a7a'><a href='http://www.java.com/download/' target='_blank'>HERE</a></font> to install the latest Java to use the desktop sharing feature.
bbb.window.minimizeBtn.toolTip = Minimize
bbb.window.maximizeRestoreBtn.toolTip = Maximize
bbb.window.closeBtn.toolTip = Close
@ -287,17 +283,16 @@ bbb.video.publish.closeBtn.accessName = Close the webcam settings dialog box
bbb.video.publish.closeBtn.label = Cancel
bbb.video.publish.titleBar = Publish Webcam Window
bbb.video.streamClose.toolTip = Close stream for: {0}
bbb.screensharePublish.title = Desktop Sharing: Presenter's Preview
bbb.screensharePublish.title = Screen Sharing: Presenter's Preview
bbb.screensharePublish.pause.tooltip = Pause screen share
bbb.screensharePublish.pause.label = Pause
bbb.screensharePublish.restart.tooltip = Restart screen share
bbb.screensharePublish.restart.label = Restart
bbb.screensharePublish.maximizeRestoreBtn.toolTip = You cannot maximize this window.
bbb.screensharePublish.closeBtn.toolTip = Stop Sharing and Close
bbb.screensharePublish.chromeOnMacUnsupportedHint = Desktop sharing is not currently supported on Chrome running under Mac OS X. Recommend you use FireFox to share desktop.
bbb.screensharePublish.minimizeBtn.toolTip = Minimize
bbb.screensharePublish.minimizeBtn.accessibilityName = Minimize the Desktop Sharing Publish Window
bbb.screensharePublish.maximizeRestoreBtn.accessibilityName = Maximize the Desktop Sharing Publish Window
bbb.screensharePublish.minimizeBtn.accessibilityName = Minimize the Screen Sharing Publish Window
bbb.screensharePublish.maximizeRestoreBtn.accessibilityName = Maximize the Screen Sharing Publish Window
bbb.screensharePublish.commonHelpText.text = The steps below will guide you through starting screen sharing (requires Java).
bbb.screensharePublish.helpButton.toolTip = Help
bbb.screensharePublish.helpButton.accessibilityName = Help (Opens tutorial in a new window)
@ -331,7 +326,7 @@ bbb.screensharePublish.helpText.LinuxChrome3 = 3. Accept the certificate
bbb.screensharePublish.shareTypeLabel.text = Share:
bbb.screensharePublish.shareType.fullScreen = Full screen
bbb.screensharePublish.shareType.region = Region
bbb.screensharePublish.pauseMessage.label = Desktop sharing is currently paused.
bbb.screensharePublish.pauseMessage.label = Screen sharing is currently paused.
bbb.screensharePublish.startFailed.label = Did not detect start of screen sharing.
bbb.screensharePublish.restartFailed.label = Did not detect restart of screen sharing.
bbb.screensharePublish.jwsCrashed.label = The screen sharing application closed unexpectedly.
@ -339,43 +334,19 @@ bbb.screensharePublish.commonErrorMessage.label = Select 'Cancel' and try again.
bbb.screensharePublish.cancelButton.label = Cancel
bbb.screensharePublish.startButton.label = Start
bbb.screensharePublish.stopButton.label = Stop
bbb.screenshareView.title = Desktop Sharing
bbb.screenshareView.title = Screen Sharing
bbb.screenshareView.fitToWindow = Fit to Window
bbb.screenshareView.actualSize = Display actual size
bbb.screenshareView.minimizeBtn.accessibilityName = Minimize the Desktop Sharing View Window
bbb.screenshareView.maximizeRestoreBtn.accessibilityName = Maximize the Desktop Sharing View Window
bbb.screenshareView.closeBtn.accessibilityName = Close the Desktop Sharing View Window
bbb.desktopPublish.title = Desktop Sharing: Presenter's Preview
bbb.desktopPublish.fullscreen.tooltip = Share Your Main Screen
bbb.desktopPublish.fullscreen.label = Full Screen
bbb.desktopPublish.region.tooltip = Share a Part of Your Screen
bbb.desktopPublish.region.label = Region
bbb.desktopPublish.stop.tooltip = Close screen share
bbb.desktopPublish.stop.label = Close
bbb.desktopPublish.maximizeRestoreBtn.toolTip = You cannot maximize this window.
bbb.desktopPublish.closeBtn.toolTip = Stop Sharing and Close
bbb.desktopPublish.chromeOnMacUnsupportedHint = Desktop sharing is not currently supported on Chrome running under Mac OS X. You must use a different web browser (Firefox recommended) to share your desktop.
bbb.desktopPublish.chrome42UnsupportedHint = Chrome no longer supports Java Applets. You must use a different web browser (Firefox recommended) to share your desktop.
bbb.desktopPublish.edgePluginUnsupportedHint = Edge does not support Java Applets. You must use a different web browser (Firefox recommended) to share your desktop.
bbb.desktopPublish.minimizeBtn.toolTip = Minimize
bbb.desktopPublish.minimizeBtn.accessibilityName = Minimize the Desktop Sharing Publish Window
bbb.desktopPublish.maximizeRestoreBtn.accessibilityName = Maximize the Desktop Sharing Publish Window
bbb.desktopPublish.chromeHint.title = Chrome may need your permission.
bbb.desktopPublish.chromeHint.message = Select the plug-in icon (upper right-hand corner of Chrome), un-block plug-ins, and then select 'Retry'.
bbb.desktopPublish.chromeHint.button = Retry
bbb.desktopView.title = Desktop Sharing
bbb.desktopView.fitToWindow = Fit to Window
bbb.desktopView.actualSize = Display actual size
bbb.desktopView.minimizeBtn.accessibilityName = Minimize the Desktop Sharing View Window
bbb.desktopView.maximizeRestoreBtn.accessibilityName = Maximize the Desktop Sharing View Window
bbb.desktopView.closeBtn.accessibilityName = Close the Desktop Sharing View Window
bbb.screenshareView.minimizeBtn.accessibilityName = Minimize the Screen Sharing View Window
bbb.screenshareView.maximizeRestoreBtn.accessibilityName = Maximize the Screen Sharing View Window
bbb.screenshareView.closeBtn.accessibilityName = Close the Screen Sharing View Window
bbb.toolbar.phone.toolTip.start = Share Your Microphone
bbb.toolbar.phone.toolTip.stop = Stop Sharing Your Microphone
bbb.toolbar.phone.toolTip.mute = Stop listening the conference
bbb.toolbar.phone.toolTip.unmute = Start listening the conference
bbb.toolbar.phone.toolTip.nomic = No microphone detected
bbb.toolbar.deskshare.toolTip.start = Share Your Desktop
bbb.toolbar.deskshare.toolTip.stop = Stop Sharing Your Desktop
bbb.toolbar.deskshare.toolTip.start = Share Your Screen
bbb.toolbar.deskshare.toolTip.stop = Stop Sharing Your Screen
bbb.toolbar.video.toolTip.start = Share Your Webcam
bbb.toolbar.video.toolTip.stop = Stop Sharing Your Webcam
bbb.layout.addButton.toolTip = Add the custom layout to the list
@ -446,9 +417,6 @@ bbb.notes.saveBtn.toolTip = Save Note
bbb.settings.deskshare.instructions = Choose Allow on the prompt that pops up to check that desktop sharing is working properly for you
bbb.settings.deskshare.start = Check Desktop Sharing
bbb.settings.voice.volume = Microphone Activity
bbb.settings.java.label = Java version error
bbb.settings.java.text = You have Java {0} installed, but you need at least version {1} to use the BigBlueButton desktop sharing feature. The button below will install the newest Java JRE version.
bbb.settings.java.command = Install newest Java
bbb.settings.flash.label = Flash version error
bbb.settings.flash.text = You have Flash {0} installed, but you need at least version {1} to run BigBlueButton properly. The button below will install the newest Adobe Flash version.
bbb.settings.flash.command = Install newest Flash
@ -677,11 +645,14 @@ bbb.users.breakout.remainingTimeParent = <b>{1} remaining</b>
bbb.users.breakout.calculatingRemainingTime = Calculating remaining time...
bbb.users.breakout.remainingTimeEnded = Time ended, breakout room will close.
bbb.users.breakout.rooms = Rooms
bbb.users.breakout.roomsCombo.accessibilityName = Number of rooms to create
bbb.users.breakout.room = Room
bbb.users.breakout.randomAssign = Randomly Assign Users
bbb.users.breakout.timeLimit = Time Limit
bbb.users.breakout.durationStepper.accessibilityName = Time limit in minutes
bbb.users.breakout.minutes = Minutes
bbb.users.breakout.record = Record
bbb.users.breakout.recordCheckbox.accessibilityName = Record breakout rooms
bbb.users.breakout.notAssigned = Not Assigned
bbb.users.breakout.dragAndDropToolTip = Tip: You can drag and drop users between rooms
bbb.users.breakout.start = Start

View File

@ -24,7 +24,6 @@
</style>
<script type="text/javascript" src="swfobject/swfobject.js"></script>
<script src="lib/deployJava.js?v=VERSION" language="javascript"></script>
<script type="text/javascript">
// Check for Firefox 41.0.1/2 to workaround Flash hang
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1210665
@ -106,7 +105,6 @@
<script src="lib/Screen-Capturing.js" language="javascript"></script>
<script src="lib/verto_extension.js" language="javascript"></script>
<script src="lib/bbb_deskshare.js?v=VERSION" language="javascript"></script>
<script src="lib/bbb_api_bridge.js?v=VERSION" language="javascript"></script>
<script src="lib/sip.js?v=VERSION" language="javascript"></script>
<script src="lib/bbb_webrtc_bridge_sip.js?v=VERSION" language="javascript"></script>

View File

@ -1,57 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css" media="screen">
html, body, #content { height:100%; }
body { margin:0; padding:0; overflow:hidden; }
#altContent { /* style alt content */ }
</style>
<script type="text/javascript" src="swfobject/swfobject.js"></script>
<script type="text/javascript">
swfobject.registerObject("BigBlueButton", "10.3.0", "expressInstall.swf");
</script>
<script src="lib/jquery-2.1.1.min.js" language="javascript"></script>
<!--<script src="lib/jquery-1.5.1.min.js" language="javascript"></script>-->
<script src="lib/bigbluebutton.js" language="javascript"></script>
<script src="lib/bbb_localization.js" language="javascript"></script>
<script src="lib/bbb_blinker.js" language="javascript"></script>
<script src="lib/jquery.mobile.min.js" language="javascript"></script>
<script src="lib/jquery.json-2.4.min.js" language="javascript"></script>
<script src="lib/jquery.cookie.js" language="javascript"></script>
<script src="lib/jquery.dataTables.min.js" language="javascript"></script>
<script src="lib/getScreenId.js" language="javascript"></script>
<script src="lib/jquery.FSRTC.js" language="javascript"></script>
<script src="lib/jquery.jsonrpcclient.js" language="javascript"></script>
<script src="lib/jquery.verto.js" language="javascript"></script>
<script src="lib/Screen-Capturing.js" language="javascript"></script>
<script src="lib/verto_extension.js" language="javascript"></script>
<script src="lib/verto_extension_share.js" language="javascript"></script>
<script src="lib/bbb_deskshare.js" language="javascript"></script>
</head>
<body>
<div id="content">
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%" id="BigBlueButton" name="BigBlueButton" align="middle">
<param name="movie" value="DeskshareStandalone.swf?v=VERSION" />
<param name="quality" value="high" />
<param name="allowfullscreen" value="true" />
<param name="bgcolor" value="#869ca7" />
<!--[if !IE]>-->
<object type="application/x-shockwave-flash" data="DeskshareStandalone.swf?v=VERSION" width="100%" height="100%" align="middle">
<param name="quality" value="high" />
<param name="bgcolor" value="#869ca7" />
<!--<![endif]-->
<a href="http://www.adobe.com/go/getflashplayer">
<img src="//www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" />
</a>
<!--[if !IE]>-->
</object>
<!--<![endif]-->
</object>
</div>
</body>
</html>

View File

@ -16,7 +16,7 @@
<script src="lib/bigbluebutton.js" language="javascript"></script>
<script src="lib/bbb_localization.js" language="javascript"></script>
<script src="lib/bbb_blinker.js" language="javascript"></script>
<script src="lib/bbb_deskshare.js" language="javascript"></script>
<script src="lib/bbb_screenshare.js" language="javascript"></script>
</head>
<body>
<div id="controls"/>

View File

@ -505,13 +505,6 @@
}
}
BBB.javaAppletLaunched = function() {
var swfObj = getSwfObj();
if (swfObj) {
swfObj.javaAppletLaunched();
}
}
// Third-party JS apps should use this to query if the BBB SWF file is ready to handle calls.
BBB.isSwfClientReady = function() {
return swfReady;

View File

@ -1,174 +0,0 @@
if (!window.console) window.console = {};
if (!window.console.log) window.console.log = function () { };
function startApplet(IP, useTLS , roomNumber, fullScreen, useSVC2)
{
var deskshareElement = document.getElementById("deskshare");
if (deskshareElement == null) {
console.log("Starting deskshare applet.");
var div = document.createElement("div");
div.id = "deskshare";
div.innerHTML =
"<applet code=\"org.bigbluebutton.deskshare.client.DeskShareApplet.class\"" +
"id=\"DeskShareApplet\" width=\"100\" height=\"10\" archive=\"bbb-deskshare-applet-0.9.0.jar\">" +
"<param name=\"ROOM\" value=\"" + roomNumber + "\"/>" +
"<param name=\"IP\" value=\"" + IP + "\"/>" +
"<param name=\"useTLS\" value=\"" + useTLS + "\"/>" +
"<param name=\"PORT\" value=\"9123\"/>" +
"<param name=\"SCALE\" value=\"0.8\"/>" +
"<param name=\"FULL_SCREEN\" value=\"" + fullScreen + "\"/>" +
"<param name=\"SVC2\" value=\"" + useSVC2 + "\"/>" +
"<param name=\"JavaVersion\" value=\"1.7.0_51\"/>" +
"<param name=\"permissions\" value=\"all-permissions\"/>" +
"</applet>";
document.body.appendChild(div);
} else {
console.log("Deskshare applet element already exists.");
var div = document.getElementById("deskshare");
if (div.parentNode) {
// Just rewrite the applet tag to kick off the applet. We don't remove the applet tag
// when desktop sharing is stopped to prevent Firefox (38.0.5) from asking for user permissions
// again resulting in the page reloading. (ralam june 17, 2015)
// https://code.google.com/p/bigbluebutton/issues/detail?id=1953
div.innerHTML =
"<applet code=\"org.bigbluebutton.deskshare.client.DeskShareApplet.class\"" +
"id=\"DeskShareApplet\" width=\"100\" height=\"10\" archive=\"bbb-deskshare-applet-0.9.0.jar\">" +
"<param name=\"ROOM\" value=\"" + roomNumber + "\"/>" +
"<param name=\"IP\" value=\"" + IP + "\"/>" +
"<param name=\"PORT\" value=\"9123\"/>" +
"<param name=\"SCALE\" value=\"0.8\"/>" +
"<param name=\"FULL_SCREEN\" value=\"" + fullScreen + "\"/>" +
"<param name=\"SVC2\" value=\"" + useSVC2 + "\"/>" +
"<param name=\"JavaVersion\" value=\"1.7.0_51\"/>" +
"<param name=\"permissions\" value=\"all-permissions\"/>" +
"</applet>";
}
}
}
function removeFrame () {
var div = document.getElementById("deskshare");
if (div.parentNode) {
// Need to set the innerHTML otherwise the applet will restart in IE.
// see https://code.google.com/p/bigbluebutton/issues/detail?id=1776
// Do NOT remove the applet tag as it makes Firefox (38.0.5) prompt for
// permissions again resulting in the page reloading. (ralam june 17, 2015)
// div.innerHTML = "";
// div.parentNode.removeChild(div);
}
}
function setScreenCoordinates(x, y) {
document.DeskShareApplet.setScreenCoordinates(x,y);
}
function stopApplet(){
console.log("Stopping deskshare applet.");
removeFrame();
}
function appletStartupCallback() {
BBB.javaAppletLaunched();
}
function getHighestJavaVersion(javas) {
var highestJava = javas[0];
console.log("highestJava = [" + highestJava + "]");
for (j = 0; j < javas.length; j++) {
var java = javas[j];
console.log("java[" + j + "]=[" + java + "]");
var highest = highestJava.split(".");
console.log(highest);
var iter = java.split(".");
console.log(iter);
if (parseInt(iter[0]) > parseInt(highest[0])) {
highestJava = java;
} else if (parseInt(iter[0]) == parseInt(highest[0]) && parseInt(iter[1]) > parseInt(highest[1])) {
highestJava = java;
console.log(highestJava);
} else if (parseInt(iter[0]) == parseInt(highest[0]) && parseInt(iter[1]) == parseInt(highest[1])) {
var iterMinor = parseInt((iter[2]).split("_")[1]);
var highestMinor = parseInt((highest[2]).split("_")[1]);
if (iterMinor > highestMinor) {
highestJava = java;
console.log(highestJava);
}
}
}
return highestJava;
}
function getIcedTeaWebVersion() {
for (i = 0; i < navigator.plugins.length; i++) {
var matches;
if (matches = navigator.plugins[i].name.match(/using IcedTea-Web ([0-9.]+)/)) {
return matches[1];
}
}
return null;
}
function isJavaVersionOk(installedVersion, minVersion) {
var required = minVersion.split(".");
highest = installedVersion.split(".");
if (parseInt(required[0]) > parseInt(highest[0])) {
console.log("older major version=[" + installedVersion + "]");
return {result: "JAVA_OLDER", version: installedVersion};
} else if (parseInt(required[0]) == parseInt(highest[0]) && parseInt(required[1]) > parseInt(highest[1])) {
console.log("older minor version=[" + installedVersion + "]");
return {result: "JAVA_OLDER", version: installedVersion};
} else if (parseInt(required[0]) == parseInt(highest[0]) && parseInt(required[1]) == parseInt(highest[1])) {
var requiredMinor = parseInt((required[2]).split("_")[1]);
var highestJavaMinor = parseInt((highest[2]).split("_")[1]);
if (requiredMinor > highestJavaMinor) {
console.log("older update version=[" + installedVersion + "]");
return {result: "JAVA_OLDER", version: installedVersion};
}
}
return {result: "JAVA_OK"};
}
function isIcedTeaVersionOkLinux(installedVersion, minVersion) {
var required = minVersion.split(".");
highest = installedVersion.split(".");
if (parseInt(required[0]) > parseInt(highest[0])) {
console.log("ice: older major version=[" + installedVersion + "]");
return {result: "JAVA_OLDER", version: installedVersion};
} else if (parseInt(required[0]) == parseInt(highest[0]) && parseInt(required[1]) > parseInt(highest[1])) {
console.log("ice: older minor version=[" + installedVersion + "]");
return {result: "JAVA_OLDER", version: installedVersion};
}
return {result: "JAVA_OK"};
}
function checkJavaVersion(minJavaVersion) {
var javas = deployJava.getJREs();
var highestJavaVersion = null;
if (javas == null || javas.length == 0) {
if (javas == null) {
return {result:"JAVA_NOT_DETECTED"};
}
if (javas.length == 0) {
return {result: "JAVA_NOT_INSTALLED"};
}
} else {
var highestJavaVersion = getHighestJavaVersion(javas);
var isOk = isJavaVersionOk(highestJavaVersion, minJavaVersion);
if (isOk.result === "JAVA_OLDER") {
highestJavaVersion = getIcedTeaWebVersion();
return isIcedTeaVersionOkLinux(highestJavaVersion, "1.5.0");
} else {
return isOk;
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -1,113 +0,0 @@
<?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/>.
-->
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:maps="org.bigbluebutton.modules.deskshare.maps.*"
implements="org.bigbluebutton.common.IBigBlueButtonModule"
creationComplete="onCreationComplete()">
<maps:DeskshareEventMap id="javaDeskshareEventMap" />
<maps:WebRTCDeskshareEventMap id="webRTCDeskshareEventMap" />
<mx:Script>
<![CDATA[
import com.asfusion.mate.events.Dispatcher;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.IBigBlueButtonModule;
import org.bigbluebutton.modules.deskshare.events.ModuleEvent;
private static const LOGGER:ILogger = getClassLogger(DeskShareModule);
private var _moduleName:String = "Desk Share";
private var _attributes:Object;
private var globalDispatcher:Dispatcher = new Dispatcher();;
private function onCreationComplete():void{
LOGGER.debug("DeskShareModule initialized");
}
public function get moduleName():String{
return _moduleName;
}
public function get uri():String{
return _attributes.uri;
}
public function get username():String{
return _attributes.username;
}
public function get mode():String{
if (_attributes.mode == null){
_attributes.mode = "LIVE";
LOGGER.debug("Setting DeskShare mode: {0}", [_attributes.mode]);
}
LOGGER.debug("DeskShare mode: {0}", [_attributes.mode]);
return _attributes.mode;
}
public function get userid():Number{
return _attributes.userid as Number;
}
public function get role():String{
return _attributes.userrole as String;
}
public function start(attributes:Object):void{
LOGGER.debug("desk share attr: {0}", [attributes.username]);
_attributes = attributes;
var startEvent:ModuleEvent = new ModuleEvent(ModuleEvent.START);
startEvent.module = this;
globalDispatcher.dispatchEvent(startEvent);
}
public function stop():void{
LOGGER.debug("STOPPING DESKSHARE MODULE!!!");
var stopEvent:ModuleEvent = new ModuleEvent(ModuleEvent.STOP);
globalDispatcher.dispatchEvent(stopEvent);
}
public function getRoom():String{
return _attributes.room;
}
public function getRed5ServerUri():String{
return _attributes.uri;
}
public function tunnel():Boolean {
if (_attributes.protocol == "RTMPT") {
LOGGER.debug("Use tunneling for desktop sharing");
return true;
}
return false;
}
]]>
</mx:Script>
</mx:Module>

View File

@ -1,355 +0,0 @@
<?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/>.
-->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:mate="http://mate.asfusion.com/"
creationComplete="onCreationComplete()" resize="onResize()"
backgroundColor="white"
width="100%" height="100%"
layout="absolute">
<mate:Listener type="{AppletStartedEvent.APPLET_STARTED}" method="onAppletStart" />
<mate:Listener type="{ViewStreamEvent.STOP}" method="onAppletStop" />
<mate:Listener type="{ViewStreamEvent.START}" method="onViewStreamStart"/>
<mate:Listener type="{CursorEvent.UPDATE_CURSOR_LOC_EVENT}" method="onUpdateCursorEvent" />
<mate:Listener type="{ConnectionEvent.DESKSHARE_CONNECTION_EVENT}" method="onDeskshareConnectionEvent" />
<mx:Script>
<![CDATA[
import mx.core.UIComponent;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.Images;
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.services.DeskshareService;
import org.bigbluebutton.modules.deskshare.services.red5.ConnectionEvent;
import org.bigbluebutton.util.QueryStringParameters;
private static const LOGGER:ILogger = getClassLogger(DeskshareStandalone);
private var videoHolder:UIComponent;
private var cursor:Shape = new Shape();;
private var images:Images = new Images();
[Bindable] public var bbbLogo:Class = images.bbb_logo;
private var video:Video;
private var ns:NetStream;
private var stream:String;
private var logoutURL:String;
private var host:String;
private var room:String;
private var displayWidth:Number;
private var displayHeight:Number;
private var service:DeskshareService = new DeskshareService();
private var videoWidth:int;
private var videoHeight:int;
private function onCreationComplete():void {
var p:QueryStringParameters = new QueryStringParameters();
p.collectParameters();
logoutURL = p.getParameter("LOGOUTURL");
host = p.getParameter("HOST");
room = p.getParameter("ROOM");
service.connect(host, room);
cursor.graphics.lineStyle(6, 0xFF0000, 0.6);
cursor.graphics.drawCircle(0,0,3);
cursor.visible = false;
displayWidth = this.parent.width;
displayHeight = this.parent.height;
}
private function onAppletStart(event:AppletStartedEvent):void{
LOGGER.debug("DeskshareSA::onAppletStart.");
startVideo(service.getConnection(), room, event.videoWidth, event.videoHeight);
}
private function onViewStreamStart(event:ViewStreamEvent):void {
LOGGER.debug("DeskshareSA::onViewStreamStart.");
startVideo(service.getConnection(), room, event.videoWidth, event.videoHeight);
}
private function onAppletStop(event:ViewStreamEvent):void {
LOGGER.debug("DeskshareSA::onAppletStop.");
var url:URLRequest = new URLRequest(logoutURL);
navigateToURL(url, '_self');
}
private function onDeskshareConnectionEvent(event:ConnectionEvent):void {
var warningText:String;
switch(event.status) {
case ConnectionEvent.SUCCESS:
warningText = "Connecting to server successful.";
break;
case ConnectionEvent.FAILED:
warningText = "Connecting to server failed.";
break;
case ConnectionEvent.CLOSED:
warningText = "Connection to server closed.";
break;
case ConnectionEvent.REJECTED:
warningText = "Connection to server rejected.";
break;
case ConnectionEvent.INVALIDAPP:
warningText = "Connecting to server failed. Invalid application.";
break;
case ConnectionEvent.APPSHUTDOWN:
warningText = "Connection to server failed. Server shutting down.";
break;
case ConnectionEvent.SECURITYERROR:
warningText = "Connecting to server failed. Security error.";
break;
case ConnectionEvent.DISCONNECTED:
warningText = "Connection to server disconnected.";
break;
case ConnectionEvent.CONNECTING:
warningText = "Connecting to server...";
break;
case ConnectionEvent.CONNECTING_RETRY:
warningText = "Connecting to server failed. Retry [" + event.retryAttempts + "]";
break;
case ConnectionEvent.CONNECTING_MAX_RETRY:
warningText = "Connecting to server failed. Max retry reached. Giving up.";
break;
case ConnectionEvent.CHECK_FOR_DESKSHARE_STREAM:
warningText = "Loading...";
break;
case ConnectionEvent.FAIL_CHECK_FOR_DESKSHARE_STREAM:
warningText = "Loading shared desktop failed.";
break;
case ConnectionEvent.NO_DESKSHARE_STREAM:
warningText = "Desktop is not shared.";
break;
}
showStatusText(warningText, true, "0x000000");
LOGGER.debug("CONNECT STATUS EVENT [{0}]", [event.status]);
}
private function startVideo(connection:NetConnection, stream:String, videoWidth:Number, videoHeight:Number):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);
video = new Video(videoWidth, videoHeight);
video.attachNetStream(ns);
this.videoWidth = videoWidth;
this.videoHeight = videoHeight;
videoHolder = new UIComponent();
LOGGER.debug("DeskshareSA::Determine how to display video = [{0}x{1}] display=[{2}x{3}]", [videoWidth, videoHeight, this.width, this.height]);
determineHowToDisplayVideo();
ns.play(stream);
this.stream = stream;
}
private function onMetaData(info:Object):void {
LOGGER.debug("DeskshareSA:: ****metadata: width={0} height={1}", [info.width, info.height]);
videoWidth = info.width;
videoHeight = info.height;
// determineHowToDisplayVideo();
}
private function onResize():void {
if (video != null) {
determineHowToDisplayVideo();
}
}
private function onUpdateCursorEvent(event:CursorEvent):void {
if (cursor == null) return;
cursor.x = videoHolder.x + (event.x * (videoHolder.width / videoWidth));
cursor.y = videoHolder.y + (event.y * (videoHolder.height / videoHeight));
cursorImg.visible = true;
// DO NOT compute the x and y coordinate and assign directly to the cursorImg
// as it results in a flickering and jerky mouse pointer (ralam jun 10, 2010).
cursorImg.x = cursor.x;
cursorImg.y = cursor.y;
}
public function stopViewing():void {
ns.close();
}
private function onAsyncError(e:AsyncErrorEvent):void{
LOGGER.debug("DeskshareSA::::asyncerror {0}", [e.toString()]);
}
private function onNetStatus(e:NetStatusEvent):void{
switch(e.info.code){
case "NetStream.Play.Start":
LOGGER.debug("DeskshareSA::NetStream.Publish.Start for broadcast stream {0}", [stream]);
LOGGER.debug("DeskshareSA::Dispatching start viewing event");
service.sendStartedViewingNotification(stream);
break;
case "NetStream.Play.UnpublishNotify":
LOGGER.debug("DeskshareSA::NetStream.Play.UnpublishNotify for broadcast stream {0}", [stream]);
stopViewing();
break;
case "NetStream.DRM.UpdateNeeded":
case "NetStream.Play.Failed":
case "NetStream.Play.FileStructureInvalid":
case "NetStream.Play.NoSupportedTrackFound":
case "NetStream.Play.StreamNotFound":
// case "NetStream.Play.Reset":
showStatusText(e.info.code, true, "0x000000");
break;
}
LOGGER.debug("NET STATUS EVENT [{0}]", [e.info.code]);
}
//----------------------------
private function centerToWindow():void{
videoHolder.width = video.width = videoWidth;
videoHolder.height = video.height = videoHeight;
videoHolder.x = video.x = (this.width - video.width) / 4;
videoHolder.y = video.y = (this.height - video.height) / 4;
LOGGER.debug("DeskshareSA::Center video = [{0}x{1}] display=[{2}x{3}]" + "loc=[{4},{5}]",
[video.width, video.height, this.width, this.height, videoHolder.x, videoHolder.y]);
videoHolder.addChild(video);
videoHolder.addChild(cursor);
videoHolder.addChild(cursorImg);
showVideoHolder();
}
private function fitVideoToWindow():void {
if (width < height) {
fitToWidthAndAdjustHeightToMaintainAspectRatio();
} else {
fitToHeightAndAdjustWidthToMaintainAspectRatio();
}
}
private function videoIsSmallerThanWindow():Boolean {
return (videoHeight < height) && (videoWidth < width);
}
private function fitToWidthAndAdjustHeightToMaintainAspectRatio():void {
LOGGER.debug("DeskshareSA::fitToWidthAndAdjustHeightToMaintainAspectRatio");
videoHolder.width = video.width = width;
// Maintain aspect-ratio
videoHolder.height = video.height = (videoHeight * video.width) / videoWidth;
videoHolder.x = video.x = 0;
videoHolder.y = video.y = 0;
LOGGER.debug("DeskshareSA::Disp video = [{0}x{1}] display=[{2}x{3}]" + "loc=[{4},{5}]",
[video.width, video.height, this.width, this.height, videoHolder.x, videoHolder.y]);
videoHolder.addChild(video);
videoHolder.addChild(cursor);
videoHolder.addChild(cursorImg);
showVideoHolder();
}
private function fitToHeightAndAdjustWidthToMaintainAspectRatio():void {
LOGGER.debug("DeskshareSA::fitToHeightAndAdjustWidthToMaintainAspectRatio");
videoHolder.height = video.height = height;
// Maintain aspect-ratio
videoHolder.width = video.width = (videoWidth * video.height) / videoHeight;
if (videoHolder.width > width) {
videoHolder.width = video.width = width;
videoHolder.height = video.height = (videoHeight * video.width) / videoWidth;
}
videoHolder.x = video.x = (width - video.width) / 4;
videoHolder.y = video.y = (height - video.height) / 4;
LOGGER.debug("DeskshareSA::Disp video = [{0}x{1}] display=[{2}x{3}]" + "loc=[{4},{5}]",
[video.width, video.height, this.width, this.height, videoHolder.x, videoHolder.y]);
videoHolder.addChild(video);
videoHolder.addChild(cursor);
videoHolder.addChild(cursorImg);
showVideoHolder();
}
private function showVideoHolder():void {
addChild(videoHolder);
}
private function determineHowToDisplayVideo():void {
// if (videoIsSmallerThanWindow()) {
// trace("Video is smaller than window. Centering.");
centerToWindow();
// } else {
// trace("Video is greater than window. Scaling.");
// fitVideoToWindow();
// }
}
private var hideStatusTextTimer:Timer = null;
private function showStatusText(statusText:String, autoHide:Boolean=false, color:String="0xFF0000"):void {
if (hideStatusTextTimer != null)
hideStatusTextTimer.stop();
if (autoHide) {
hideStatusTextTimer = new Timer(3000, 1);
hideStatusTextTimer.addEventListener(TimerEvent.TIMER, hideStatusText);
hideStatusTextTimer.start();
}
// bring the label to front
setChildIndex(statusTextDisplay, getChildren().length - 1);
statusTextDisplay.text = statusText;
statusTextDisplay.setStyle("color", color);
statusTextDisplay.visible = true;
}
private function hideStatusText(e:TimerEvent):void {
statusTextDisplay.visible = false;
}
]]>
</mx:Script>
<mx:Image id="cursorImg" visible="false" source="@Embed('org/bigbluebutton/modules/deskshare/assets/images/cursor4.png')"/>
<mx:Fade id="dissolveOut" duration="1000" alphaFrom="1.0" alphaTo="0.0"/>
<mx:Fade id="dissolveIn" duration="1000" alphaFrom="0.0" alphaTo="1.0"/>
<mx:Text id="statusTextDisplay" width="100%" fontSize="14" fontWeight="bold" textAlign="center" y="{(this.height - statusTextDisplay.height) / 2}"
visible="false" selectable="false" hideEffect="{dissolveOut}" showEffect="{dissolveIn}"/>
</mx:Application>

View File

@ -346,7 +346,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
]]>
</mx:Script>
<mx:Image id="cursorImg" visible="false" source="@Embed('org/bigbluebutton/modules/deskshare/assets/images/cursor4.png')"/>
<mx:Image id="cursorImg" visible="false" source="@Embed('org/bigbluebutton/modules/screenshare/assets/images/cursor4.png')"/>
<mx:Fade id="dissolveOut" duration="1000" alphaFrom="1.0" alphaTo="0.0"/>
<mx:Fade id="dissolveIn" duration="1000" alphaFrom="0.0" alphaTo="1.0"/>

View File

@ -38,7 +38,6 @@ package org.bigbluebutton.main.api
import org.bigbluebutton.main.model.users.events.EmojiStatusEvent;
import org.bigbluebutton.main.model.users.events.KickUserEvent;
import org.bigbluebutton.main.model.users.events.RoleChangeEvent;
import org.bigbluebutton.modules.deskshare.events.DeskshareAppletLaunchedEvent;
import org.bigbluebutton.modules.phone.events.AudioSelectionWindowEvent;
import org.bigbluebutton.modules.phone.events.WebRTCCallEvent;
import org.bigbluebutton.modules.phone.events.WebRTCEchoTestEvent;
@ -104,7 +103,6 @@ package org.bigbluebutton.main.api
ExternalInterface.addCallback("webRTCMediaRequest", handleWebRTCMediaRequest);
ExternalInterface.addCallback("webRTCMediaSuccess", handleWebRTCMediaSuccess);
ExternalInterface.addCallback("webRTCMediaFail", handleWebRTCMediaFail);
ExternalInterface.addCallback("javaAppletLaunched", handleJavaAppletLaunched);
ExternalInterface.addCallback("getSessionToken", handleGetSessionToken);
}
@ -436,10 +434,5 @@ package org.bigbluebutton.main.api
private function handleWebRTCMediaFail():void {
_dispatcher.dispatchEvent(new WebRTCMediaEvent(WebRTCMediaEvent.WEBRTC_MEDIA_FAIL));
}
private function handleJavaAppletLaunched():void
{
_dispatcher.dispatchEvent(new DeskshareAppletLaunchedEvent(DeskshareAppletLaunchedEvent.APPLET_LAUNCHED));
}
}
}

View File

@ -39,7 +39,9 @@ package org.bigbluebutton.main.events {
public var meetingId:String;
public var breakoutId:String;
public var breakoutMeetingId:String;
public var breakoutMeetingSequence:int;
public var rooms:Array;

View File

@ -334,12 +334,11 @@ package org.bigbluebutton.main.model.users
private var _breakoutRooms : Array = [];
[Bindable("displayNameChange")]
public function get displayName() : String {
if (ArrayUtils.isEmpty(_breakoutRooms)){
public function get displayName():String {
if (ArrayUtils.isEmpty(_breakoutRooms)) {
return name;
}
else {
return "[" + _breakoutRooms.join(",") + "] " +name;
} else {
return "[" + _breakoutRooms.join(",") + "] " + name;
}
}
@ -352,14 +351,14 @@ package org.bigbluebutton.main.model.users
dispatchEvent(new Event("displayNameChange"));
}
public function addBreakoutRoom(roomNumber:String):void {
public function addBreakoutRoom(roomNumber:int):void {
if (!ArrayUtils.contains(_breakoutRooms, roomNumber)) {
_breakoutRooms.push(roomNumber);
dispatchEvent(new Event("displayNameChange"));
}
}
public function removeBreakoutRoom(roomNumber:String):void {
public function removeBreakoutRoom(roomNumber:int):void {
_breakoutRooms.splice(_breakoutRooms.indexOf(roomNumber), 1);
dispatchEvent(new Event("displayNameChange"));
}

View File

@ -28,7 +28,11 @@ package org.bigbluebutton.main.model.users {
public static const OTHER:String = "other";
public var breakoutId:String;
public var externalMeetingId:String;
public var meetingId:String;
public var sequence:int;
public var name:String;
@ -44,6 +48,5 @@ package org.bigbluebutton.main.model.users {
public function get numberOfUsers():int {
return users.length;
}
}
}

View File

@ -20,6 +20,7 @@ package org.bigbluebutton.main.model.users {
import mx.collections.ArrayCollection;
import mx.collections.Sort;
import mx.collections.SortField;
import org.as3commons.lang.ArrayUtils;
import org.as3commons.lang.StringUtils;
@ -534,59 +535,87 @@ package org.bigbluebutton.main.model.users {
/* Breakout room feature */
public function addBreakoutRoom(newRoom:BreakoutRoom):void {
if (hasBreakoutRoom(newRoom.breakoutId)) {
removeBreakoutRoom(newRoom.breakoutId);
if (hasBreakoutRoom(newRoom.meetingId)) {
removeBreakoutRoom(newRoom.meetingId);
}
breakoutRooms.addItem(newRoom);
sortBreakoutRooms();
}
private function sortBreakoutRooms() : void {
var sort:Sort = new Sort();
sort.fields = [new SortField("sequence", true, false, true)];
breakoutRooms.sort = sort;
breakoutRooms.refresh();
}
public function updateBreakoutRoomUsers(breakoutId:String, breakoutUsers:Array):void {
var room:Object = getBreakoutRoom(breakoutId);
public function updateBreakoutRoomUsers(breakoutMeetingId:String, breakoutUsers:Array):void {
var room:BreakoutRoom = getBreakoutRoom(breakoutMeetingId);
if (room != null) {
BreakoutRoom(room).users = new ArrayCollection(breakoutUsers);
var breakoutRoomNumber:String = StringUtils.substringAfterLast(breakoutId, "-");
room.users = new ArrayCollection(breakoutUsers);
var updateUsers:Array = [];
// Update users breakout rooms
var user : BBBUser;
var user:BBBUser;
for (var i:int = 0; i < breakoutUsers.length; i++) {
var userId:String = StringUtils.substringBeforeLast(breakoutUsers[i].id, "-");
user = getUser(userId);
if (user) {
user.addBreakoutRoom(breakoutRoomNumber)
user.addBreakoutRoom(room.sequence)
}
updateUsers.push(userId);
}
// Remove users breakout rooms if the users left the breakout rooms
for (var j:int = 0; j < users.length; j++) {
user = BBBUser(users.getItemAt(j));
if (updateUsers.indexOf(BBBUser(users.getItemAt(j)).userID) == -1 && ArrayUtils.contains(user.breakoutRooms, breakoutRoomNumber)) {
user.removeBreakoutRoom(breakoutRoomNumber);
if (updateUsers.indexOf(BBBUser(users.getItemAt(j)).userID) == -1 && ArrayUtils.contains(user.breakoutRooms, room.sequence)) {
user.removeBreakoutRoom(room.sequence);
}
}
users.refresh();
}
}
/**
* Returns a breakout room by its breakoutId
* Returns a breakout room by its internal meeting ID
*/
public function getBreakoutRoom(breakoutId:String):BreakoutRoom {
var r:Object = getBreakoutRoomIndex(breakoutId);
public function getBreakoutRoom(breakoutMeetingId:String):BreakoutRoom {
var r:Object = getBreakoutRoomIndex(breakoutMeetingId);
if (r != null) {
return r.room as BreakoutRoom;
}
return null;
}
/**
* Finds the index of a breakout room by its breakoutId
*/
public function getBreakoutRoomIndex(breakoutId:String):Object {
public function getBreakoutRoomByExternalId(externalId:String):BreakoutRoom {
var aRoom:BreakoutRoom;
for (var i:int = 0; i < breakoutRooms.length; i++) {
aRoom = breakoutRooms.getItemAt(i) as BreakoutRoom;
if (aRoom.breakoutId == breakoutId) {
if (aRoom.externalMeetingId == externalId) {
return aRoom;
}
}
return null;
}
public function getBreakoutRoomBySequence(sequence:int):BreakoutRoom {
var aRoom:BreakoutRoom;
for (var i:int = 0; i < breakoutRooms.length; i++) {
aRoom = breakoutRooms.getItemAt(i) as BreakoutRoom;
if (aRoom.sequence == sequence) {
return aRoom;
}
}
return null;
}
/**
* Finds the index of a breakout room by its internal meeting ID
*/
public function getBreakoutRoomIndex(breakoutMeetingId:String):Object {
var aRoom:BreakoutRoom;
for (var i:int = 0; i < breakoutRooms.length; i++) {
aRoom = breakoutRooms.getItemAt(i) as BreakoutRoom;
if (aRoom.meetingId == breakoutMeetingId) {
return {index: i, room: aRoom};
}
}
@ -594,39 +623,38 @@ package org.bigbluebutton.main.model.users {
return null;
}
public function removeBreakoutRoom(breakoutId:String):void {
var p:Object = getBreakoutRoomIndex(breakoutId);
if (p != null) {
breakoutRooms.removeItemAt(p.index);
breakoutRooms.refresh();
public function removeBreakoutRoom(breakoutMeetingId:String):void {
var room:Object = getBreakoutRoomIndex(breakoutMeetingId);
if (room != null) {
breakoutRooms.removeItemAt(room.index);
sortBreakoutRooms();
if (breakoutRooms.length == 0) {
breakoutRoomsReady = false;
}
// Remove breakout room number display from users
for (var i:int; i < users.length; i++) {
var breakoutRoomNumber:String = StringUtils.substringAfterLast(breakoutId, "-");
if (ArrayUtils.contains(users[i].breakoutRooms, breakoutRoomNumber)) {
users[i].removeBreakoutRoom(breakoutRoomNumber);
if (ArrayUtils.contains(users[i].breakoutRooms, room.room.sequence)) {
users[i].removeBreakoutRoom(room.room.sequence);
}
}
users.refresh();
}
}
public function hasBreakoutRoom(breakoutId:String):Boolean {
var p:Object = getBreakoutRoomIndex(breakoutId);
public function hasBreakoutRoom(breakoutMeetingId:String):Boolean {
var p:Object = getBreakoutRoomIndex(breakoutMeetingId);
if (p != null) {
return true;
}
return false;
}
public function setBreakoutRoomInListen(listen:Boolean, breakoutId:String):void {
public function setBreakoutRoomInListen(listen:Boolean, breakoutMeetingId:String):void {
for (var i:int = 0; i < breakoutRooms.length; i++) {
var br:BreakoutRoom = BreakoutRoom(breakoutRooms.getItemAt(i));
if (listen == false) {
br.listenStatus = BreakoutRoom.NONE;
} else if (listen == true && br.breakoutId == breakoutId) {
} else if (listen == true && br.meetingId == breakoutMeetingId) {
br.listenStatus = BreakoutRoom.SELF;
} else {
br.listenStatus = BreakoutRoom.OTHER;

View File

@ -199,20 +199,20 @@ package org.bigbluebutton.main.model.users
}
public function createBreakoutRooms(e:BreakoutRoomEvent):void{
sender.createBreakoutRooms(_conferenceParameters.meetingID, e.rooms, e.durationInMinutes, e.record);
sender.createBreakoutRooms(_conferenceParameters.meetingID, e.rooms, e.durationInMinutes, e.record, true);
}
public function requestBreakoutJoinUrl(e:BreakoutRoomEvent):void{
sender.requestBreakoutJoinUrl(_conferenceParameters.meetingID, e.breakoutId, e.userId);
sender.requestBreakoutJoinUrl(_conferenceParameters.meetingID, e.breakoutMeetingId, e.userId, true);
}
public function listenInOnBreakout(e:BreakoutRoomEvent):void {
if (e.listen) {
sender.listenInOnBreakout(_conferenceParameters.meetingID, e.breakoutId, _conferenceParameters.userid);
sender.listenInOnBreakout(_conferenceParameters.meetingID, e.breakoutMeetingId, _conferenceParameters.userid);
} else {
sender.listenInOnBreakout(e.breakoutId, _conferenceParameters.meetingID, _conferenceParameters.userid);
sender.listenInOnBreakout(e.breakoutMeetingId, _conferenceParameters.meetingID, _conferenceParameters.userid);
}
UserManager.getInstance().getConference().setBreakoutRoomInListen(e.listen, e.breakoutId);
UserManager.getInstance().getConference().setBreakoutRoomInListen(e.listen, e.breakoutMeetingId);
}
public function endAllBreakoutRooms(e:BreakoutRoomEvent):void {

View File

@ -94,6 +94,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
messages.push(obj);
showNotification();
LOGGER.warn("ClientNotification:" + e.title + " " + e.message);
}
private function showNotification():void {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 332 B

View File

@ -1,36 +0,0 @@
/**
* 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.deskshare.events
{
import flash.events.Event;
public class CursorEvent extends Event
{
public static const UPDATE_CURSOR_LOC_EVENT:String = "Update sharer cursor event";
public var x:Number = 0;
public var y:Number = 0;
public function CursorEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,14 +0,0 @@
package org.bigbluebutton.modules.deskshare.events
{
import flash.events.Event;
public class DeskshareAppletLaunchedEvent extends Event
{
public static const APPLET_LAUNCHED:String = "DESKSHARE_APPLET_LAUNCHED_EVENT";
public function DeskshareAppletLaunchedEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,39 +0,0 @@
/**
* 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.deskshare.events
{
import flash.events.Event;
import org.bigbluebutton.common.IBigBlueButtonModule;
public class ModuleEvent extends Event
{
public static const START:String = "Deskshare Module Start Event";
public static const STOP:String = "Deskshare Module Stop Event";
public var module:IBigBlueButtonModule;
public function ModuleEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
this.module = module;
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,40 +0,0 @@
/**
* 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.deskshare.events
{
import flash.events.Event;
public class RecordingStatusEvent extends Event
{
public static const DESKSHARE_RECORD_EVENT:String = "DESKSHARE_RECORD_EVENT";
public static const RECORD_STOPPED_EVENT:String = "DESKSHARE_RECORD_STOPPED_EVENT";
public static const RECORD_STARTED_EVENT:String = "DESKSHARE_RECORD_STARTED_EVENT";
public static const RECORD_UPDATED_EVENT:String = "DESKSHARE_RECORD_UPDATED_EVENT";
public static const RECORD_ERROR_EVENT:String = "DESKSHARE_RECORD_ERROR_EVENT";
public var status:String;
public function RecordingStatusEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,34 +0,0 @@
/**
* 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.deskshare.events
{
import flash.events.Event;
public class ShareEvent extends Event
{
public static const START_SHARING:String = "START SHARING";
public static const STOP_SHARING:String = "STOP SHARING";
public function ShareEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,33 +0,0 @@
/**
* 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.deskshare.events
{
import flash.events.Event;
public class ShareWindowEvent extends Event
{
public static const CLOSE:String = "Deskshare Share Window Close Event";
public function ShareWindowEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,35 +0,0 @@
/**
* 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.deskshare.events
{
import flash.events.Event;
public class StartedViewingEvent extends Event
{
public static const STARTED_VIEWING_EVENT:String = "STARTED VIEWING DESKSHARE EVENT";
public var stream:String;
public function StartedViewingEvent(type: String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,33 +0,0 @@
/**
* 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.deskshare.events
{
import flash.events.Event;
public class StopSharingButtonEvent extends Event
{
public static const STOP_SHARING:String = "Stop Sharing Event";
public function StopSharingButtonEvent(type:String)
{
super(type, true, false);
}
}
}

View File

@ -1,37 +0,0 @@
/**
* 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.deskshare.events
{
import flash.events.Event;
public class StreamEvent extends Event
{
public static const START:String = "Deskshare Stream Started Event";
public static const STOP:String = "Deskshare Stream Stopped Event";
public var videoWidth:Number = 0;
public var videoHeight:Number = 0;
public function StreamEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,14 +0,0 @@
package org.bigbluebutton.modules.deskshare.events
{
import flash.events.Event;
public class UseJavaModeCommand extends Event
{
public static const USE_JAVA_MODE:String = "use Java to join deskshare event";
public function UseJavaModeCommand()
{
super(USE_JAVA_MODE, true, false);
}
}
}

View File

@ -1,37 +0,0 @@
/**
* 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.deskshare.events
{
import flash.events.Event;
public class ViewStreamEvent extends Event
{
public static const START:String = "Start Viewing Stream Event";
public static const STOP:String = "Stop Viewing Stream Event";
public var videoWidth:Number = 0;
public var videoHeight:Number = 0;
public function ViewStreamEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,33 +0,0 @@
/**
* 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.deskshare.events
{
import flash.events.Event;
public class ViewWindowEvent extends Event
{
public static const CLOSE:String = "Deskshare View Window Close Event";
public function ViewWindowEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,33 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2015 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.deskshare.events
{
import flash.events.Event;
public class WebRTCShareWindowEvent extends Event
{
public static const CLOSE:String = "WebRTC Deskshare Share Window Close Event";
public function WebRTCShareWindowEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,37 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2015 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.deskshare.events
{
import flash.events.Event;
public class WebRTCStreamEvent extends Event
{
public static const START:String = "WebRTC Deskshare Stream Started Event";
public static const STOP:String = "WebRTC Deskshare Stream Stopped Event";
public var videoWidth:Number = 0;
public var videoHeight:Number = 0;
public function WebRTCStreamEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,41 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2015 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.deskshare.events
{
import flash.events.Event;
import org.bigbluebutton.main.api.JSLog;
public class WebRTCViewStreamEvent extends Event
{
public static const START:String = "WebRTC Start Viewing Stream Event";
public static const STOP:String = "WebRTC Stop Viewing Stream Event";
public var videoWidth:Number = 0;
public var videoHeight:Number = 0;
public var rtmp:String = null;
public function WebRTCViewStreamEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
JSLog.warn("creating a WebRTCViewStreamEvent event " + type, null);
}
}
}

View File

@ -1,33 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2015 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.deskshare.events
{
import flash.events.Event;
public class WebRTCViewWindowEvent extends Event
{
public static const CLOSE:String = "WebRTC Deskshare View Window Close Event";
public function WebRTCViewWindowEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,174 +0,0 @@
/**
* 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.deskshare.managers
{
import com.asfusion.mate.events.Dispatcher;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.main.events.MadePresenterEvent;
import org.bigbluebutton.modules.deskshare.events.UseJavaModeCommand;
import org.bigbluebutton.modules.deskshare.model.DeskshareOptions;
import org.bigbluebutton.modules.deskshare.services.DeskshareService;
import org.bigbluebutton.modules.deskshare.utils.JavaCheck;
import org.bigbluebutton.modules.deskshare.utils.BrowserCheck;
import flash.external.ExternalInterface;
public class DeskshareManager {
private static const LOGGER:ILogger = getClassLogger(DeskshareManager);
private var publishWindowManager:PublishWindowManager;
private var viewWindowManager:ViewerWindowManager;
private var toolbarButtonManager:ToolbarButtonManager;
private var module:DeskShareModule;
private var service:DeskshareService;
private var globalDispatcher:Dispatcher;
private var sharing:Boolean = false;
private var usingJava:Boolean = true;
public function DeskshareManager() {
service = new DeskshareService();
globalDispatcher = new Dispatcher();
publishWindowManager = new PublishWindowManager(service);
viewWindowManager = new ViewerWindowManager(service);
toolbarButtonManager = new ToolbarButtonManager();
}
public function handleStartModuleEvent(module:DeskShareModule):void {
LOGGER.debug("Deskshare Module starting");
this.module = module;
service.handleStartModuleEvent(module);
if (UsersUtil.amIPresenter()) {
initDeskshare();
}
}
public function handleStopModuleEvent():void {
LOGGER.debug("Deskshare Module stopping");
publishWindowManager.stopSharing();
viewWindowManager.stopViewing();
service.disconnect();
}
public function handleStreamStoppedEvent():void {
LOGGER.debug("Sending deskshare stopped command");
service.stopSharingDesktop(module.getRoom(), module.getRoom());
}
public function handleStreamStartedEvent(videoWidth:Number, videoHeight:Number):void {
LOGGER.debug("Sending startViewing command");
service.sendStartViewingNotification(videoWidth, videoHeight);
}
public function handleStartedViewingEvent(stream:String):void {
LOGGER.debug("handleStartedViewingEvent [{0}]", [stream]);
service.sendStartedViewingNotification(stream);
}
private function initDeskshare():void {
sharing = false;
var options:DeskshareOptions = new DeskshareOptions();
options.parseOptions();
if (options.autoStart) {
handleStartSharingEvent(true);
}
if(options.showButton){
toolbarButtonManager.addToolbarButton();
}
}
public function handleMadePresenterEvent(e:MadePresenterEvent):void {
LOGGER.debug("Got MadePresenterEvent ");
initDeskshare();
}
public function handleMadeViewerEvent(e:MadePresenterEvent):void{
LOGGER.debug("Got MadeViewerEvent ");
toolbarButtonManager.removeToolbarButton();
if (sharing) {
publishWindowManager.stopSharing();
}
sharing = false;
}
public function handleStartSharingEvent(autoStart:Boolean):void {
LOGGER.debug("DeskshareManager::handleStartSharingEvent (Java)");
var options:DeskshareOptions = new DeskshareOptions();
options.parseOptions();
// falling back to java, or we can't use WebRTC
if (autoStart || (options.useWebRTCIfAvailable && !BrowserCheck.isWebRTCSupported())) {
if (BrowserCheck.isUsingLessThanChrome38OnMac()) {
usingJava = false;
publishWindowManager.startSharing(options.publishURI , options.useTLS , module.getRoom(), autoStart, options.autoFullScreen);
} else {
var javaIssue:String = JavaCheck.checkJava();
if (javaIssue != null) {
if (BrowserCheck.isChrome42OrHigher()) {
usingJava = false;
publishWindowManager.startSharing(options.publishURI , options.useTLS , module.getRoom(), autoStart, options.autoFullScreen);
} else {
usingJava = false;
publishWindowManager.startSharing(options.publishURI , options.useTLS , module.getRoom(), autoStart, options.autoFullScreen);
}
} else {
usingJava = true;
toolbarButtonManager.startedSharing();
publishWindowManager.startSharing(options.publishURI , options.useTLS , module.getRoom(), autoStart, options.autoFullScreen);
sharing = true;
}
}
} else {
// using WebRTC or not a fallback case
usingJava = false;
}
}
public function handleShareWindowCloseEvent():void {
//toolbarButtonManager.enableToolbarButton();
publishWindowManager.handleShareWindowCloseEvent();
sharing = false;
toolbarButtonManager.stopedSharing();
}
public function handleViewWindowCloseEvent():void {
LOGGER.debug("Received stop viewing command");
viewWindowManager.handleViewWindowCloseEvent();
}
public function handleStreamStartEvent(videoWidth:Number, videoHeight:Number):void{
if (!usingJava) { return; }
if (sharing) { return; }
LOGGER.debug("Received start viewing command");
viewWindowManager.startViewing(module.getRoom(), videoWidth, videoHeight);
}
public function handleUseJavaModeCommand():void {
usingJava = true;
handleStartSharingEvent(true);
}
}
}

View File

@ -1,107 +0,0 @@
/**
* 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.deskshare.managers
{
import com.asfusion.mate.events.Dispatcher;
import flash.events.TimerEvent;
import flash.utils.Timer;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.IBbbModuleWindow;
import org.bigbluebutton.common.events.CloseWindowEvent;
import org.bigbluebutton.common.events.OpenWindowEvent;
import org.bigbluebutton.modules.deskshare.services.DeskshareService;
import org.bigbluebutton.modules.deskshare.view.components.DesktopPublishWindow;
public class PublishWindowManager {
private static const LOGGER:ILogger = getClassLogger(PublishWindowManager);
private var shareWindow:DesktopPublishWindow;
private var globalDispatcher:Dispatcher;
private var service:DeskshareService;
private var buttonShownOnToolbar:Boolean = false;
private var isOpen:Boolean = false;
// Timer to auto-publish webcam. We need this timer to delay
// the auto-publishing until after the Viewers's window has loaded
// to receive the publishing events. Otherwise, the user joining next
// won't be able to view the webcam.
private var autoPublishTimer:Timer;
public function PublishWindowManager(service:DeskshareService) {
LOGGER.debug("PublishWindowManager init");
globalDispatcher = new Dispatcher();
this.service = service;
}
public function stopSharing():void {
if (shareWindow != null) {
shareWindow.stopSharing();
isOpen = false;
}
}
public function startSharing(uri:String , useTLS:Boolean , room:String, autoStart:Boolean, autoFullScreen:Boolean):void {
LOGGER.debug("DS:PublishWindowManager::opening desk share window, autostart={0} autoFullScreen={1}", [autoStart, autoFullScreen]);
if (isOpen) {
return;
}
isOpen = true;
shareWindow = new DesktopPublishWindow();
shareWindow.initWindow(service.getConnection(), uri , useTLS , room, autoStart, autoFullScreen);
shareWindow.visible = true;
openWindow(shareWindow);
if (autoStart || autoFullScreen) {
/*
* Need to have a timer to trigger auto-publishing of deskshare.
*/
shareWindow.btnFSPublish.enabled = false;
shareWindow.btnRegionPublish.enabled = false;
autoPublishTimer = new Timer(2000, 1);
autoPublishTimer.addEventListener(TimerEvent.TIMER, autopublishTimerHandler);
autoPublishTimer.start();
}
}
private function autopublishTimerHandler(event:TimerEvent):void {
shareWindow.shareScreen(true);
}
public function handleShareWindowCloseEvent():void {
closeWindow(shareWindow);
}
private function openWindow(window:IBbbModuleWindow):void {
isOpen = true;
var event:OpenWindowEvent = new OpenWindowEvent(OpenWindowEvent.OPEN_WINDOW_EVENT);
event.window = window;
globalDispatcher.dispatchEvent(event);
}
private function closeWindow(window:IBbbModuleWindow):void {
isOpen = false;
var event:CloseWindowEvent = new CloseWindowEvent(CloseWindowEvent.CLOSE_WINDOW_EVENT);
event.window = window;
globalDispatcher.dispatchEvent(event);
}
}
}

View File

@ -1,85 +0,0 @@
/**
* 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.deskshare.managers
{
import com.asfusion.mate.events.Dispatcher;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.events.ToolbarButtonEvent;
import org.bigbluebutton.modules.deskshare.view.components.ToolbarButton;
public class ToolbarButtonManager {
private static const LOGGER:ILogger = getClassLogger(ToolbarButtonManager);
private var button:ToolbarButton;
private var isSharing:Boolean = false;
private var globalDispatcher:Dispatcher;
private var buttonShownOnToolbar:Boolean = false;
public function ToolbarButtonManager() {
globalDispatcher = new Dispatcher();
button = new ToolbarButton();
}
public function addToolbarButton():void {
LOGGER.debug("DeskShare::addToolbarButton");
if ((button != null) && (!buttonShownOnToolbar)) {
button = new ToolbarButton();
/* Test */ //button.tabIndex=4;
var event:ToolbarButtonEvent = new ToolbarButtonEvent(ToolbarButtonEvent.ADD);
event.button = button;
event.module="DeskShare";
//event.tabIndex = 0;
globalDispatcher.dispatchEvent(event);
buttonShownOnToolbar = true;
button.enabled = true;
}
}
public function removeToolbarButton():void {
if (buttonShownOnToolbar) {
var event:ToolbarButtonEvent = new ToolbarButtonEvent(ToolbarButtonEvent.REMOVE);
event.button = button;
globalDispatcher.dispatchEvent(event);
buttonShownOnToolbar = false;
}
}
//OLD - CAN BE DELETED
public function enableToolbarButton():void {
button.enabled = true;
button.stopDeskshare();
}
//OLD - CAN BE DELETED
public function disableToolbarButton():void {
button.enabled = false;
}
public function startedSharing():void {
button.deskshareStatus(button.START_SHARING);
}
public function stopedSharing():void {
button.deskshareStatus(button.STOP_SHARING);
}
}
}

View File

@ -1,81 +0,0 @@
/**
* 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.deskshare.managers
{
import com.asfusion.mate.events.Dispatcher;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.IBbbModuleWindow;
import org.bigbluebutton.common.events.CloseWindowEvent;
import org.bigbluebutton.common.events.OpenWindowEvent;
import org.bigbluebutton.modules.deskshare.services.DeskshareService;
import org.bigbluebutton.modules.deskshare.view.components.DesktopViewWindow;
public class ViewerWindowManager {
private static const LOGGER:ILogger = getClassLogger(ViewerWindowManager);
private var viewWindow:DesktopViewWindow;
private var service:DeskshareService;
private var isViewing:Boolean = false;
private var globalDispatcher:Dispatcher;
public function ViewerWindowManager(service:DeskshareService) {
this.service = service;
globalDispatcher = new Dispatcher();
}
public function stopViewing():void {
if (isViewing) viewWindow.stopViewing();
}
public function handleStartedViewingEvent(stream:String):void{
LOGGER.debug("ViewerWindowManager handleStartedViewingEvent");
service.sendStartedViewingNotification(stream);
}
private function openWindow(window:IBbbModuleWindow):void{
var event:OpenWindowEvent = new OpenWindowEvent(OpenWindowEvent.OPEN_WINDOW_EVENT);
event.window = window;
globalDispatcher.dispatchEvent(event);
}
public function handleViewWindowCloseEvent():void {
LOGGER.debug("ViewerWindowManager Received stop viewing command");
closeWindow(viewWindow);
isViewing = false;
}
private function closeWindow(window:IBbbModuleWindow):void {
var event:CloseWindowEvent = new CloseWindowEvent(CloseWindowEvent.CLOSE_WINDOW_EVENT);
event.window = window;
globalDispatcher.dispatchEvent(event);
}
public function startViewing(room:String, videoWidth:Number, videoHeight:Number):void{
LOGGER.debug("ViewerWindowManager::startViewing");
viewWindow = new DesktopViewWindow();
viewWindow.startVideo(service.getConnection(), room, videoWidth, videoHeight);
openWindow(viewWindow);
isViewing = true;
}
}
}

View File

@ -1,264 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2015 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.deskshare.managers
{
import com.asfusion.mate.events.Dispatcher;
import flash.external.ExternalInterface;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.main.events.MadePresenterEvent;
import org.bigbluebutton.modules.deskshare.events.UseJavaModeCommand;
import org.bigbluebutton.modules.deskshare.events.WebRTCViewStreamEvent;
import org.bigbluebutton.modules.deskshare.model.DeskshareOptions;
import org.bigbluebutton.modules.deskshare.events.ShareWindowEvent;
import org.bigbluebutton.modules.deskshare.services.WebRTCDeskshareService;
import org.bigbluebutton.modules.deskshare.utils.BrowserCheck;
import org.bigbluebutton.main.api.JSLog;
public class WebRTCDeskshareManager {
private static const LOGGER:ILogger = getClassLogger(WebRTCDeskshareManager);
private var publishWindowManager:WebRTCPublishWindowManager;
private var viewWindowManager:WebRTCViewerWindowManager;
private var toolbarButtonManager:ToolbarButtonManager;
private var module:DeskShareModule;
private var service:WebRTCDeskshareService;
private var globalDispatcher:Dispatcher;
private var sharing:Boolean = false;
private var usingWebRTC:Boolean = false;
private var chromeExtensionKey:String = null;
private var vertoServerCredentials:Object = new Object();
public function WebRTCDeskshareManager() {
service = new WebRTCDeskshareService();
globalDispatcher = new Dispatcher();
publishWindowManager = new WebRTCPublishWindowManager(service);
viewWindowManager = new WebRTCViewerWindowManager(service);
}
public function handleStartModuleEvent(module:DeskShareModule):void {
LOGGER.debug("WebRTC Deskshare Module starting");
this.module = module;
service.handleStartModuleEvent(module);
if (UsersUtil.amIPresenter()) {
initDeskshare();
}
}
public function handleStopModuleEvent():void {
LOGGER.debug("WebRTC Deskshare Module stopping");
publishWindowManager.stopSharing();
viewWindowManager.stopViewing();
service.disconnect();
}
/*presenter stopped their program stream*/
public function handleStreamStoppedEvent():void {
LOGGER.debug("DeskshareManager::handleStreamStoppedEvent Sending deskshare stopped command");
JSLog.warn("WebRTCDeskshareManager::handleStreamStoppedEvent", {});
stopWebRTCDeskshare();
}
/*viewer being told there is no more stream*/
public function handleStreamStopEvent(args:Object):void {
LOGGER.debug("WebRTCDeskshareManager::handleStreamStopEvent");
JSLog.warn("WebRTCDeskshareManager::handleStreamStopEvent", {});
viewWindowManager.handleViewWindowCloseEvent();
}
private function stopWebRTCDeskshare():void {
LOGGER.debug("DeskshareManager::stopWebRTCDeskshare");
viewWindowManager.stopViewing();
/* stopping WebRTC deskshare. Alert DeskshareManager to reset toolbar */
globalDispatcher.dispatchEvent(new ShareWindowEvent(ShareWindowEvent.CLOSE));
if (ExternalInterface.available) {
var loggingCallback:Function = function(args:Object):void {LOGGER.debug(args); JSLog.warn("loggingCallback", args)};
var onSuccess:Function = function():void { LOGGER.debug("onSuccess"); JSLog.warn("onSuccess - as", {})};
ExternalInterface.addCallback("loggingCallback", loggingCallback);
ExternalInterface.addCallback("onSuccess", onSuccess);
ExternalInterface.call("endScreenshare", "loggingCallback", "onSuccess");
} else {
LOGGER.error("Error! ExternalInterface not available (webrtcDeskshare)");
}
}
private function startWebRTCDeskshare():void {
LOGGER.debug("DeskshareManager::startWebRTCDeskshare");
if (ExternalInterface.available) {
var videoTag:String = "localVertoVideo";
var onFail:Function = function(args:Object):void {
JSLog.warn("onFail - as", args);
JSLog.warn("WebRTCDeskshareManager::startWebRTCDeskshare - falling back to java", {});
globalDispatcher.dispatchEvent(new UseJavaModeCommand())
};
ExternalInterface.addCallback("onFail", onFail);
ExternalInterface.call(
'vertoShareScreen',
videoTag,
'3500',
'FreeSWITCH USers - abc',
'1008',
null,
vertoServerCredentials,
chromeExtensionKey,
onFail
);
}
}
private function initDeskshare():void {
sharing = false;
var options:DeskshareOptions = new DeskshareOptions();
options.parseOptions();
if (options.chromeExtensionKey) {
chromeExtensionKey = options.chromeExtensionKey;
}
if (options.vertoPort) {
vertoServerCredentials.vertoPort = options.vertoPort;
}
if (options.hostName) {
vertoServerCredentials.hostName = options.hostName;
}
if (options.login) {
vertoServerCredentials.login = options.login;
}
if (options.password) {
vertoServerCredentials.password = options.password;
}
if (options.autoStart) {
handleStartSharingEvent(true);
}
}
public function handleMadePresenterEvent(e:MadePresenterEvent):void {
LOGGER.debug("Got MadePresenterEvent ");
initDeskshare();
}
public function handleMadeViewerEvent(e:MadePresenterEvent):void{
LOGGER.debug("Got MadeViewerEvent ");
if (sharing) {
publishWindowManager.stopSharing();
stopWebRTCDeskshare();
}
sharing = false;
}
private function canIUseVertoOnThisBrowser(onFailure:Function, onSuccess:Function):void {
LOGGER.debug("DeskshareManager::canIUseVertoOnThisBrowser");
var options:DeskshareOptions = new DeskshareOptions();
options.parseOptions();
if (options.useWebRTCIfAvailable && BrowserCheck.isWebRTCSupported()) {
JSLog.warn("WebRTCDeskshareManager::handleStartSharingEvent WebRTC Supported", {});
if (BrowserCheck.isFirefox()) {
onSuccess("Firefox, lets try");
} else {
if (chromeExtensionKey != null) {
/*toolbarButtonManager.startedSharing();*/
JSLog.warn("WebRTCDeskshareManager::handleStartSharingEvent chrome extension key exists - ", chromeExtensionKey);
if (ExternalInterface.available) {
var success:Function = function(status:String):void {
ExternalInterface.addCallback("callback", null);
JSLog.warn("WebRTCDeskshareManager::handleStartSharingEvent inside onSuccess", {});
if (status == "installed-enabled") {
JSLog.warn("Chrome Extension exists", {});
onSuccess("worked");
} else {
onFailure("No Chrome Extension");
}
};
ExternalInterface.addCallback("callback", success);
ExternalInterface.call("getChromeExtensionStatus", chromeExtensionKey, "callback");
}
} else {
onFailure("No chromeExtensionKey in config.xml");
return;
}
}
} else {
onFailure("Web browser doesn't support WebRTC");
return;
}
}
/*handle start sharing event*/
public function handleStartSharingEvent(autoStart:Boolean):void {
LOGGER.debug("WebRTCDeskshareManager::handleStartSharingEvent");
JSLog.warn("WebRTCDeskshareManager::handleStartSharingEvent", {});
var onFailure:Function = function(message:String):void {
JSLog.warn(message, {});
usingWebRTC = false;
// send out event to fallback to Java
JSLog.warn("WebRTCDeskshareManager::handleStartSharingEvent - falling back to java", {});
globalDispatcher.dispatchEvent(new UseJavaModeCommand());
return;
};
var onSuccess:Function = function(message:String):void {
JSLog.warn(message, {});
usingWebRTC = true;
startWebRTCDeskshare();
};
canIUseVertoOnThisBrowser(onFailure, onSuccess);
}
public function handleShareWindowCloseEvent():void {
publishWindowManager.handleShareWindowCloseEvent();
sharing = false;
stopWebRTCDeskshare();
}
public function handleViewWindowCloseEvent():void {
LOGGER.debug("Received stop viewing command");
JSLog.warn("WebRTCDeskshareManager::handleViewWindowCloseEvent", {});
viewWindowManager.handleViewWindowCloseEvent();
}
public function handleStreamStartEvent(e:WebRTCViewStreamEvent):void{
// if (!usingWebRTC) { return; } //TODO this was causing issues
if (sharing) return; //TODO must uncomment this for the non-webrtc desktop share
var isPresenter:Boolean = UserManager.getInstance().getConference().amIPresenter;
LOGGER.debug("Received start viewing command when isPresenter==[{0}]",[isPresenter]);
if(isPresenter) {
publishWindowManager.startViewing(e.rtmp, e.videoWidth, e.videoHeight);
} else {
viewWindowManager.startViewing(e.rtmp, e.videoWidth, e.videoHeight);
}
sharing = true; //TODO must uncomment this for the non-webrtc desktop share
}
public function handleUseJavaModeCommand():void {
usingWebRTC = false;
}
}
}

View File

@ -1,86 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2015 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.deskshare.managers
{
import com.asfusion.mate.events.Dispatcher;
import flash.events.TimerEvent;
import flash.utils.Timer;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.IBbbModuleWindow;
import org.bigbluebutton.common.events.CloseWindowEvent;
import org.bigbluebutton.common.events.OpenWindowEvent;
import org.bigbluebutton.modules.deskshare.services.WebRTCDeskshareService;
import org.bigbluebutton.modules.deskshare.view.components.WebRTCDesktopPublishWindow;
public class WebRTCPublishWindowManager {
private static const LOGGER:ILogger = getClassLogger(PublishWindowManager);
private var shareWindow:WebRTCDesktopPublishWindow;
private var globalDispatcher:Dispatcher;
private var service:WebRTCDeskshareService;
private var buttonShownOnToolbar:Boolean = false;
// Timer to auto-publish webcam. We need this timer to delay
// the auto-publishing until after the Viewers's window has loaded
// to receive the publishing events. Otherwise, the user joining next
// won't be able to view the webcam.
private var autoPublishTimer:Timer;
public function WebRTCPublishWindowManager(service:WebRTCDeskshareService) {
LOGGER.debug("PublishWindowManager init");
globalDispatcher = new Dispatcher();
this.service = service;
}
public function stopSharing():void {
if (shareWindow != null) shareWindow.stopSharing();
}
private function autopublishTimerHandler(event:TimerEvent):void {
shareWindow.shareScreen(true);
}
public function handleShareWindowCloseEvent():void {
closeWindow(shareWindow);
}
private function openWindow(window:IBbbModuleWindow):void {
var event:OpenWindowEvent = new OpenWindowEvent(OpenWindowEvent.OPEN_WINDOW_EVENT);
event.window = window;
globalDispatcher.dispatchEvent(event);
}
private function closeWindow(window:IBbbModuleWindow):void {
var event:CloseWindowEvent = new CloseWindowEvent(CloseWindowEvent.CLOSE_WINDOW_EVENT);
event.window = window;
globalDispatcher.dispatchEvent(event);
}
public function startViewing(rtmp:String, videoWidth:Number, videoHeight:Number):void{
shareWindow = new WebRTCDesktopPublishWindow();
shareWindow.visible = true;
openWindow(shareWindow);
shareWindow.startVideo(rtmp, videoWidth, videoHeight);
}
}
}

View File

@ -1,78 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2015 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.deskshare.managers
{
import com.asfusion.mate.events.Dispatcher;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.IBbbModuleWindow;
import org.bigbluebutton.common.events.CloseWindowEvent;
import org.bigbluebutton.common.events.OpenWindowEvent;
import org.bigbluebutton.modules.deskshare.services.WebRTCDeskshareService;
import org.bigbluebutton.modules.deskshare.view.components.WebRTCDesktopPublishWindow;
import org.bigbluebutton.modules.deskshare.view.components.WebRTCDesktopViewWindow;
public class WebRTCViewerWindowManager {
private static const LOGGER:ILogger = getClassLogger(ViewerWindowManager);
private var viewWindow:WebRTCDesktopViewWindow;
private var shareWindow:WebRTCDesktopPublishWindow;
private var service:WebRTCDeskshareService;
private var isViewing:Boolean = false;
private var globalDispatcher:Dispatcher;
public function WebRTCViewerWindowManager(service:WebRTCDeskshareService) {
this.service = service;
globalDispatcher = new Dispatcher();
}
public function stopViewing():void {
if (isViewing) viewWindow.stopViewing();
}
private function openWindow(window:IBbbModuleWindow):void{
var event:OpenWindowEvent = new OpenWindowEvent(OpenWindowEvent.OPEN_WINDOW_EVENT);
event.window = window;
globalDispatcher.dispatchEvent(event);
}
public function handleViewWindowCloseEvent():void {
LOGGER.debug("ViewerWindowManager Received stop viewing command");
closeWindow(viewWindow);
isViewing = false;
}
private function closeWindow(window:IBbbModuleWindow):void {
var event:CloseWindowEvent = new CloseWindowEvent(CloseWindowEvent.CLOSE_WINDOW_EVENT);
event.window = window;
globalDispatcher.dispatchEvent(event);
}
public function startViewing(rtmp:String, videoWidth:Number, videoHeight:Number):void{
LOGGER.debug("ViewerWindowManager::startViewing");
viewWindow = new WebRTCDesktopViewWindow();
viewWindow.startVideo(rtmp, videoWidth, videoHeight);
openWindow(viewWindow);
isViewing = true;
}
}
}

View File

@ -1,103 +0,0 @@
<?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/>.
-->
<EventMap xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns="http://mate.asfusion.com/">
<mx:Script>
<![CDATA[
import mx.events.FlexEvent;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.main.events.MadePresenterEvent;
import org.bigbluebutton.modules.deskshare.events.ModuleEvent;
import org.bigbluebutton.modules.deskshare.events.ShareEvent;
import org.bigbluebutton.modules.deskshare.events.ShareWindowEvent;
import org.bigbluebutton.modules.deskshare.events.StartedViewingEvent;
import org.bigbluebutton.modules.deskshare.events.StreamEvent;
import org.bigbluebutton.modules.deskshare.events.UseJavaModeCommand;
import org.bigbluebutton.modules.deskshare.events.ViewStreamEvent;
import org.bigbluebutton.modules.deskshare.events.ViewWindowEvent;
import org.bigbluebutton.modules.deskshare.managers.DeskshareManager;
]]>
</mx:Script>
<EventHandlers type="{FlexEvent.PREINITIALIZE}">
<!--
The FlexEvent.PREINITIALIZE event is a good place for creating and initializing managers.
-->
<ObjectBuilder generator="{DeskshareManager}"/>
</EventHandlers>
<EventHandlers type="{ShareEvent.START_SHARING}">
<MethodInvoker generator="{DeskshareManager}" method="handleStartSharingEvent" arguments="{false}"/>
</EventHandlers>
<EventHandlers type="{BBBEvent.START_DESKSHARE}">
<MethodInvoker generator="{DeskshareManager}" method="handleStartSharingEvent" arguments="{true}"/>
</EventHandlers>
<EventHandlers type="{MadePresenterEvent.SWITCH_TO_PRESENTER_MODE}">
<MethodInvoker generator="{DeskshareManager}" method="handleMadePresenterEvent" arguments="{event}"/>
</EventHandlers>
<EventHandlers type="{MadePresenterEvent.SWITCH_TO_VIEWER_MODE}">
<MethodInvoker generator="{DeskshareManager}" method="handleMadeViewerEvent" arguments="{event}"/>
</EventHandlers>
<EventHandlers type="{StreamEvent.START}">
<MethodInvoker generator="{DeskshareManager}" method="handleStreamStartedEvent" arguments="{[event.videoWidth, event.videoHeight]}"/>
</EventHandlers>
<EventHandlers type="{StreamEvent.STOP}" >
<MethodInvoker generator="{DeskshareManager}" method="handleStreamStoppedEvent"/>
</EventHandlers>
<EventHandlers type="{ViewStreamEvent.START}">
<MethodInvoker generator="{DeskshareManager}" method="handleStreamStartEvent" arguments="{[event.videoWidth, event.videoHeight]}"/>
</EventHandlers>
<EventHandlers type="{ShareWindowEvent.CLOSE}">
<MethodInvoker generator="{DeskshareManager}" method="handleShareWindowCloseEvent"/>
</EventHandlers>
<EventHandlers type="{StartedViewingEvent.STARTED_VIEWING_EVENT}">
<MethodInvoker generator="{DeskshareManager}" method="handleStartedViewingEvent" arguments="{event.stream}"/>
</EventHandlers>
<EventHandlers type="{ViewWindowEvent.CLOSE}">
<MethodInvoker generator="{DeskshareManager}" method="handleViewWindowCloseEvent"/>
</EventHandlers>
<EventHandlers type="{UseJavaModeCommand.USE_JAVA_MODE}">
<MethodInvoker generator="{DeskshareManager}" method="handleUseJavaModeCommand"/>
</EventHandlers>
<EventHandlers type="{ModuleEvent.STOP}">
<MethodInvoker generator="{DeskshareManager}" method="handleStopModuleEvent"/>
</EventHandlers>
<EventHandlers type="{ModuleEvent.START}">
<MethodInvoker generator="{DeskshareManager}" method="handleStartModuleEvent" arguments="{event.module}"/>
</EventHandlers>
</EventMap>

View File

@ -1,98 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
Copyright (c) 2015 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/>.
-->
<EventMap xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns="http://mate.asfusion.com/">
<mx:Script>
<![CDATA[
import mx.events.FlexEvent;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.main.events.MadePresenterEvent;
import org.bigbluebutton.modules.deskshare.events.ModuleEvent;
import org.bigbluebutton.modules.deskshare.events.ShareEvent;
import org.bigbluebutton.modules.deskshare.events.UseJavaModeCommand;
import org.bigbluebutton.modules.deskshare.events.WebRTCShareWindowEvent;
import org.bigbluebutton.modules.deskshare.events.WebRTCStreamEvent;
import org.bigbluebutton.modules.deskshare.events.WebRTCViewStreamEvent;
import org.bigbluebutton.modules.deskshare.events.WebRTCViewWindowEvent;
import org.bigbluebutton.modules.deskshare.managers.WebRTCDeskshareManager;
]]>
</mx:Script>
<EventHandlers type="{FlexEvent.PREINITIALIZE}">
<!--
The FlexEvent.PREINITIALIZE event is a good place for creating and initializing managers.
-->
<ObjectBuilder generator="{WebRTCDeskshareManager}"/>
</EventHandlers>
<EventHandlers type="{ShareEvent.START_SHARING}">
<MethodInvoker generator="{WebRTCDeskshareManager}" method="handleStartSharingEvent" arguments="{false}"/>
</EventHandlers>
<EventHandlers type="{BBBEvent.START_DESKSHARE}">
<MethodInvoker generator="{WebRTCDeskshareManager}" method="handleStartSharingEvent" arguments="{true}"/>
</EventHandlers>
<EventHandlers type="{MadePresenterEvent.SWITCH_TO_PRESENTER_MODE}">
<MethodInvoker generator="{WebRTCDeskshareManager}" method="handleMadePresenterEvent" arguments="{event}"/>
</EventHandlers>
<EventHandlers type="{MadePresenterEvent.SWITCH_TO_VIEWER_MODE}">
<MethodInvoker generator="{WebRTCDeskshareManager}" method="handleMadeViewerEvent" arguments="{event}"/>
</EventHandlers>
<EventHandlers type="{WebRTCStreamEvent.STOP}" >
<MethodInvoker generator="{WebRTCDeskshareManager}" method="handleStreamStoppedEvent"/>
</EventHandlers>
<EventHandlers type="{WebRTCViewStreamEvent.START}">
<MethodInvoker generator="{WebRTCDeskshareManager}" method="handleStreamStartEvent" arguments="{event}"/>
</EventHandlers>
<EventHandlers type="{WebRTCViewStreamEvent.STOP}">
<MethodInvoker generator="{WebRTCDeskshareManager}" method="handleStreamStopEvent" arguments="{event}"/>
</EventHandlers>
<EventHandlers type="{WebRTCShareWindowEvent.CLOSE}">
<MethodInvoker generator="{WebRTCDeskshareManager}" method="handleShareWindowCloseEvent"/>
</EventHandlers>
<EventHandlers type="{WebRTCViewWindowEvent.CLOSE}">
<MethodInvoker generator="{WebRTCDeskshareManager}" method="handleViewWindowCloseEvent"/>
</EventHandlers>
<EventHandlers type="{UseJavaModeCommand.USE_JAVA_MODE}">
<MethodInvoker generator="{WebRTCDeskshareManager}" method="handleUseJavaModeCommand"/>
</EventHandlers>
<EventHandlers type="{ModuleEvent.STOP}">
<MethodInvoker generator="{WebRTCDeskshareManager}" method="handleStopModuleEvent"/>
</EventHandlers>
<EventHandlers type="{ModuleEvent.START}">
<MethodInvoker generator="{WebRTCDeskshareManager}" method="handleStartModuleEvent" arguments="{event.module}"/>
</EventHandlers>
</EventMap>

View File

@ -1,90 +0,0 @@
/**
* 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.deskshare.model
{
import flash.external.ExternalInterface;
import org.bigbluebutton.core.BBB;
public class DeskshareOptions
{
[Bindable] public var showButton:Boolean = true;
[Bindable] public var autoStart:Boolean = false;
[Bindable] public var autoFullScreen:Boolean = false;
public var useTLS:Boolean = false;
[Bindable] public var baseTabIndex:int;
public var publishURI:String;
[Bindable] public var useWebRTCIfAvailable:Boolean = true;
[Bindable] public var chromeExtensionKey:String = null;
[Bindable] public var vertoPort:String = null;
[Bindable] public var hostName:String = null;
[Bindable] public var login:String = null;
[Bindable] public var password:String = null;
public function parseOptions():void {
var vxml:XML = BBB.getConfigForModule("DeskShareModule");
if (vxml != null) {
publishURI = "";
if (vxml.@publishURI != undefined){
publishURI = vxml.@publishURI.toString();
}
if (vxml.@autoStart != undefined) {
autoStart = (vxml.@autoStart.toString().toUpperCase() == "TRUE") ? true : false;
}
if (vxml.@useTLS != undefined){
useTLS = (vxml.@useTLS.toString().toUpperCase() == "TRUE") ? true : false;
}
if (vxml.@autoFullScreen != undefined){
autoFullScreen = (vxml.@autoFullScreen.toString().toUpperCase() == "TRUE") ? true : false;
}
if (vxml.@baseTabIndex != undefined) {
baseTabIndex = vxml.@baseTabIndex;
}
else{
baseTabIndex = 201;
}
if (vxml.@showButton != undefined){
showButton = (vxml.@showButton.toString().toUpperCase() == "TRUE") ? true : false;
// If we are using Puffin browser
if (ExternalInterface.call("determineBrowser")[0] == "Puffin") {
showButton = false;
}
}
if (vxml.@useWebRTCIfAvailable != undefined) {
useWebRTCIfAvailable = (vxml.@useWebRTCIfAvailable.toString().toUpperCase() == "TRUE");
}
if (vxml.@chromeExtensionKey != undefined) {
chromeExtensionKey = vxml.@chromeExtensionKey.toString();
}
if (vxml.@vertoPort != undefined) {
vertoPort = vxml.@vertoPort.toString();
}
if (vxml.@hostName != undefined) {
hostName = vxml.@hostName.toString();
}
if (vxml.@login != undefined) {
login = vxml.@login.toString();
}
if (vxml.@password != undefined) {
password = vxml.@password.toString();
}
}
}
}
}

View File

@ -1,89 +0,0 @@
/**
* 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.deskshare.services
{
import com.asfusion.mate.events.Dispatcher;
import flash.net.NetConnection;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.modules.deskshare.services.red5.Connection;
/**
* The DeskShareProxy communicates with the Red5 deskShare server application
* @author Snap
*
*/
public class DeskshareService
{
private static const LOGGER:ILogger = getClassLogger(DeskshareService);
private var conn:Connection;
private var module:DeskShareModule;
private var dispatcher:Dispatcher;
private var uri:String;
private var room:String;
public function DeskshareService() {
this.dispatcher = new Dispatcher();
}
public function handleStartModuleEvent(module:DeskShareModule):void {
LOGGER.debug("Deskshare Module starting");
this.module = module;
connect(module.uri, module.getRoom());
}
public function connect(uri:String, room:String):void {
this.uri = uri;
this.room = room;
LOGGER.debug("Deskshare Service connecting to {0}", [uri]);
conn = new Connection(room);
conn.setURI(uri);
conn.connect();
}
public function getConnection():NetConnection{
return conn.getConnection();
}
public function disconnect():void{
conn.disconnect();
}
public function sendStartViewingNotification(captureWidth:Number, captureHeight:Number):void{
conn.sendStartViewingNotification(captureWidth, captureHeight);
}
public function sendStartedViewingNotification(stream:String):void{
conn.sendStartedViewingNotification(stream);
}
public function stopSharingDesktop(meetingId: String, stream: String):void {
conn.stopSharingDesktop(meetingId, stream);
}
}
}

View File

@ -1,74 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2015 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.deskshare.services
{
import com.asfusion.mate.events.Dispatcher;
import flash.net.NetConnection;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.modules.deskshare.services.red5.WebRTCConnection;
/**
* The DeskShareProxy communicates with the Red5 deskShare server application
* @author Snap
*
*/
public class WebRTCDeskshareService
{
private static const LOGGER:ILogger = getClassLogger(DeskshareService);
private var conn:WebRTCConnection;
private var module:DeskShareModule;
private var dispatcher:Dispatcher;
private var uri:String;
private var room:String;
public function WebRTCDeskshareService() {
this.dispatcher = new Dispatcher();
}
public function handleStartModuleEvent(module:DeskShareModule):void {
LOGGER.debug("Deskshare Module starting");
this.module = module;
connect(module.uri, module.getRoom());
}
public function connect(uri:String, room:String):void {
this.uri = uri;
this.room = room;
LOGGER.debug("Deskshare Service connecting to {0}", [uri]);
conn = new WebRTCConnection(room); //to red5 deskshare
conn.setURI(uri);
conn.connect();
}
public function getConnection():NetConnection{
return conn.getConnection();
}
public function disconnect():void{
conn.disconnect();
}
}
}

View File

@ -1,411 +0,0 @@
/**
* 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.deskshare.services.red5
{
import com.asfusion.mate.events.Dispatcher;
import flash.events.AsyncErrorEvent;
import flash.events.NetStatusEvent;
import flash.events.SecurityErrorEvent;
import flash.events.TimerEvent;
import flash.net.NetConnection;
import flash.net.ObjectEncoding;
import flash.net.Responder;
import flash.net.SharedObject;
import flash.utils.Timer;
import mx.utils.ObjectUtil;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.core.managers.ReconnectionManager;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.modules.deskshare.events.AppletStartedEvent;
import org.bigbluebutton.modules.deskshare.events.CursorEvent;
import org.bigbluebutton.modules.deskshare.events.ViewStreamEvent;
public class Connection {
private static const LOGGER:ILogger = getClassLogger(Connection);
private var nc:NetConnection;
private var uri:String;
private var retryTimer:Timer = null;
private var retryCount:int = 0;
private const MAX_RETRIES:int = 5;
private var deskSO:SharedObject;
private var responder:Responder;
private var width:Number;
private var height:Number;
private var room:String;
private var logoutOnUserCommand:Boolean = false;
private var reconnecting:Boolean = false;
private var wasPresenterBeforeDisconnect:Boolean = false;
private var dispatcher:Dispatcher = new Dispatcher();
public function Connection(room:String) {
this.room = room;
responder = new Responder(
function(result:Object):void {
if (result != null && (result.publishing as Boolean)){
width = result.width as Number;
height = result.height as Number;
LOGGER.debug("Desk Share stream is streaming [{0},{1}]", [width, height]);
var event:ViewStreamEvent = new ViewStreamEvent(ViewStreamEvent.START);
event.videoWidth = width;
event.videoHeight = height;
dispatcher.dispatchEvent(event);
} else {
LOGGER.debug("No deskshare stream being published");
var connEvent:ConnectionEvent = new ConnectionEvent();
connEvent.status = ConnectionEvent.NO_DESKSHARE_STREAM;
dispatcher.dispatchEvent(connEvent);
}
},
function(status:Object):void{
var checkFailedEvent:ConnectionEvent = new ConnectionEvent();
checkFailedEvent.status = ConnectionEvent.FAIL_CHECK_FOR_DESKSHARE_STREAM;
dispatcher.dispatchEvent(checkFailedEvent);
LOGGER.debug("Error while trying to call remote mathod on server");
}
);
}
public function connect(retry:Boolean = false):void {
nc = new NetConnection();
nc.proxyType = "best";
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);
if (getURI().length == 0){
LOGGER.error("please provide a valid URI connection string. URI Connection String missing");
return;
} else if (nc.connected){
LOGGER.error("You are already connected to {0}", [getURI()]);
return;
}
LOGGER.debug("Trying to connect to [{0}] retry=[{1}]", [getURI(), retry]);
if (! (retryCount > 0)) {
var ce:ConnectionEvent = new ConnectionEvent();
ce.status = ConnectionEvent.CONNECTING;
dispatcher.dispatchEvent(ce);
}
nc.connect(getURI(), UsersUtil.getInternalMeetingID());
}
private function connectTimeoutHandler(e:TimerEvent):void {
LOGGER.debug("Connection attempt to [{0}] timedout. Retrying.", [getURI()]);
retryTimer.stop();
retryTimer = null;
nc.close();
nc = null;
var ce:ConnectionEvent = new ConnectionEvent();;
retryCount++;
if (retryCount < MAX_RETRIES) {
ce.status = ConnectionEvent.CONNECTING_RETRY;
ce.retryAttempts = retryCount;
dispatcher.dispatchEvent(ce);
connect(false);
} else {
ce.status = ConnectionEvent.CONNECTING_MAX_RETRY;
dispatcher.dispatchEvent(ce);
}
}
public function close():void{
nc.close();
}
public function setURI(p_URI:String):void{
uri = p_URI;
}
public function getURI():String{
return uri;
}
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
LOGGER.debug("bandwidth = {0} Kbps.", [p_bw]);
}
private function netStatusHandler(event:NetStatusEvent):void {
LOGGER.debug("Connected to [" + getURI() + "]. [" + event.info.code + "]");
if (retryTimer) {
retryCount = 0;
LOGGER.debug("Cancelling retry timer.");
retryTimer.stop();
retryTimer = null;
}
var ce:ConnectionEvent = new ConnectionEvent();
switch(event.info.code){
case "NetConnection.Connect.Failed":
if (reconnecting) {
var attemptFailedEvent:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_CONNECTION_ATTEMPT_FAILED_EVENT);
attemptFailedEvent.payload.type = ReconnectionManager.DESKSHARE_CONNECTION;
dispatcher.dispatchEvent(attemptFailedEvent);
}
ce.status = ConnectionEvent.FAILED;
dispatcher.dispatchEvent(ce);
break;
case "NetConnection.Connect.Success":
ce.status = ConnectionEvent.SUCCESS;
if (reconnecting) {
reconnecting = false;
if (wasPresenterBeforeDisconnect) {
wasPresenterBeforeDisconnect = false;
stopSharingDesktop(room, room)
}
var attemptSucceeded:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_CONNECTION_ATTEMPT_SUCCEEDED_EVENT);
attemptSucceeded.payload.type = ReconnectionManager.DESKSHARE_CONNECTION;
dispatcher.dispatchEvent(attemptSucceeded);
}
dispatcher.dispatchEvent(ce);
connectionSuccessHandler();
break;
case "NetConnection.Connect.Rejected":
ce.status = ConnectionEvent.REJECTED;
dispatcher.dispatchEvent(ce);
break;
case "NetConnection.Connect.Closed":
LOGGER.debug("Deskshare connection closed.");
ce.status = ConnectionEvent.CLOSED;
if (UsersUtil.amIPresenter()) {
// Let's keep our presenter status before disconnected. We can't
// tell the other user's to stop desktop sharing as our connection is broken. (ralam july 24, 2015)
wasPresenterBeforeDisconnect = true;
} else {
stopViewing();
}
if (!logoutOnUserCommand) {
reconnecting = true;
var disconnectedEvent:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_DISCONNECTED_EVENT);
disconnectedEvent.payload.type = ReconnectionManager.DESKSHARE_CONNECTION;
disconnectedEvent.payload.callback = connect;
disconnectedEvent.payload.callbackParameters = [];
dispatcher.dispatchEvent(disconnectedEvent);
}
break;
case "NetConnection.Connect.InvalidApp":
ce.status = ConnectionEvent.INVALIDAPP;
dispatcher.dispatchEvent(ce);
break;
case "NetConnection.Connect.AppShutdown":
ce.status = ConnectionEvent.APPSHUTDOWN;
dispatcher.dispatchEvent(ce);
break;
case "NetConnection.Connect.NetworkChange":
LOGGER.info("Detected network change. User might be on a wireless and temporarily dropped connection. Doing nothing. Just making a note.");
break;
default :
// I dispatch DISCONNECTED incase someone just simply wants to know if we're not connected'
// rather than having to subscribe to the events individually
ce.status = ConnectionEvent.DISCONNECTED;
dispatcher.dispatchEvent(ce);
break;
}
}
private function securityErrorHandler(event:SecurityErrorEvent):void{
var ce:ConnectionEvent = new ConnectionEvent();
ce.status = ConnectionEvent.SECURITYERROR;
dispatcher.dispatchEvent(ce);
}
public function mouseLocationCallback(x:Number, y:Number):void {
var event:CursorEvent = new CursorEvent(CursorEvent.UPDATE_CURSOR_LOC_EVENT);
event.x = x;
event.y = y;
dispatcher.dispatchEvent(event);
}
/**
* Check if anybody is publishing the stream for this room
* This method is useful for clients which have joined a room where somebody is already publishing
*
*/
private function checkIfStreamIsPublishing(room: String):void{
LOGGER.debug("checking if desk share stream is publishing");
var event:ConnectionEvent = new ConnectionEvent();
event.status = ConnectionEvent.CHECK_FOR_DESKSHARE_STREAM;
dispatcher.dispatchEvent(event);
nc.call("deskshare.checkIfStreamIsPublishing", responder, room);
}
public function disconnect():void{
logoutOnUserCommand = true;
if (nc != null) nc.close();
}
public function connectionSuccessHandler():void{
LOGGER.debug("Successully connection to {0}", [uri]);
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 {
LOGGER.debug("netStatusHandler target={0} info={1}", [e.target, ObjectUtil.toString(e.info)]);
}
private function debugAsyncErrorHandler(e:AsyncErrorEvent):void {
LOGGER.debug("asyncErrorHandler target={0} info={1}", [e.target, e.text]);
}
public function getConnection():NetConnection{
return nc;
}
public function connectionFailedHandler(e:ConnectionEvent):void{
LOGGER.error("connection failed to {0} with message {1}", [uri, e.toString()]);
}
public function connectionRejectedHandler(e:ConnectionEvent):void{
LOGGER.error("connection rejected to {0} with message {1}", [uri, e.toString()]);
}
/**
* Invoked on the server once the clients' applet has started sharing and the server has started a video stream
*
*/
public function appletStarted(videoWidth:Number, videoHeight:Number):void{
LOGGER.debug("Got applet started");
if (nc != null && nc.connected) {
var event:AppletStartedEvent = new AppletStartedEvent();
event.videoWidth = videoWidth;
event.videoHeight = videoHeight;
dispatcher.dispatchEvent(event);
}
}
/**
* Call this method to send out a room-wide notification to start viewing the stream
*
*/
public function sendStartViewingNotification(captureWidth:Number, captureHeight:Number):void{
try{
deskSO.send("startViewing", captureWidth, captureHeight);
} catch(e:Error){
LOGGER.error("error while trying to send start viewing notification");
}
}
public function sendStartedViewingNotification(stream:String):void{
LOGGER.debug("Sending start viewing to server");
nc.call("deskshare.startedToViewStream", null, stream);
}
public function stopSharingDesktop(meetingId: String, stream: String):void {
nc.call("deskshare.stopSharingDesktop", null, meetingId);
}
/**
* Called by the server when a notification is received to start viewing the broadcast stream .
* This method is called on successful execution of sendStartViewingNotification()
*
*/
public function startViewing(videoWidth:Number, videoHeight:Number):void{
LOGGER.debug("startViewing invoked by server");
var event:ViewStreamEvent = new ViewStreamEvent(ViewStreamEvent.START);
event.videoWidth = videoWidth;
event.videoHeight = videoHeight;
dispatcher.dispatchEvent(event);
}
/**
* Sends a notification through the server to all the participants in the room to stop viewing the stream
*
*/
public function sendStopViewingNotification():void{
LOGGER.debug("Sending stop viewing notification to other clients.");
try{
deskSO.send("stopViewing");
} catch(e:Error){
LOGGER.debug("could not send stop viewing notification");
}
}
/**
* Called by the server to notify clients that the deskshare stream has stooped.
*/
public function deskshareStreamStopped():void {
stopViewing();
}
/**
* Sends a notification to the module to stop viewing the stream
* This method is called on successful execution of sendStopViewingNotification()
*
*/
public function stopViewing():void{
LOGGER.debug("Received dekskshareStreamStopped");
dispatcher.dispatchEvent(new ViewStreamEvent(ViewStreamEvent.STOP));
}
}
}

View File

@ -1,50 +0,0 @@
/**
* 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.deskshare.services.red5
{
import flash.events.Event;
public class ConnectionEvent extends Event {
public static const DESKSHARE_CONNECTION_EVENT:String = "deskshare connection event";
public static const SUCCESS:String = "connection success";
public static const FAILED:String = "connection failed";
public static const CLOSED:String = "connection closed";
public static const REJECTED:String = "connection rejected";
public static const INVALIDAPP:String = "connection invalidApp";
public static const APPSHUTDOWN:String = "connection appShutdown";
public static const SECURITYERROR:String = "connection securityError";
public static const DISCONNECTED:String = "connection disconnected";
public static const CONNECTING:String = "connection connecting";
public static const CONNECTING_RETRY:String = "connection retry";
public static const CONNECTING_MAX_RETRY:String = "connection max retry";
public static const CHECK_FOR_DESKSHARE_STREAM:String = "connection check deskshare publishing";
public static const NO_DESKSHARE_STREAM:String = "connection deskshare publishing";
public static const FAIL_CHECK_FOR_DESKSHARE_STREAM:String = "connection failed check deskshare publishing";
public var status:String = "";
public var retryAttempts:int = 0;
public function ConnectionEvent():void {
super(DESKSHARE_CONNECTION_EVENT, true, false);
}
}
}

View File

@ -1,322 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2015 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.deskshare.services.red5
{
import com.asfusion.mate.events.Dispatcher;
import flash.events.AsyncErrorEvent;
import flash.events.NetStatusEvent;
import flash.events.SecurityErrorEvent;
import flash.events.TimerEvent;
import flash.net.NetConnection;
import flash.net.ObjectEncoding;
import flash.net.Responder;
import flash.utils.Timer;
import mx.utils.ObjectUtil;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.core.BBB;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.core.managers.ReconnectionManager;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.modules.deskshare.events.WebRTCViewStreamEvent;
public class WebRTCConnection {
private static const LOGGER:ILogger = getClassLogger(Connection);
private var nc:NetConnection;
private var uri:String;
private var retryTimer:Timer = null;
private var retryCount:int = 0;
private const MAX_RETRIES:int = 5;
private var responder:Responder;
private var width:Number;
private var height:Number;
private var room:String;
private var logoutOnUserCommand:Boolean = false;
private var reconnecting:Boolean = false;
private var wasPresenterBeforeDisconnect:Boolean = false;
private var dispatcher:Dispatcher = new Dispatcher();
public function WebRTCConnection(room:String) {
this.room = room;
responder = new Responder(
function(result:Object):void {
if (result != null && (result.publishing as Boolean)){
width = result.width as Number;
height = result.height as Number;
LOGGER.debug("Desk Share stream is streaming [{0},{1}]", [width, height]);
var event:WebRTCViewStreamEvent = new WebRTCViewStreamEvent(WebRTCViewStreamEvent.START);
event.videoWidth = width;
event.videoHeight = height;
dispatcher.dispatchEvent(event); //TODO why?
} else {
LOGGER.debug("No deskshare stream being published");
var connEvent:ConnectionEvent = new ConnectionEvent();
connEvent.status = ConnectionEvent.NO_DESKSHARE_STREAM;
dispatcher.dispatchEvent(connEvent); //TODO why?
}
},
function(status:Object):void{
var checkFailedEvent:ConnectionEvent = new ConnectionEvent();
checkFailedEvent.status = ConnectionEvent.FAIL_CHECK_FOR_DESKSHARE_STREAM;
dispatcher.dispatchEvent(checkFailedEvent);
LOGGER.debug("Error while trying to call remote mathod on server");
}
);
}
public function connect(retry:Boolean = false):void {
nc = new NetConnection();
nc.proxyType = "best";
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);
if (getURI().length == 0){
LOGGER.error("please provide a valid URI connection string. URI Connection String missing");
return;
} else if (nc.connected){
LOGGER.error("You are already connected to {0}", [getURI()]);
return;
}
LOGGER.debug("Trying to connect to [{0}] retry=[{1}]", [getURI(), retry]);
if (! (retryCount > 0)) {
var ce:ConnectionEvent = new ConnectionEvent();
ce.status = ConnectionEvent.CONNECTING;
dispatcher.dispatchEvent(ce);
}
nc.connect(getURI(), UsersUtil.getInternalMeetingID());
}
private function connectTimeoutHandler(e:TimerEvent):void {
LOGGER.debug("Connection attempt to [{0}] timedout. Retrying.", [getURI()]);
retryTimer.stop();
retryTimer = null;
nc.close();
nc = null;
var ce:ConnectionEvent = new ConnectionEvent();;
retryCount++;
if (retryCount < MAX_RETRIES) {
ce.status = ConnectionEvent.CONNECTING_RETRY;
ce.retryAttempts = retryCount;
dispatcher.dispatchEvent(ce);
connect(false);
} else {
ce.status = ConnectionEvent.CONNECTING_MAX_RETRY;
dispatcher.dispatchEvent(ce);
}
}
public function close():void{
nc.close();
}
public function setURI(p_URI:String):void{
uri = p_URI;
}
public function getURI():String{
return uri;
}
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
LOGGER.debug("bandwidth = {0} Kbps.", [p_bw]);
}
private function netStatusHandler(event:NetStatusEvent):void {
LOGGER.debug("Connected to [" + getURI() + "]. [" + event.info.code + "]");
if (retryTimer) {
retryCount = 0;
LOGGER.debug("Cancelling retry timer.");
retryTimer.stop();
retryTimer = null;
}
var ce:ConnectionEvent = new ConnectionEvent();
switch(event.info.code){
case "NetConnection.Connect.Failed":
if (reconnecting) {
var attemptFailedEvent:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_CONNECTION_ATTEMPT_FAILED_EVENT);
attemptFailedEvent.payload.type = ReconnectionManager.DESKSHARE_CONNECTION;
dispatcher.dispatchEvent(attemptFailedEvent);
}
ce.status = ConnectionEvent.FAILED;
dispatcher.dispatchEvent(ce);
break;
case "NetConnection.Connect.Success":
ce.status = ConnectionEvent.SUCCESS;
if (reconnecting) {
reconnecting = false;
if (wasPresenterBeforeDisconnect) {
wasPresenterBeforeDisconnect = false;
// stopSharingDesktop(room, room) //TODO
}
var attemptSucceeded:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_CONNECTION_ATTEMPT_SUCCEEDED_EVENT);
attemptSucceeded.payload.type = ReconnectionManager.DESKSHARE_CONNECTION;
dispatcher.dispatchEvent(attemptSucceeded);
}
// request desktop sharing info (as a late joiner)
LOGGER.debug("Sending [desktopSharing.requestDeskShareInfo] to server.");
var _nc:ConnectionManager = BBB.initConnectionManager();
_nc.sendMessage("desktopSharing.requestDeskShareInfo",
function(result:String):void { // On successful result
LOGGER.debug(result);
},
function(status:String):void { // status - On error occurred
LOGGER.error(status);
}
);
dispatcher.dispatchEvent(ce);
break;
case "NetConnection.Connect.Rejected":
ce.status = ConnectionEvent.REJECTED;
dispatcher.dispatchEvent(ce);
break;
case "NetConnection.Connect.Closed":
LOGGER.debug("Deskshare connection closed.");
ce.status = ConnectionEvent.CLOSED;
if (UsersUtil.amIPresenter()) {
// Let's keep our presenter status before disconnected. We can't
// tell the other user's to stop desktop sharing as our connection is broken. (ralam july 24, 2015)
wasPresenterBeforeDisconnect = true;
} else {
// stopViewing(); //TODO
}
if (!logoutOnUserCommand) {
reconnecting = true;
var disconnectedEvent:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_DISCONNECTED_EVENT);
disconnectedEvent.payload.type = ReconnectionManager.DESKSHARE_CONNECTION;
disconnectedEvent.payload.callback = connect;
disconnectedEvent.payload.callbackParameters = [];
dispatcher.dispatchEvent(disconnectedEvent);
}
break;
case "NetConnection.Connect.InvalidApp":
ce.status = ConnectionEvent.INVALIDAPP;
dispatcher.dispatchEvent(ce);
break;
case "NetConnection.Connect.AppShutdown":
ce.status = ConnectionEvent.APPSHUTDOWN;
dispatcher.dispatchEvent(ce);
break;
case "NetConnection.Connect.NetworkChange":
LOGGER.info("Detected network change. User might be on a wireless and temporarily dropped connection. Doing nothing. Just making a note.");
break;
default :
// I dispatch DISCONNECTED incase someone just simply wants to know if we're not connected'
// rather than having to subscribe to the events individually
ce.status = ConnectionEvent.DISCONNECTED;
dispatcher.dispatchEvent(ce);
break;
}
}
private function securityErrorHandler(event:SecurityErrorEvent):void{
var ce:ConnectionEvent = new ConnectionEvent();
ce.status = ConnectionEvent.SECURITYERROR;
dispatcher.dispatchEvent(ce);
}
/**
* Check if anybody is publishing the stream for this room
* This method is useful for clients which have joined a room where somebody is already publishing
*
*/
private function checkIfStreamIsPublishing(room: String):void{
LOGGER.debug("checking if desk share stream is publishing");
var event:ConnectionEvent = new ConnectionEvent();
event.status = ConnectionEvent.CHECK_FOR_DESKSHARE_STREAM;
dispatcher.dispatchEvent(event); // TODO anton send to akka-bbb-apps
nc.call("deskshare.checkIfStreamIsPublishing", responder, room);
}
public function disconnect():void{
logoutOnUserCommand = true;
if (nc != null) nc.close();
}
public function connectionSuccessHandler():void{
LOGGER.debug("Successully connection to {0}", [uri]);
checkIfStreamIsPublishing(room);
}
private function debugNetStatusHandler(e:NetStatusEvent):void {
LOGGER.debug("netStatusHandler target={0} info={1}", [e.target, ObjectUtil.toString(e.info)]);
}
private function debugAsyncErrorHandler(e:AsyncErrorEvent):void {
LOGGER.debug("asyncErrorHandler target={0} info={1}", [e.target, e.text]);
}
public function getConnection():NetConnection{
return nc;
}
public function connectionFailedHandler(e:ConnectionEvent):void{
LOGGER.error("connection failed to {0} with message {1}", [uri, e.toString()]);
}
public function connectionRejectedHandler(e:ConnectionEvent):void{
LOGGER.error("connection rejected to {0} with message {1}", [uri, e.toString()]);
}
}
}

View File

@ -1,49 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2015 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.deskshare.services.red5
{
import flash.events.Event;
public class WebRTCConnectionEvent extends Event {
public static const DESKSHARE_CONNECTION_EVENT:String = "webrtcDeskshare connection event";
public static const SUCCESS:String = "connection success";
public static const FAILED:String = "connection failed";
public static const CLOSED:String = "connection closed";
public static const REJECTED:String = "connection rejected";
public static const INVALIDAPP:String = "connection invalidApp";
public static const APPSHUTDOWN:String = "connection appShutdown";
public static const SECURITYERROR:String = "connection securityError";
public static const DISCONNECTED:String = "connection disconnected";
public static const CONNECTING:String = "connection connecting";
public static const CONNECTING_RETRY:String = "connection retry";
public static const CONNECTING_MAX_RETRY:String = "connection max retry";
public static const CHECK_FOR_DESKSHARE_STREAM:String = "connection check webrtcDeskshare publishing";
public static const NO_DESKSHARE_STREAM:String = "connection webrtcDeskshare publishing";
public static const FAIL_CHECK_FOR_DESKSHARE_STREAM:String = "connection failed check webrtcDeskshare publishing";
public var status:String = "";
public var retryAttempts:int = 0;
public function WebRTCConnectionEvent():void {
super(DESKSHARE_CONNECTION_EVENT, true, false);
}
}
}

View File

@ -1,62 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2016 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.deskshare.utils
{
import flash.external.ExternalInterface;
import org.bigbluebutton.core.BBB;
import flash.system.Capabilities;
import org.as3commons.logging.api.getClassLogger;
import org.as3commons.logging.api.ILogger;
public class BrowserCheck {
private static const LOGGER:ILogger = getClassLogger(BrowserCheck);
public static function isChrome42OrHigher():Boolean {
var browser:Array = ExternalInterface.call("determineBrowser");
return ((browser[0] == "Chrome") && (parseInt(browser[1]) >= 42));
}
public static function isUsingLessThanChrome38OnMac():Boolean {
var browser:Array = ExternalInterface.call("determineBrowser");
return ((browser[0] == "Chrome") && (parseInt(browser[1]) <= 38) && (Capabilities.os.indexOf("Mac") >= 0));
}
public static function isWebRTCSupported():Boolean {
LOGGER.debug("isWebRTCSupported - ExternalInterface.available=[{0}], isWebRTCAvailable=[{1}]", [ExternalInterface.available, ExternalInterface.call("isWebRTCAvailable")]);
return (ExternalInterface.available && ExternalInterface.call("isWebRTCAvailable"));
}
public static function isUsingEdgePluginUnsupported():Boolean {
var browser:Array = ExternalInterface.call("determineBrowser");
/* Currently no browser version of Edge supports plugins */
return browser[0] == "Edge";
}
public static function isChrome():Boolean {
var browser:Array = ExternalInterface.call("determineBrowser");
return browser[0] == "Chrome";
}
public static function isFirefox():Boolean {
var browser:Array = ExternalInterface.call("determineBrowser");
return browser[0] == "Firefox";
}
}
}

Some files were not shown because too many files have changed in this diff Show More