Merge branch 'master' into merge-bbb-1.1-dev-java8-with-master

Conflicts:
	akka-bbb-apps/build.sbt
	akka-bbb-apps/src/main/java/org/bigbluebutton/core/api/IBigBlueButtonInGW.java
	akka-bbb-apps/src/main/resources/application.conf
	akka-bbb-apps/src/main/scala/org/bigbluebutton/Boot.scala
	akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonActor.scala
	akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala
	akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MeetingActor.scala
	akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MeetingModel.scala
	akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MessageSenderActor.scala
	akka-bbb-apps/src/main/scala/org/bigbluebutton/core/RecorderActor.scala
	akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala
	akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala
	akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/ValueObjects.scala
	akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/WhiteboardApp.scala
	akka-bbb-fsesl/build.sbt
	akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/pubsub/receivers/RedisMessageReceiver.java
	akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/ConnectionManager.java
	akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/FreeswitchApplication.java
	bbb-common-message/build.sbt
	bbb-common-message/src/main/java/org/bigbluebutton/common/messages/Constants.java
	bbb-common-message/src/main/java/org/bigbluebutton/common/messages/MessagingConstants.java
	bbb-common-message/src/main/java/org/bigbluebutton/common/messages/Util.java
	bigbluebutton-apps/build.gradle
	bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/pubsub/redis/RedisPubSubMessageHandler.java
	bigbluebutton-apps/src/main/webapp/WEB-INF/red5-web.xml
	bigbluebutton-client/build.xml
	bigbluebutton-client/resources/config.xml.template
	bigbluebutton-client/resources/prod/BigBlueButton.html
	bigbluebutton-client/src/org/bigbluebutton/common/Images.as
	bigbluebutton-client/src/org/bigbluebutton/main/maps/ApplicationEventMap.mxml
	bigbluebutton-client/src/org/bigbluebutton/main/model/users/Conference.as
	bigbluebutton-client/src/org/bigbluebutton/modules/deskshare/utils/JavaCheck.as
	bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as
	bigbluebutton-web/build.gradle
	bigbluebutton-web/grails-app/conf/spring/resources.xml
	bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy
	bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingService.java
	bigbluebutton-web/src/java/org/bigbluebutton/api/domain/Meeting.java
	bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MeetingMessageHandler.java
	bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/RedisMessagingService.java
	record-and-playback/core/scripts/bigbluebutton.yml
This commit is contained in:
Richard Alam 2016-05-16 11:35:36 -04:00
commit 58c239bc43
540 changed files with 48754 additions and 43410 deletions

View File

@ -1,170 +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 */ }
.visually-hidden {
position: absolute !important;
clip: rect(1px 1px, 1px, 1px);
clip: rect(1px, 1px, 1px, 1px);
padding: 0 !important;
border: 0 !important;
height: 1px !important;
width: 1px !important;
overflow: hidden;
}
#deployJavaPlugin {
display : none;
}
</style>
<script type="text/javascript" src="swfobject/swfobject.js"></script>
<script src="lib/deployJava.js?v=264" language="javascript"></script>
<script type="text/javascript">
//swfobject.registerObject("BigBlueButton", "11", "expressInstall.swf");
var flashvars = {};
var params = {};
params.quality = "high";
params.bgcolor = "#869ca7";
params.allowfullscreen = "true";
params.wmode = "window";
params.allowscriptaccess = "true";
params.seamlesstabbing = "true";
var attributes = {};
attributes.id = "BigBlueButton";
attributes.name = "BigBlueButton";
attributes.align = "middle";
attributes.tabIndex = 0;
swfobject.embedSWF("BigBlueButton.swf?v=264", "altFlash", "100%", "100%", "11.0.0", "expressInstall.swf", flashvars, params, attributes, embedCallback);
function embedCallback(e) {
// Work around pixel alignment bug with Chrome 21 on Mac.
// See: http://code.google.com/p/bigbluebutton/issues/detail?id=1294
var objs = $('object');
objs.each(function(i, o) {
var o = $(o);
var top = o.offset().top;
var left = o.offset().left;
var roundtop = Math.round(top);
var roundleft = Math.round(left);
o.css("position", "relative");
if (roundtop === top) {
} else {
o.css("top", roundtop - top);
}
if (roundleft === left) {
} else {
o.css("left", roundleft - left);
}
});
}
</script>
<script src="lib/jquery-1.5.1.min.js?v=264" language="javascript"></script>
<script src="lib/bbblogger.js?v=264" language="javascript"></script>
<script src="lib/bigbluebutton.js?v=264" language="javascript"></script>
<script src="lib/bbb_localization.js?v=264" language="javascript"></script>
<script src="lib/bbb_blinker.js?v=264" language="javascript"></script>
<script src="lib/bbb_deskshare.js?v=264" language="javascript"></script>
<script src="lib/bbb_api_bridge.js?v=264" language="javascript"></script>
<script src="lib/sip.js?v=264" language="javascript"></script>
<script src="lib/bbb_webrtc_bridge_sip.js?v=264" language="javascript"></script>
<script src="lib/weburl_regex.js?v=264" language="javascript"></script>
<script>
window.chatLinkClicked = function(url) {
window.open(url, '_blank');
window.focus();
}
</script>
<script type="text/javascript">
function html5() {
// no Flash detected on the client
var originalPath, request;
originalPath = document.location.pathname;
// reuse code in a function to log an error when needed
var reportError = function() {
alert("Unable to load the HTML5 client!");
BBBLog.debug("Could not redirect to html5client (the server side does not seem to be running)");
}
var checkRequest = $.ajax({
dataType: 'json',
url: '/html5client/check'
});
checkRequest.done(function(data) {
if(typeof data.html5clientStatus !== "undefined" && data.html5clientStatus !== null) {
if(data.html5clientStatus === "running") {
// use the enter api to detect the meetingid, userid and authToken
// for the attempted joining of the meeting
// and reuse them to join via the HTML5 client
var enterRequest = $.ajax({
dataType: 'json',
url: '/bigbluebutton/api/enter'
});
enterRequest.done(function(enterData) {
var authToken, meetingId, userId;
meetingId = enterData.response.meetingID;
userId = enterData.response.externUserID;
authToken = enterData.response.authToken;
if ((meetingId != null) && (userId != null) && (authToken != null)) {
// redirect to the html5 client with the received info
// format <IP>/html5client/<meetingId>/<userId>/<authToken>
document.location.pathname = "/html5client/"+meetingId+"/"+userId+"/"+authToken;
} else {
// go back to the redirection page
document.location.pathname = originalPath;
}
});
enterRequest.fail(function(enterData, textStatus, errorThrown){
reportError();
});
}
else {
reportError();
}
}
else {
reportError();
}
});
checkRequest.fail(function(data, textStatus, errorThrown){
reportError();
});
}
</script>
</head>
<body>
<div>
<audio id="remote-media" autoplay="autoplay"></audio>
</div>
<div id="content">
<div id="altFlash" style="width:50%; margin-left: auto; margin-right: auto; ">
<h2>You need Flash installed and enabled in order to use the Flash client.</h2>
<br/>
<div style="width:50%; margin-left: auto; margin-right: auto; ">
<a href="http://www.adobe.com/go/getflashplayer">
<img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" />
</a>
<p style="margin-left:50px;" >OR</p>
<button type="button" onclick="html5();"><h3>Launch the HTML5 client instead</h3></button>
</div>
</div>
</div>
<button id="enterFlash" type="button" class="visually-hidden" onclick="startFlashFocus();" value="Click to focus the client"></button>
<div id="clientReady" aria-atomic="false" aria-live="polite"></div>
</body>
</html>

72
Vagrantfile vendored
View File

@ -1,72 +0,0 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure(2) do |config|
# The most common configuration options are documented and commented below.
# For a complete reference, please see the online documentation at
# https://docs.vagrantup.com.
# Every Vagrant development environment requires a box. You can search for
# boxes at https://atlas.hashicorp.com/search.
config.vm.box = "RIADVICE/bigbluebutton-dev"
# Disable automatic box update checking. If you disable this, then
# boxes will only be checked for updates when the user runs
# `vagrant box outdated`. This is not recommended.
# config.vm.box_check_update = false
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine. In the example below,
# accessing "localhost:8080" will access port 80 on the guest machine.
# config.vm.network "forwarded_port", guest: 80, host: 8080
# Create a private network, which allows host-only access to the machine
# using a specific IP.
config.vm.network "private_network", ip: "192.168.33.22"
# Create a public network, which generally matched to bridged network.
# Bridged networks make the machine appear as another physical device on
# your network.
# config.vm.network "public_network"
# Share an additional folder to the guest VM. The first argument is
# the path on the host to the actual folder. The second argument is
# the path on the guest to mount the folder. And the optional third
# argument is a set of non-required options.
config.vm.synced_folder ".", "/vagrant"
# Provider-specific configuration so you can fine-tune various
# backing providers for Vagrant. These expose provider-specific options.
# Example for VirtualBox:
#
config.vm.provider "virtualbox" do |vb|
# Display the VirtualBox GUI when booting the machine
# vb.gui = false
# Customize the amount of memory on the VM:
vb.memory = "4096"
vb.cpus = 2
end
#
# View the documentation for the provider you are using for more
# information on available options.
# Define a Vagrant Push strategy for pushing to Atlas. Other push strategies
# such as FTP and Heroku are also available. See the documentation at
# https://docs.vagrantup.com/v2/push/atlas.html for more information.
# config.push.define "atlas" do |push|
# push.app = "YOUR_ATLAS_USERNAME/YOUR_APPLICATION_NAME"
# end
# Enable provisioning with a shell script. Additional provisioners such as
# Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
# documentation for more information about their specific syntax and use.
# config.vm.provision "shell", inline: <<-SHELL
# sudo apt-get update
# sudo apt-get install -y apache2
# SHELL
end

File diff suppressed because one or more lines are too long

View File

@ -24,6 +24,8 @@ resolvers ++= Seq(
"blindside-repos" at "http://blindside.googlecode.com/svn/repository/" "blindside-repos" at "http://blindside.googlecode.com/svn/repository/"
) )
resolvers += Resolver.sonatypeRepo("releases")
publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath+"/dev/repo/maven-repo/releases" )) ) publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath+"/dev/repo/maven-repo/releases" )) )
// We want to have our jar files in lib_managed dir. // We want to have our jar files in lib_managed dir.
@ -58,9 +60,10 @@ libraryDependencies ++= {
"com.google.code.gson" % "gson" % "2.5", "com.google.code.gson" % "gson" % "2.5",
"redis.clients" % "jedis" % "2.7.2", "redis.clients" % "jedis" % "2.7.2",
"org.apache.commons" % "commons-lang3" % "3.2", "org.apache.commons" % "commons-lang3" % "3.2",
"org.bigbluebutton" % "bbb-common-message" % "0.0.17-SNAPSHOT", "org.bigbluebutton" % "bbb-common-message" % "0.0.18-SNAPSHOT",
"io.spray" %% "spray-json" % "1.3.2" "io.spray" %% "spray-json" % "1.3.2"
)} )
}
seq(Revolver.settings: _*) seq(Revolver.settings: _*)

View File

@ -31,7 +31,7 @@ public interface IBigBlueButtonInGW {
// Users // Users
void validateAuthToken(String meetingId, String userId, String token, String correlationId, String sessionId); void validateAuthToken(String meetingId, String userId, String token, String correlationId, String sessionId);
void registerUser(String roomName, String userid, String username, String role, String externUserID, String authToken); void registerUser(String roomName, String userid, String username, String role, String externUserID, String authToken, String avatarURL);
void userEmojiStatus(String meetingId, String userId, String emojiStatus); void userEmojiStatus(String meetingId, String userId, String emojiStatus);
void shareWebcam(String meetingId, String userId, String stream); void shareWebcam(String meetingId, String userId, String stream);
void unshareWebcam(String meetingId, String userId, String stream); void unshareWebcam(String meetingId, String userId, String stream);
@ -56,7 +56,7 @@ public interface IBigBlueButtonInGW {
void ejectUserFromVoice(String meetingID, String userId, String ejectedBy); void ejectUserFromVoice(String meetingID, String userId, String ejectedBy);
void ejectUserFromMeeting(String meetingId, String userId, String ejectedBy); void ejectUserFromMeeting(String meetingId, String userId, String ejectedBy);
void voiceUserJoined(String voiceConfId, String voiceUserId, String userId, String callerIdName, void voiceUserJoined(String voiceConfId, String voiceUserId, String userId, String callerIdName,
String callerIdNum, Boolean muted, Boolean talking); String callerIdNum, Boolean muted, String avatarURL, Boolean talking);
void voiceUserLeft(String meetingId, String userId); void voiceUserLeft(String meetingId, String userId);
void voiceUserLocked(String meetingId, String userId, Boolean locked); void voiceUserLocked(String meetingId, String userId, Boolean locked);
void voiceUserMuted(String meetingId, String userId, Boolean muted); void voiceUserMuted(String meetingId, String userId, Boolean muted);
@ -112,4 +112,11 @@ public interface IBigBlueButtonInGW {
void sendCaptionHistory(String meetingID, String requesterID); void sendCaptionHistory(String meetingID, String requesterID);
void updateCaptionOwner(String meetingID, String locale, String ownerID); void updateCaptionOwner(String meetingID, String locale, String ownerID);
void editCaptionHistory(String meetingID, String userID, Integer startIndex, Integer endIndex, String locale, String text); void editCaptionHistory(String meetingID, String userID, Integer startIndex, Integer endIndex, String locale, String text);
// DeskShare
void deskShareStarted(String conferenceName, String callerId, String callerIdName);
void deskShareStopped(String conferenceName, String callerId, String callerIdName);
void deskShareRTMPBroadcastStarted(String conferenceName, String streamname, int videoWidth, int videoHeight, String timestamp);
void deskShareRTMPBroadcastStopped(String conferenceName, String streamname, int videoWidth, int videoHeight, String timestamp);
void deskShareGetInfoRequest(String meetingId, String requesterId, String replyTo);
} }

View File

@ -0,0 +1,59 @@
package org.bigbluebutton.core.pubsub.receivers;
import com.google.gson.JsonParser;
import com.google.gson.JsonObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.bigbluebutton.common.messages.DeskShareStartedEventMessage;
import org.bigbluebutton.common.messages.DeskShareStoppedEventMessage;
import org.bigbluebutton.common.messages.DeskShareRTMPBroadcastStartedEventMessage;
import org.bigbluebutton.common.messages.DeskShareRTMPBroadcastStoppedEventMessage;
import org.bigbluebutton.common.messages.DeskShareGetInfoRequestMessage;
import org.bigbluebutton.common.messages.MessagingConstants;
import org.bigbluebutton.core.api.IBigBlueButtonInGW;
public class DeskShareMessageReceiver implements MessageHandler {
private IBigBlueButtonInGW bbbGW;
private static final Logger log = LoggerFactory.getLogger(DeskShareMessageReceiver.class);
public DeskShareMessageReceiver(IBigBlueButtonInGW bbbGW) {
this.bbbGW = bbbGW;
}
@Override
public void handleMessage(String pattern, String channel, String message) {
if (channel.equalsIgnoreCase(MessagingConstants.FROM_VOICE_CONF_SYSTEM_CHAN)) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (DeskShareStartedEventMessage.DESKSHARE_STARTED_MESSAGE.equals(messageName)) {
DeskShareStartedEventMessage msg = DeskShareStartedEventMessage.fromJson(message);
log.info("^^^^^^^DESKSHARE STARTED^^^^^^");
bbbGW.deskShareStarted(msg.conferenceName, msg.callerId, msg.callerIdName);
} else if (DeskShareStoppedEventMessage.DESK_SHARE_STOPPED_MESSAGE.equals(messageName)) {
DeskShareStoppedEventMessage msg = DeskShareStoppedEventMessage.fromJson(message);
log.info("^^^^^^^DESKSHARE STOPPED^^^^^^");
bbbGW.deskShareStopped(msg.conferenceName, msg.callerId, msg.callerIdName);
} else if (DeskShareRTMPBroadcastStartedEventMessage.DESKSHARE_RTMP_BROADCAST_STARTED_MESSAGE.equals(messageName)) {
log.info("^^^^^^^DESKSHARE_RTMP_BROADCAST_STARTED_MESSAGE^^^^^^");
DeskShareRTMPBroadcastStartedEventMessage msg = DeskShareRTMPBroadcastStartedEventMessage.fromJson(message);
bbbGW.deskShareRTMPBroadcastStarted(msg.conferenceName, msg.streamname, msg.vw, msg.vh, msg.timestamp);
} else if (DeskShareRTMPBroadcastStoppedEventMessage.DESKSHARE_RTMP_BROADCAST_STOPPED_MESSAGE.equals(messageName)) {
log.info("^^^^^^^DESKSHARE_RTMP_BROADCAST_STOPPED_MESSAGE^^^^^^");
DeskShareRTMPBroadcastStoppedEventMessage msg = DeskShareRTMPBroadcastStoppedEventMessage.fromJson(message);
bbbGW.deskShareRTMPBroadcastStopped(msg.conferenceName, msg.streamname, msg.vw, msg.vh, msg.timestamp);
} else if (DeskShareGetInfoRequestMessage.GET_DESKTOP_SHARE_GET_INFO_REQUEST.equals(messageName)) {
log.info("^^^^^^^GET_DESKTOP_SHARE_INFO_REQUEST^^^^^^");
DeskShareGetInfoRequestMessage msg = DeskShareGetInfoRequestMessage.fromJson(message);
bbbGW.deskShareGetInfoRequest(msg.meetingId, msg.requesterId, msg.replyTo);
}
}
}
}
}
}

View File

@ -60,7 +60,7 @@ public class MeetingMessageReceiver implements MessageHandler {
bbbGW.endMeeting(emm.meetingId); bbbGW.endMeeting(emm.meetingId);
} else if (msg instanceof RegisterUserMessage) { } else if (msg instanceof RegisterUserMessage) {
RegisterUserMessage emm = (RegisterUserMessage) msg; RegisterUserMessage emm = (RegisterUserMessage) msg;
bbbGW.registerUser(emm.meetingID, emm.internalUserId, emm.fullname, emm.role, emm.externUserID, emm.authToken); bbbGW.registerUser(emm.meetingID, emm.internalUserId, emm.fullname, emm.role, emm.externUserID, emm.authToken, emm.avatarURL);
} else if (msg instanceof DestroyMeetingMessage) { } else if (msg instanceof DestroyMeetingMessage) {
DestroyMeetingMessage emm = (DestroyMeetingMessage) msg; DestroyMeetingMessage emm = (DestroyMeetingMessage) msg;
bbbGW.destroyMeeting(emm.meetingId); bbbGW.destroyMeeting(emm.meetingId);

View File

@ -46,6 +46,9 @@ public class RedisMessageReceiver {
WhiteboardMessageReceiver whiteboardRx = new WhiteboardMessageReceiver(bbbGW); WhiteboardMessageReceiver whiteboardRx = new WhiteboardMessageReceiver(bbbGW);
receivers.add(whiteboardRx); receivers.add(whiteboardRx);
DeskShareMessageReceiver deskShareRx = new DeskShareMessageReceiver(bbbGW);
receivers.add(deskShareRx);
PollingMessageReceiver pollRx = new PollingMessageReceiver(bbbGW); PollingMessageReceiver pollRx = new PollingMessageReceiver(bbbGW);
receivers.add(pollRx); receivers.add(pollRx);

View File

@ -149,7 +149,7 @@ public class UsersMessageReceiver implements MessageHandler{
private void processUserJoinedVoiceConfMessage(String json) { private void processUserJoinedVoiceConfMessage(String json) {
UserJoinedVoiceConfMessage msg = UserJoinedVoiceConfMessage.fromJson(json); UserJoinedVoiceConfMessage msg = UserJoinedVoiceConfMessage.fromJson(json);
if (msg != null) { if (msg != null) {
bbbInGW.voiceUserJoined(msg.voiceConfId, msg.voiceUserId, msg.userId, msg.callerIdName, msg.callerIdNum, msg.muted, msg.talking); bbbInGW.voiceUserJoined(msg.voiceConfId, msg.voiceUserId, msg.userId, msg.callerIdName, msg.callerIdNum, msg.muted, msg.avatarURL, msg.talking);
} }
} }

View File

@ -0,0 +1,28 @@
/**
* 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.core.recorders.events;
import org.bigbluebutton.core.service.recorder.RecordEvent;
public abstract class AbstractDeskShareRecordEvent extends RecordEvent {
public AbstractDeskShareRecordEvent() {
setModule("DESKSHARE");
}
}

View File

@ -0,0 +1,26 @@
package org.bigbluebutton.core.recorders.events;
public class DeskShareNotifyViewersRTMPRecordEvent extends
AbstractDeskShareRecordEvent {
public DeskShareNotifyViewersRTMPRecordEvent() {
super();
setEvent("DeskShareNotifyViewersRTMP");
}
public void setStreamPath(String streamPath) {
eventMap.put("streamPath", streamPath);
}
public void setBroadcasting(Boolean broadcasting) {
eventMap.put("broadcasting", broadcasting.toString());
}
public void setVideoWidth(int videoWidth) {
eventMap.put("videoWidth", Integer.toString(videoWidth));
}
public void setVideoHeight(int videoHeight) {
eventMap.put("videoHeight", Integer.toString(videoHeight));
}
}

View File

@ -0,0 +1,14 @@
package org.bigbluebutton.core.recorders.events;
public class DeskShareStartRTMPRecordEvent extends
AbstractDeskShareRecordEvent {
public DeskShareStartRTMPRecordEvent() {
super();
setEvent("DeskShareStartRTMP");
}
public void setStreamPath(String streamPath) {
eventMap.put("streamPath", streamPath);
}
}

View File

@ -0,0 +1,14 @@
package org.bigbluebutton.core.recorders.events;
public class DeskShareStopRTMPRecordEvent extends
AbstractDeskShareRecordEvent {
public DeskShareStopRTMPRecordEvent() {
super();
setEvent("DeskShareStopRTMP");
}
public void setStreamPath(String streamPath) {
eventMap.put("streamPath", streamPath);
}
}

View File

@ -1,13 +0,0 @@
package org.bigbluebutton.core.service.chat;
public class ChatKeyUtil {
public static final String CHAT_TYPE = "chatType";
public static final String FROM_USERID = "fromUserID";
public static final String FROM_USERNAME = "fromUsername";
public static final String FROM_COLOR = "fromColor";
public static final String FROM_TIME = "fromTime";
public static final String FROM_TZ_OFFSET = "fromTimezoneOffset";
public static final String TO_USERID = "toUserID";
public static final String TO_USERNAME = "toUsername";
public static final String MESSAGE = "message";
}

View File

@ -1,6 +0,0 @@
package org.bigbluebutton.core.service.voice;
public class VoiceKeyUtil {
public static final String MUTE = "mute";
public static final String USERID = "userId";
}

View File

@ -51,3 +51,8 @@ services {
viewerPassword = "ap" viewerPassword = "ap"
defaultPresentationURL = "http://localhost/default.pdf" defaultPresentationURL = "http://localhost/default.pdf"
} }
red5 {
deskshareip="192.168.0.109"
deskshareapp="video-broadcast"
}

View File

@ -49,11 +49,10 @@ object Boot extends App with SystemConfiguration {
outgoingEventBus.subscribe(recorderActor, "outgoingMessageChannel") outgoingEventBus.subscribe(recorderActor, "outgoingMessageChannel")
outgoingEventBus.subscribe(newMessageSenderActor, "outgoingMessageChannel") outgoingEventBus.subscribe(newMessageSenderActor, "outgoingMessageChannel")
val bbbInGW = new BigBlueButtonInGW(system, eventBus, outGW) val bbbInGW = new BigBlueButtonInGW(system, eventBus, outGW, red5DeskShareIP, red5DeskShareApp)
val redisMsgReceiver = new RedisMessageReceiver(bbbInGW) val redisMsgReceiver = new RedisMessageReceiver(bbbInGW)
val redisSubscriberActor = system.actorOf(AppsRedisSubscriberActor.props(redisMsgReceiver), "redis-subscriber") val redisSubscriberActor = system.actorOf(AppsRedisSubscriberActor.props(redisMsgReceiver), "redis-subscriber")
val keepAliveRedisPublisher = new KeepAliveRedisPublisher(system, redisPublisher) val keepAliveRedisPublisher = new KeepAliveRedisPublisher(system, redisPublisher)
} }

View File

@ -22,4 +22,6 @@ trait SystemConfiguration {
lazy val bbbWebViewerPassword = Try(config.getString("services.viewerPassword")).getOrElse("changeme") lazy val bbbWebViewerPassword = Try(config.getString("services.viewerPassword")).getOrElse("changeme")
lazy val bbbWebDefaultPresentationURL = Try(config.getString("services.defaultPresentationURL")).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 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

@ -5,23 +5,9 @@ import akka.actor.ActorLogging
import akka.pattern.{ ask, pipe } import akka.pattern.{ ask, pipe }
import akka.util.Timeout import akka.util.Timeout
import scala.concurrent.duration._ import scala.concurrent.duration._
import scala.collection.mutable.HashMap
import org.bigbluebutton.core.bus._ import org.bigbluebutton.core.bus._
import org.bigbluebutton.core.api._ import org.bigbluebutton.core.api._
import org.bigbluebutton.core.util._
import org.bigbluebutton.core.api.ValidateAuthTokenTimedOut
import scala.util.Success
import scala.util.Failure
import org.bigbluebutton.SystemConfiguration import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.core.recorders.events.VoiceUserJoinedRecordEvent
import org.bigbluebutton.core.recorders.events.VoiceUserLeftRecordEvent
import org.bigbluebutton.core.recorders.events.VoiceUserLockedRecordEvent
import org.bigbluebutton.core.recorders.events.VoiceUserMutedRecordEvent
import org.bigbluebutton.core.recorders.events.VoiceStartRecordingRecordEvent
import org.bigbluebutton.core.recorders.events.VoiceUserTalkingRecordEvent
import org.bigbluebutton.core.service.recorder.RecorderApplication
import scala.collection._
import com.google.gson.Gson
object BigBlueButtonActor extends SystemConfiguration { object BigBlueButtonActor extends SystemConfiguration {
def props(system: ActorSystem, def props(system: ActorSystem,
@ -45,7 +31,57 @@ class BigBlueButtonActor(val system: ActorSystem,
case msg: PubSubPing => handlePubSubPingMessage(msg) case msg: PubSubPing => handlePubSubPingMessage(msg)
case msg: ValidateAuthToken => handleValidateAuthToken(msg) case msg: ValidateAuthToken => handleValidateAuthToken(msg)
case msg: GetAllMeetingsRequest => handleGetAllMeetingsRequest(msg) case msg: GetAllMeetingsRequest => handleGetAllMeetingsRequest(msg)
// case _ => // do nothing 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 msg: DeskShareStartedRequest => handleDeskShareStartedRequest(msg)
case msg: DeskShareStoppedRequest => handleDeskShareStoppedRequest(msg)
case msg: DeskShareRTMPBroadcastStartedRequest => handleDeskShareRTMPBroadcastStartedRequest(msg)
case msg: DeskShareRTMPBroadcastStoppedRequest => handleDeskShareRTMPBroadcastStoppedRequest(msg)
case msg: DeskShareGetDeskShareInfoRequest => handleDeskShareGetDeskShareInfoRequest(msg)
case _ => // do nothing
}
private def findMeetingWithVoiceConfId(voiceConfId: String): Option[RunningMeeting] = {
meetings.values.find(m => { m.mProps.voiceBridge == voiceConfId })
}
private def handleUserJoinedVoiceConfMessage(msg: UserJoinedVoiceConfMessage) {
findMeetingWithVoiceConfId(msg.voiceConfId) foreach { m => m.actorRef ! msg }
}
private def handleUserLeftVoiceConfMessage(msg: UserLeftVoiceConfMessage) {
findMeetingWithVoiceConfId(msg.voiceConfId) foreach { m =>
m.actorRef ! msg
}
}
private def handleUserLockedInVoiceConfMessage(msg: UserLockedInVoiceConfMessage) {
findMeetingWithVoiceConfId(msg.voiceConfId) foreach { m =>
m.actorRef ! msg
}
}
private def handleUserMutedInVoiceConfMessage(msg: UserMutedInVoiceConfMessage) {
findMeetingWithVoiceConfId(msg.voiceConfId) foreach { m =>
m.actorRef ! msg
}
}
private def handleVoiceConfRecordingStartedMessage(msg: VoiceConfRecordingStartedMessage) {
findMeetingWithVoiceConfId(msg.voiceConfId) foreach { m =>
m.actorRef ! msg
}
}
private def handleUserTalkingInVoiceConfMessage(msg: UserTalkingInVoiceConfMessage) {
findMeetingWithVoiceConfId(msg.voiceConfId) foreach { m =>
m.actorRef ! msg
}
} }
private def handleValidateAuthToken(msg: ValidateAuthToken) { private def handleValidateAuthToken(msg: ValidateAuthToken) {
@ -162,9 +198,61 @@ class BigBlueButtonActor(val system: ActorSystem,
//send lock settings //send lock settings
self ! (new GetLockSettings(id, "nodeJSapp")) self ! (new GetLockSettings(id, "nodeJSapp"))
//send desktop sharing info
self ! (new DeskShareGetDeskShareInfoRequest(id, "nodeJSapp", "nodeJSapp"))
} }
outGW.send(new GetAllMeetingsReply(resultArray)) outGW.send(new GetAllMeetingsReply(resultArray))
} }
private def handleDeskShareStartedRequest(msg: DeskShareStartedRequest) {
log.info("handleDeskShareStartedRequest: msg.conferenceName=" + msg.conferenceName)
findMeetingWithVoiceConfId(msg.conferenceName) foreach { m =>
{
// println(msg.conferenceName + " (in for each) handleDeskShareStartedRequest BBBActor ")
m.actorRef ! msg
} }
}
}
private def handleDeskShareStoppedRequest(msg: DeskShareStoppedRequest) {
log.info("handleDeskShareStoppedRequest msg.conferenceName=" + msg.conferenceName)
findMeetingWithVoiceConfId(msg.conferenceName) foreach { m =>
{
// println(msg.conferenceName + " (in for each) handleDeskShareStoppedRequest BBBActor ")
m.actorRef ! msg
}
}
}
private def handleDeskShareRTMPBroadcastStartedRequest(msg: DeskShareRTMPBroadcastStartedRequest) {
log.info("handleDeskShareRTMPBroadcastStartedRequest msg.conferenceName=" + msg.conferenceName)
findMeetingWithVoiceConfId(msg.conferenceName) foreach { m =>
{
// println(msg.conferenceName + " (in for each) handleDeskShareRTMPBroadcastStartedRequest BBBActor ")
m.actorRef ! msg
}
}
}
private def handleDeskShareRTMPBroadcastStoppedRequest(msg: DeskShareRTMPBroadcastStoppedRequest) {
log.info("handleDeskShareRTMPBroadcastStoppedRequest msg.conferenceName=" + msg.conferenceName)
findMeetingWithVoiceConfId(msg.conferenceName) foreach { m =>
{
// println(msg.conferenceName + " (in for each) handleDeskShareRTMPBroadcastStoppedRequest BBBActor ")
m.actorRef ! msg
}
}
}
private def handleDeskShareGetDeskShareInfoRequest(msg: DeskShareGetDeskShareInfoRequest): Unit = {
val m = meetings.values.find(m => {
m.mProps.meetingID == msg.conferenceName
})
m foreach { mActor => mActor.actorRef ! msg }
}
}

View File

@ -26,13 +26,12 @@ import spray.json.JsonParser
class BigBlueButtonInGW( class BigBlueButtonInGW(
val system: ActorSystem, val system: ActorSystem,
eventBus: IncomingEventBus, eventBus: IncomingEventBus,
outGW: OutMessageGateway) extends IBigBlueButtonInGW { outGW: OutMessageGateway,
val red5DeskShareIP: String,
val red5DeskShareApp: String) extends IBigBlueButtonInGW {
val log = Logging(system, getClass) val log = Logging(system, getClass)
val bbbActor = system.actorOf(BigBlueButtonActor.props(system, eventBus, outGW), "bigbluebutton-actor")
val bbbActor = system.actorOf(
BigBlueButtonActor.props(system, eventBus, outGW), "bigbluebutton-actor")
eventBus.subscribe(bbbActor, "meeting-manager") eventBus.subscribe(bbbActor, "meeting-manager")
def handleBigBlueButtonMessage(message: IBigBlueButtonMessage) { def handleBigBlueButtonMessage(message: IBigBlueButtonMessage) {
@ -68,12 +67,10 @@ class BigBlueButtonInGW(
msg.payload.viewerPassword, msg.payload.viewerPassword,
msg.payload.createTime, msg.payload.createTime,
msg.payload.createDate, msg.payload.createDate,
red5DeskShareIP, red5DeskShareApp,
msg.payload.isBreakout) msg.payload.isBreakout)
eventBus.publish( eventBus.publish(BigBlueButtonEvent("meeting-manager", new CreateMeeting(msg.payload.id, mProps)))
BigBlueButtonEvent(
"meeting-manager",
new CreateMeeting(msg.payload.id, mProps)))
} }
} }
} }
@ -137,9 +134,9 @@ class BigBlueButtonInGW(
eventBus.publish(BigBlueButtonEvent(meetingId, new ValidateAuthToken(meetingId, userId, token, correlationId, sessionId))) eventBus.publish(BigBlueButtonEvent(meetingId, new ValidateAuthToken(meetingId, userId, token, correlationId, sessionId)))
} }
def registerUser(meetingID: String, userID: String, name: String, role: String, extUserID: String, authToken: String): Unit = { def registerUser(meetingID: String, userID: String, name: String, role: String, extUserID: String, authToken: String, avatarURL: String): Unit = {
val userRole = if (role == "MODERATOR") Role.MODERATOR else Role.VIEWER val userRole = if (role == "MODERATOR") Role.MODERATOR else Role.VIEWER
eventBus.publish(BigBlueButtonEvent(meetingID, new RegisterUser(meetingID, userID, name, userRole, extUserID, authToken))) eventBus.publish(BigBlueButtonEvent(meetingID, new RegisterUser(meetingID, userID, name, userRole, extUserID, authToken, avatarURL)))
} }
def sendLockSettings(meetingID: String, userId: String, settings: java.util.Map[String, java.lang.Boolean]) { def sendLockSettings(meetingID: String, userId: String, settings: java.util.Map[String, java.lang.Boolean]) {
@ -470,9 +467,9 @@ class BigBlueButtonInGW(
} }
def voiceUserJoined(voiceConfId: String, voiceUserId: String, userId: String, callerIdName: String, def voiceUserJoined(voiceConfId: String, voiceUserId: String, userId: String, callerIdName: String,
callerIdNum: String, muted: java.lang.Boolean, talking: java.lang.Boolean) { callerIdNum: String, muted: java.lang.Boolean, avatarURL: String, talking: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(voiceConfId, new UserJoinedVoiceConfMessage(voiceConfId, voiceUserId, userId, userId, callerIdName, eventBus.publish(BigBlueButtonEvent(voiceConfId, new UserJoinedVoiceConfMessage(voiceConfId, voiceUserId, userId, userId, callerIdName,
callerIdNum, muted, talking, false /*hardcode listenOnly to false as the message for listenOnly is ConnectedToGlobalAudio*/ ))) callerIdNum, muted, talking, avatarURL, false /*hardcode listenOnly to false as the message for listenOnly is ConnectedToGlobalAudio*/ )))
} }
def voiceUserLeft(voiceConfId: String, voiceUserId: String) { def voiceUserLeft(voiceConfId: String, voiceUserId: String) {
@ -497,10 +494,30 @@ class BigBlueButtonInGW(
/** /**
* ******************************************************************* * *******************************************************************
* Message Interface for Polling * Message Interface for DeskShare
* ***************************************************************** * *****************************************************************
*/ */
def deskShareStarted(conferenceName: String, callerId: String, callerIdName: String) {
bbbActor ! new DeskShareStartedRequest(conferenceName, callerId, callerIdName)
}
def deskShareStopped(conferenceName: String, callerId: String, callerIdName: String) {
bbbActor ! new DeskShareStoppedRequest(conferenceName, callerId, callerIdName)
}
def deskShareRTMPBroadcastStarted(conferenceName: String, streamname: String, videoWidth: Int, videoHeight: Int, timestamp: String) {
bbbActor ! new DeskShareRTMPBroadcastStartedRequest(conferenceName, streamname, videoWidth, videoHeight, timestamp)
}
def deskShareRTMPBroadcastStopped(conferenceName: String, streamname: String, videoWidth: Int, videoHeight: Int, timestamp: String) {
bbbActor ! new DeskShareRTMPBroadcastStoppedRequest(conferenceName, streamname, videoWidth, videoHeight, timestamp)
}
def deskShareGetInfoRequest(meetingId: String, requesterId: String, replyTo: String): Unit = {
bbbActor ! new DeskShareGetDeskShareInfoRequest(meetingId, requesterId, replyTo)
}
// Polling
def votePoll(meetingId: String, userId: String, pollId: String, questionId: Integer, answerId: Integer) { def votePoll(meetingId: String, userId: String, pollId: String, questionId: Integer, answerId: Integer) {
eventBus.publish(BigBlueButtonEvent(meetingId, new RespondToPollRequest(meetingId, userId, pollId, questionId, answerId))) eventBus.publish(BigBlueButtonEvent(meetingId, new RespondToPollRequest(meetingId, userId, pollId, questionId, answerId)))
} }

View File

@ -22,6 +22,8 @@ import org.bigbluebutton.core.pubsub.senders.UsersMessageToJsonConverter
import org.bigbluebutton.common.messages._ import org.bigbluebutton.common.messages._
import org.bigbluebutton.core.pubsub.senders.WhiteboardMessageToJsonConverter import org.bigbluebutton.core.pubsub.senders.WhiteboardMessageToJsonConverter
import org.bigbluebutton.common.converters.ToJsonEncoder import org.bigbluebutton.common.converters.ToJsonEncoder
import org.bigbluebutton.common.messages.payload._
import org.bigbluebutton.common.messages._
import org.bigbluebutton.messages.payload._ import org.bigbluebutton.messages.payload._
import org.bigbluebutton.messages._ import org.bigbluebutton.messages._

View File

@ -181,4 +181,74 @@ class MeetingActor(val mProps: MeetingProperties,
case _ => // do nothing case _ => // do nothing
} }
// Broadcast video stream,
private def handleDeskShareStartedRequest(msg: DeskShareStartedRequest) {
log.info("handleDeskShareStartedRequest: dsStarted=" + meetingModel.getDeskShareStarted())
if (!meetingModel.getDeskShareStarted()) {
val timestamp = System.currentTimeMillis().toString()
val streamPath = "rtmp://" + mProps.red5DeskShareIP + "/" + mProps.red5DeskShareApp +
"/" + mProps.meetingID + "/" + mProps.meetingID + "-" + timestamp
log.info("handleDeskShareStartedRequest: streamPath=" + streamPath)
// Tell FreeSwitch to broadcast to RTMP
outGW.send(new DeskShareStartRTMPBroadcast(msg.conferenceName, streamPath))
meetingModel.setDeskShareStarted(true)
}
}
private def handleDeskShareStoppedRequest(msg: DeskShareStoppedRequest) {
log.info("handleDeskShareStoppedRequest: dsStarted=" + meetingModel.getDeskShareStarted())
// Tell FreeSwitch to stop broadcasting to RTMP
outGW.send(new DeskShareStopRTMPBroadcast(msg.conferenceName, meetingModel.getRTMPBroadcastingUrl()))
meetingModel.setDeskShareStarted(false)
}
private def handleDeskShareRTMPBroadcastStartedRequest(msg: DeskShareRTMPBroadcastStartedRequest) {
log.info("handleDeskShareRTMPBroadcastStartedRequest: isBroadcastingRTMP=" + meetingModel.isBroadcastingRTMP())
// only valid if not broadcasting yet
if (!meetingModel.isBroadcastingRTMP()) {
meetingModel.setRTMPBroadcastingUrl(msg.streamname)
meetingModel.broadcastingRTMPStarted()
meetingModel.setDesktopShareVideoWidth(msg.videoWidth)
meetingModel.setDesktopShareVideoHeight(msg.videoHeight)
log.info("START broadcast ALLOWED when isBroadcastingRTMP=false")
// Notify viewers in the meeting that there's an rtmp stream to view
outGW.send(new DeskShareNotifyViewersRTMP(mProps.meetingID, msg.streamname, msg.videoWidth, msg.videoHeight, true))
} else {
log.info("START broadcast NOT ALLOWED when isBroadcastingRTMP=true")
}
}
private def handleDeskShareRTMPBroadcastStoppedRequest(msg: DeskShareRTMPBroadcastStoppedRequest) {
log.info("handleDeskShareRTMPBroadcastStoppedRequest: isBroadcastingRTMP=" + meetingModel.isBroadcastingRTMP())
// only valid if currently broadcasting
if (meetingModel.isBroadcastingRTMP()) {
log.info("STOP broadcast ALLOWED when isBroadcastingRTMP=true")
meetingModel.broadcastingRTMPStopped()
// notify viewers that RTMP broadcast stopped
outGW.send(new DeskShareNotifyViewersRTMP(mProps.meetingID, meetingModel.getRTMPBroadcastingUrl(),
msg.videoWidth, msg.videoHeight, false))
} else {
log.info("STOP broadcast NOT ALLOWED when isBroadcastingRTMP=false")
}
}
private def handleDeskShareGetDeskShareInfoRequest(msg: DeskShareGetDeskShareInfoRequest): Unit = {
log.info("handleDeskShareGetDeskShareInfoRequest: " + msg.conferenceName + "isBroadcasting=" + meetingModel.isBroadcastingRTMP())
if (meetingModel.isBroadcastingRTMP()) {
// if the meeting has an ongoing WebRTC Deskshare session, send a notification
outGW.send(new DeskShareNotifyASingleViewer(mProps.meetingID, msg.requesterID, meetingModel.getRTMPBroadcastingUrl(),
meetingModel.getDesktopShareVideoWidth(), meetingModel.getDesktopShareVideoHeight(), true))
}
}
} }

View File

@ -6,7 +6,8 @@ import java.util.concurrent.TimeUnit
case object StopMeetingActor case object StopMeetingActor
case class MeetingProperties(meetingID: String, externalMeetingID: String, meetingName: String, recorded: Boolean, case class MeetingProperties(meetingID: String, externalMeetingID: String, meetingName: String, recorded: Boolean,
voiceBridge: String, duration: Int, autoStartRecording: Boolean, allowStartStopRecording: Boolean, voiceBridge: String, duration: Int, autoStartRecording: Boolean, allowStartStopRecording: Boolean,
moderatorPass: String, viewerPass: String, createTime: Long, createDate: String, isBreakout: Boolean) moderatorPass: String, viewerPass: String, createTime: Long, createDate: String,
red5DeskShareIP: String, red5DeskShareApp: String, isBreakout: Boolean)
case class MeetingExtensionProp(maxExtensions: Int = 2, numExtensions: Int = 0, extendByMinutes: Int = 20, case class MeetingExtensionProp(maxExtensions: Int = 2, numExtensions: Int = 0, extendByMinutes: Int = 20,
sendNotice: Boolean = true, sent15MinNotice: Boolean = false, sendNotice: Boolean = true, sent15MinNotice: Boolean = false,
@ -17,6 +18,7 @@ class MeetingModel {
private var permissionsInited = false private var permissionsInited = false
private var permissions = new Permissions() private var permissions = new Permissions()
private var recording = false; private var recording = false;
private var broadcastingRTMP = false
private var muted = false; private var muted = false;
private var meetingEnded = false private var meetingEnded = false
private var meetingMuted = false private var meetingMuted = false
@ -26,11 +28,69 @@ class MeetingModel {
private var lastWebUserLeftOnTimestamp: Long = 0 private var lastWebUserLeftOnTimestamp: Long = 0
private var voiceRecordingFilename: String = "" private var voiceRecordingFilename: String = ""
private var rtmpBroadcastingUrl: String = ""
private var deskShareStarted = false
private var desktopShareVideoWidth = 0
private var desktopShareVideoHeight = 0
private var extension = new MeetingExtensionProp private var extension = new MeetingExtensionProp
val startedOn = timeNowInMinutes; val startedOn = timeNowInMinutes;
def resetDesktopSharingParams() = {
broadcastingRTMP = false
deskShareStarted = false
rtmpBroadcastingUrl = ""
desktopShareVideoWidth = 0
desktopShareVideoHeight = 0
}
def getDeskShareStarted(): Boolean = {
return deskShareStarted
}
def setDeskShareStarted(b: Boolean) {
deskShareStarted = b
println("---deskshare status changed to:" + b)
}
def setDesktopShareVideoWidth(videoWidth: Int) {
desktopShareVideoWidth = videoWidth
}
def setDesktopShareVideoHeight(videoHeight: Int) {
desktopShareVideoHeight = videoHeight
}
def getDesktopShareVideoWidth(): Int = {
desktopShareVideoWidth
}
def getDesktopShareVideoHeight(): Int = {
desktopShareVideoHeight
}
def broadcastingRTMPStarted() {
broadcastingRTMP = true
}
def isBroadcastingRTMP(): Boolean = {
broadcastingRTMP
}
def broadcastingRTMPStopped() {
broadcastingRTMP = false
}
def setRTMPBroadcastingUrl(path: String) {
println("---RTMP broadcastUrl changed to:" + path)
rtmpBroadcastingUrl = path
}
def getRTMPBroadcastingUrl(): String = {
rtmpBroadcastingUrl
}
def isExtensionAllowed(): Boolean = extension.numExtensions < extension.maxExtensions def isExtensionAllowed(): Boolean = extension.numExtensions < extension.maxExtensions
def incNumExtension(): Int = { def incNumExtension(): Int = {
if (extension.numExtensions < extension.maxExtensions) { if (extension.numExtensions < extension.maxExtensions) {

View File

@ -12,6 +12,7 @@ import org.bigbluebutton.common.messages.StopRecordingVoiceConfRequestMessage
import org.bigbluebutton.core.pubsub.senders.MeetingMessageToJsonConverter import org.bigbluebutton.core.pubsub.senders.MeetingMessageToJsonConverter
import org.bigbluebutton.core.pubsub.senders.PesentationMessageToJsonConverter import org.bigbluebutton.core.pubsub.senders.PesentationMessageToJsonConverter
import org.bigbluebutton.core.pubsub.senders.CaptionMessageToJsonConverter import org.bigbluebutton.core.pubsub.senders.CaptionMessageToJsonConverter
import org.bigbluebutton.core.pubsub.senders.DeskShareMessageToJsonConverter
import org.bigbluebutton.common.messages.GetPresentationInfoReplyMessage import org.bigbluebutton.common.messages.GetPresentationInfoReplyMessage
import org.bigbluebutton.common.messages.PresentationRemovedMessage import org.bigbluebutton.common.messages.PresentationRemovedMessage
import org.bigbluebutton.core.apps.Page import org.bigbluebutton.core.apps.Page
@ -128,6 +129,11 @@ class MessageSenderActor(val service: MessageSender)
case msg: SendCaptionHistoryReply => handleSendCaptionHistoryReply(msg) case msg: SendCaptionHistoryReply => handleSendCaptionHistoryReply(msg)
case msg: UpdateCaptionOwnerReply => handleUpdateCaptionOwnerReply(msg) case msg: UpdateCaptionOwnerReply => handleUpdateCaptionOwnerReply(msg)
case msg: EditCaptionHistoryReply => handleEditCaptionHistoryReply(msg) case msg: EditCaptionHistoryReply => handleEditCaptionHistoryReply(msg)
case msg: DeskShareStartRTMPBroadcast => handleDeskShareStartRTMPBroadcast(msg)
case msg: DeskShareStopRTMPBroadcast => handleDeskShareStopRTMPBroadcast(msg)
case msg: DeskShareNotifyViewersRTMP => handleDeskShareNotifyViewersRTMP(msg)
case msg: DeskShareNotifyASingleViewer => handleDeskShareNotifyASingleViewer(msg)
case msg: DeskShareHangUp => handleDeskShareHangUp(msg)
case _ => // do nothing case _ => // do nothing
} }
@ -136,6 +142,31 @@ class MessageSenderActor(val service: MessageSender)
service.send(MessagingConstants.FROM_USERS_CHANNEL, m.toJson) service.send(MessagingConstants.FROM_USERS_CHANNEL, m.toJson)
} }
private def handleDeskShareHangUp(msg: DeskShareHangUp) {
val json = DeskShareMessageToJsonConverter.getDeskShareHangUpToJson(msg)
service.send(MessagingConstants.TO_VOICE_CONF_SYSTEM_CHAN, json)
}
private def handleDeskShareStopRTMPBroadcast(msg: DeskShareStopRTMPBroadcast) {
val json = DeskShareMessageToJsonConverter.getDeskShareStopRTMPBroadcastToJson(msg)
service.send(MessagingConstants.TO_VOICE_CONF_SYSTEM_CHAN, json)
}
private def handleDeskShareNotifyViewersRTMP(msg: DeskShareNotifyViewersRTMP) {
val json = DeskShareMessageToJsonConverter.getDeskShareNotifyViewersRTMPToJson(msg)
service.send(MessagingConstants.FROM_DESK_SHARE_CHANNEL, json)
}
def handleDeskShareNotifyASingleViewer(msg: DeskShareNotifyASingleViewer) {
val json = DeskShareMessageToJsonConverter.getDeskShareNotifyASingleViewerToJson(msg)
service.send(MessagingConstants.FROM_DESK_SHARE_CHANNEL, json)
}
private def handleDeskShareStartRTMPBroadcast(msg: DeskShareStartRTMPBroadcast) {
val json = DeskShareMessageToJsonConverter.getDeskShareStartRTMPBroadcastToJson(msg)
service.send(MessagingConstants.TO_VOICE_CONF_SYSTEM_CHAN, json)
}
private def handleGetChatHistoryReply(msg: GetChatHistoryReply) { private def handleGetChatHistoryReply(msg: GetChatHistoryReply) {
val json = ChatMessageToJsonConverter.getChatHistoryReplyToJson(msg) val json = ChatMessageToJsonConverter.getChatHistoryReplyToJson(msg)
service.send(MessagingConstants.FROM_CHAT_CHANNEL, json) service.send(MessagingConstants.FROM_CHAT_CHANNEL, json)
@ -526,6 +557,7 @@ class MessageSenderActor(val service: MessageSender)
private def handleUserRegistered(msg: UserRegistered) { private def handleUserRegistered(msg: UserRegistered) {
val json = UsersMessageToJsonConverter.userRegisteredToJson(msg) val json = UsersMessageToJsonConverter.userRegisteredToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json) service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
handleRegisteredUser(msg);
} }
private def handleUserStatusChange(msg: UserStatusChange) { private def handleUserStatusChange(msg: UserStatusChange) {

View File

@ -29,7 +29,11 @@ import org.bigbluebutton.core.recorders.events.ParticipantEndAndKickAllRecordEve
import org.bigbluebutton.core.recorders.events.UndoShapeWhiteboardRecordEvent import org.bigbluebutton.core.recorders.events.UndoShapeWhiteboardRecordEvent
import org.bigbluebutton.core.recorders.events.ClearPageWhiteboardRecordEvent import org.bigbluebutton.core.recorders.events.ClearPageWhiteboardRecordEvent
import org.bigbluebutton.core.recorders.events.AddShapeWhiteboardRecordEvent import org.bigbluebutton.core.recorders.events.AddShapeWhiteboardRecordEvent
import org.bigbluebutton.core.service.whiteboard.WhiteboardKeyUtil import org.bigbluebutton.core.recorders.events.DeskShareStartRTMPRecordEvent
import org.bigbluebutton.core.recorders.events.DeskShareStopRTMPRecordEvent
import org.bigbluebutton.core.recorders.events.DeskShareNotifyViewersRTMPRecordEvent
// import org.bigbluebutton.core.service.whiteboard.WhiteboardKeyUtil
import org.bigbluebutton.common.messages.WhiteboardKeyUtil
import org.bigbluebutton.core.recorders.events.ModifyTextWhiteboardRecordEvent import org.bigbluebutton.core.recorders.events.ModifyTextWhiteboardRecordEvent
import org.bigbluebutton.core.recorders.events.EditCaptionHistoryRecordEvent import org.bigbluebutton.core.recorders.events.EditCaptionHistoryRecordEvent
import scala.collection.immutable.StringOps import scala.collection.immutable.StringOps
@ -69,6 +73,9 @@ class RecorderActor(val recorder: RecorderApplication)
case msg: ClearWhiteboardEvent => handleClearWhiteboardEvent(msg) case msg: ClearWhiteboardEvent => handleClearWhiteboardEvent(msg)
case msg: UndoWhiteboardEvent => handleUndoWhiteboardEvent(msg) case msg: UndoWhiteboardEvent => handleUndoWhiteboardEvent(msg)
case msg: EditCaptionHistoryReply => handleEditCaptionHistoryReply(msg) case msg: EditCaptionHistoryReply => handleEditCaptionHistoryReply(msg)
case msg: DeskShareStartRTMPBroadcast => handleDeskShareStartRTMPBroadcast(msg)
case msg: DeskShareStopRTMPBroadcast => handleDeskShareStopRTMPBroadcast(msg)
case msg: DeskShareNotifyViewersRTMP => handleDeskShareNotifyViewersRTMP(msg)
case _ => // do nothing case _ => // do nothing
} }
@ -449,4 +456,33 @@ class RecorderActor(val recorder: RecorderApplication)
recorder.record(msg.meetingID, ev); recorder.record(msg.meetingID, ev);
} }
} }
private def handleDeskShareStartRTMPBroadcast(msg: DeskShareStartRTMPBroadcast) {
val event = new DeskShareStartRTMPRecordEvent()
event.setMeetingId(msg.conferenceName)
event.setStreamPath(msg.streamPath)
event.setTimestamp(TimestampGenerator.generateTimestamp)
log.info("handleDeskShareStartRTMPBroadcast " + msg.conferenceName)
recorder.record(msg.conferenceName, event)
}
private def handleDeskShareStopRTMPBroadcast(msg: DeskShareStopRTMPBroadcast) {
val event = new DeskShareStopRTMPRecordEvent()
event.setMeetingId(msg.conferenceName)
event.setStreamPath(msg.streamPath)
event.setTimestamp(TimestampGenerator.generateTimestamp)
log.info("handleDeskShareStopRTMPBroadcast " + msg.conferenceName)
recorder.record(msg.conferenceName, event)
}
private def handleDeskShareNotifyViewersRTMP(msg: DeskShareNotifyViewersRTMP) {
val event = new DeskShareNotifyViewersRTMPRecordEvent()
event.setMeetingId(msg.meetingID)
event.setStreamPath(msg.streamPath)
event.setBroadcasting(msg.broadcasting)
event.setTimestamp(TimestampGenerator.generateTimestamp)
log.info("handleDeskShareNotifyViewersRTMP " + msg.meetingID)
recorder.record(msg.meetingID, event)
}
} }

View File

@ -78,7 +78,7 @@ case class GetLockSettings(meetingID: String, userId: String) extends InMessage
case class ValidateAuthToken(meetingID: String, userId: String, token: String, 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, case class RegisterUser(meetingID: String, userID: String, name: String, role: Role,
extUserID: String, authToken: String) extends InMessage extUserID: String, authToken: String, avatarURL: String) extends InMessage
case class UserJoining(meetingID: String, userID: String, authToken: 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 UserLeaving(meetingID: String, userID: String, sessionId: String) extends InMessage
case class GetUsers(meetingID: String, requesterID: String) extends InMessage case class GetUsers(meetingID: String, requesterID: String) extends InMessage
@ -165,7 +165,7 @@ case class EjectUserFromVoiceRequest(meetingID: String, userId: String, ejectedB
case class VoiceUserJoinedMessage(meetingID: String, user: String, voiceConfId: String, 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, case class UserJoinedVoiceConfMessage(voiceConfId: String, voiceUserId: String, userId: String, externUserId: String,
callerIdName: String, callerIdNum: String, muted: Boolean, talking: Boolean, 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 UserLeftVoiceConfMessage(voiceConfId: String, voiceUserId: String) extends InMessage
case class UserLockedInVoiceConfMessage(voiceConfId: String, voiceUserId: String, locked: Boolean) extends InMessage case class UserLockedInVoiceConfMessage(voiceConfId: String, voiceUserId: String, locked: Boolean) extends InMessage
case class UserMutedInVoiceConfMessage(voiceConfId: String, voiceUserId: String, muted: Boolean) extends InMessage case class UserMutedInVoiceConfMessage(voiceConfId: String, voiceUserId: String, muted: Boolean) extends InMessage
@ -188,3 +188,10 @@ case class GetAllMeetingsRequest(meetingID: String /** Not used. Just to satisfy
case class SendCaptionHistoryRequest(meetingID: String, requesterID: String) extends InMessage case class SendCaptionHistoryRequest(meetingID: String, requesterID: String) extends InMessage
case class UpdateCaptionOwnerRequest(meetingID: String, locale: String, ownerID: String) extends InMessage case class UpdateCaptionOwnerRequest(meetingID: String, locale: String, ownerID: String) extends InMessage
case class EditCaptionHistoryRequest(meetingID: String, userID: String, startIndex: Integer, endIndex: Integer, locale: String, text: String) extends InMessage case class EditCaptionHistoryRequest(meetingID: String, userID: String, startIndex: Integer, endIndex: Integer, locale: String, text: String) extends InMessage
// DeskShare
case class DeskShareStartedRequest(conferenceName: String, callerId: String, callerIdName: String)
case class DeskShareStoppedRequest(conferenceName: String, callerId: String, callerIdName: String)
case class DeskShareRTMPBroadcastStartedRequest(conferenceName: String, streamname: String, videoWidth: Int, videoHeight: Int, timestamp: String)
case class DeskShareRTMPBroadcastStoppedRequest(conferenceName: String, streamname: String, videoWidth: Int, videoHeight: Int, timestamp: String)
case class DeskShareGetDeskShareInfoRequest(conferenceName: String, requesterID: String, replyTo: String)

View File

@ -15,7 +15,7 @@ case class VoiceRecordingStopped(meetingID: String, recorded: Boolean, recording
case class RecordingStatusChanged(meetingID: String, recorded: Boolean, userId: String, recording: Boolean) 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 GetRecordingStatusReply(meetingID: String, recorded: Boolean, userId: String, recording: Boolean) extends IOutMessage
case class MeetingCreated(meetingID: String, externalMeetingID: String, recorded: Boolean, name: String, case class MeetingCreated(meetingID: String, externalMeetingID: String, recorded: Boolean, name: String,
voiceBridge: String, duration: Integer, moderatorPass: String, viewerPass: String, createTime: Long, createDate: String) extends IOutMessage voiceBridge: String, duration: Int, moderatorPass: String, viewerPass: String, createTime: Long, createDate: String) extends IOutMessage
case class MeetingMuted(meetingID: String, recorded: Boolean, meetingMuted: 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 MeetingEnded(meetingID: String, recorded: Boolean, voiceBridge: String) extends IOutMessage
case class MeetingState(meetingID: String, recorded: Boolean, userId: String, permissions: Permissions, meetingMuted: Boolean) extends IOutMessage case class MeetingState(meetingID: String, recorded: Boolean, userId: String, permissions: Permissions, meetingMuted: Boolean) extends IOutMessage
@ -148,6 +148,12 @@ case class GetAllMeetingsReply(meetings: Array[MeetingInfo]) extends IOutMessage
case class SendCaptionHistoryReply(meetingID: String, recorded: Boolean, requesterID: String, history: Map[String, Array[String]]) extends IOutMessage case class SendCaptionHistoryReply(meetingID: String, recorded: Boolean, requesterID: String, history: Map[String, Array[String]]) extends IOutMessage
case class UpdateCaptionOwnerReply(meetingID: String, recorded: Boolean, locale: String, ownerID: String) extends IOutMessage case class UpdateCaptionOwnerReply(meetingID: String, recorded: Boolean, locale: String, ownerID: String) extends IOutMessage
case class EditCaptionHistoryReply(meetingID: String, recorded: Boolean, userID: String, startIndex: Integer, endIndex: Integer, locale: String, text: String) extends IOutMessage case class EditCaptionHistoryReply(meetingID: String, recorded: Boolean, userID: String, startIndex: Integer, endIndex: Integer, locale: String, text: String) extends IOutMessage
// DeskShare
case class DeskShareStartRTMPBroadcast(conferenceName: String, streamPath: String) extends IOutMessage
case class DeskShareStopRTMPBroadcast(conferenceName: String, streamPath: String) extends IOutMessage
case class DeskShareNotifyViewersRTMP(meetingID: String, streamPath: String, videoWidth: Int, videoHeight: Int, broadcasting: Boolean) extends IOutMessage
case class DeskShareNotifyASingleViewer(meetingID: String, userID: String, streamPath: String, videoWidth: Int, videoHeight: Int, broadcasting: Boolean) extends IOutMessage
case class DeskShareHangUp(meetingID: String, fsConferenceName: String) extends IOutMessage
// Value Objects // Value Objects
case class MeetingVO(id: String, recorded: Boolean) case class MeetingVO(id: String, recorded: Boolean)

View File

@ -69,7 +69,8 @@ case class RegisteredUser(
externId: String, externId: String,
name: String, name: String,
role: Role.Role, role: Role.Role,
authToken: String) authToken: String,
avatarURL: String)
case class Voice( case class Voice(
id: String, id: String,
@ -94,6 +95,7 @@ case class UserVO(
phoneUser: Boolean, phoneUser: Boolean,
voiceUser: VoiceUser, voiceUser: VoiceUser,
listenOnly: Boolean, listenOnly: Boolean,
avatarURL: String,
joinedWeb: Boolean) joinedWeb: Boolean)
case class VoiceUser( case class VoiceUser(
@ -105,6 +107,7 @@ case class VoiceUser(
locked: Boolean, locked: Boolean,
muted: Boolean, muted: Boolean,
talking: Boolean, talking: Boolean,
avatarURL: String,
listenOnly: Boolean) listenOnly: Boolean)
case class MeetingConfig(name: String, case class MeetingConfig(name: String,
@ -129,4 +132,9 @@ case class MeetingPasswords(moderatorPass: String, viewerPass: String)
case class MeetingDuration(duration: Int = 0, createdTime: Long = 0, case class MeetingDuration(duration: Int = 0, createdTime: Long = 0,
startTime: Long = 0, endTime: Long = 0) startTime: Long = 0, endTime: Long = 0)
case class MeetingInfo(meetingID: String, meetingName: String, recorded: Boolean, voiceBridge: String, duration: Int) case class MeetingInfo(
meetingID: String,
meetingName: String,
recorded: Boolean,
voiceBridge: String,
duration: Long)

View File

@ -3,7 +3,8 @@ package org.bigbluebutton.core.apps
import org.bigbluebutton.core.api._ import org.bigbluebutton.core.api._
import scala.collection.mutable.HashMap import scala.collection.mutable.HashMap
import scala.collection.mutable.ArrayBuffer import scala.collection.mutable.ArrayBuffer
import org.bigbluebutton.core.service.whiteboard.WhiteboardKeyUtil import org.bigbluebutton.common.messages.WhiteboardKeyUtil
// import org.bigbluebutton.core.service.whiteboard.WhiteboardKeyUtil
import com.google.gson.Gson import com.google.gson.Gson
import java.util.ArrayList import java.util.ArrayList
import org.bigbluebutton.core.OutMessageGateway import org.bigbluebutton.core.OutMessageGateway

View File

@ -120,7 +120,7 @@ trait UsersApp {
log.info("Register user failed. Mmeeting has ended. meetingId=" + mProps.meetingID + " userId=" + msg.userID) log.info("Register user failed. Mmeeting has ended. meetingId=" + mProps.meetingID + " userId=" + msg.userID)
sendMeetingHasEnded(msg.userID) sendMeetingHasEnded(msg.userID)
} else { } else {
val regUser = new RegisteredUser(msg.userID, msg.extUserID, msg.name, msg.role, msg.authToken) val regUser = new RegisteredUser(msg.userID, msg.extUserID, msg.name, msg.role, msg.authToken, msg.avatarURL)
usersModel.addRegisteredUser(msg.authToken, regUser) usersModel.addRegisteredUser(msg.authToken, regUser)
log.info("Register user success. meetingId=" + mProps.meetingID + " userId=" + msg.userID + " user=" + regUser) log.info("Register user success. meetingId=" + mProps.meetingID + " userId=" + msg.userID + " user=" + regUser)
@ -246,6 +246,18 @@ trait UsersApp {
+ ". Making user=[" + mod.userID + "] presenter.") + ". Making user=[" + mod.userID + "] presenter.")
assignNewPresenter(mod.userID, mod.name, mod.userID) assignNewPresenter(mod.userID, mod.name, mod.userID)
} }
if (meetingModel.isBroadcastingRTMP()) {
// The presenter left during desktop sharing. Stop desktop sharing on FreeSWITCH
outGW.send(new DeskShareHangUp(mProps.meetingID, mProps.voiceBridge))
// notify other clients to close their deskshare view
outGW.send(new DeskShareNotifyViewersRTMP(mProps.meetingID, meetingModel.getRTMPBroadcastingUrl(),
meetingModel.getDesktopShareVideoWidth(), meetingModel.getDesktopShareVideoHeight(), false))
// reset meeting info
meetingModel.resetDesktopSharingParams()
}
} }
} }
@ -329,7 +341,7 @@ trait UsersApp {
*/ */
new VoiceUser(u.voiceUser.userId, msg.userID, ru.name, ru.name, new VoiceUser(u.voiceUser.userId, msg.userID, ru.name, ru.name,
joined = false, locked = false, muted = false, joined = false, locked = false, muted = false,
talking = false, listenOnly = u.listenOnly) talking = false, u.avatarURL, listenOnly = u.listenOnly)
} }
} }
case None => { case None => {
@ -339,7 +351,7 @@ trait UsersApp {
*/ */
new VoiceUser(msg.userID, msg.userID, ru.name, ru.name, new VoiceUser(msg.userID, msg.userID, ru.name, ru.name,
joined = false, locked = false, joined = false, locked = false,
muted = false, talking = false, listenOnly = false) muted = false, talking = false, ru.avatarURL, listenOnly = false)
} }
} }
@ -363,7 +375,7 @@ trait UsersApp {
ru.role, emojiStatus = "none", presenter = false, ru.role, emojiStatus = "none", presenter = false,
hasStream = false, locked = getInitialLockStatus(ru.role), hasStream = false, locked = getInitialLockStatus(ru.role),
webcamStreams = new ListSet[String](), phoneUser = false, vu, webcamStreams = new ListSet[String](), phoneUser = false, vu,
listenOnly = vu.listenOnly, joinedWeb = true) listenOnly = vu.listenOnly, avatarURL = vu.avatarURL, joinedWeb = true)
usersModel.addUser(uvo) usersModel.addUser(uvo)
@ -399,9 +411,9 @@ trait UsersApp {
* and is reconnecting. Make the user as joined only in the voice conference. If we get a * and is reconnecting. Make the user as joined only in the voice conference. If we get a
* user left voice conference message, then we will remove the user from the users list. * user left voice conference message, then we will remove the user from the users list.
*/ */
switchUserToPhoneUser((new UserJoinedVoiceConfMessage(mProps.voiceBridge, switchUserToPhoneUser(new UserJoinedVoiceConfMessage(mProps.voiceBridge,
vu.userId, u.userID, u.externUserID, vu.callerName, vu.userId, u.userID, u.externUserID, vu.callerName,
vu.callerNum, vu.muted, vu.talking, u.listenOnly))); vu.callerNum, vu.muted, vu.talking, vu.avatarURL, u.listenOnly));
} }
checkCaptionOwnerLogOut(u.userID) checkCaptionOwnerLogOut(u.userID)
@ -438,7 +450,7 @@ trait UsersApp {
* If user is not joined listenOnly then user is joined calling through phone or webrtc. * If user is not joined listenOnly then user is joined calling through phone or webrtc.
*/ */
val vu = new VoiceUser(msg.voiceUserId, webUserId, msg.callerIdName, msg.callerIdNum, val vu = new VoiceUser(msg.voiceUserId, webUserId, msg.callerIdName, msg.callerIdNum,
joined = !msg.listenOnly, locked = false, muted = msg.muted, talking = msg.talking, listenOnly = msg.listenOnly) joined = !msg.listenOnly, locked = false, muted = msg.muted, talking = msg.talking, msg.avatarURL, listenOnly = msg.listenOnly)
/** /**
* If user is not joined listenOnly then user is joined calling through phone or webrtc. * If user is not joined listenOnly then user is joined calling through phone or webrtc.
@ -448,7 +460,7 @@ trait UsersApp {
Role.VIEWER, emojiStatus = "none", presenter = false, Role.VIEWER, emojiStatus = "none", presenter = false,
hasStream = false, locked = getInitialLockStatus(Role.VIEWER), hasStream = false, locked = getInitialLockStatus(Role.VIEWER),
webcamStreams = new ListSet[String](), webcamStreams = new ListSet[String](),
phoneUser = !msg.listenOnly, vu, listenOnly = msg.listenOnly, joinedWeb = false) phoneUser = !msg.listenOnly, vu, listenOnly = msg.listenOnly, avatarURL = msg.avatarURL, joinedWeb = false)
usersModel.addUser(uvo) usersModel.addUser(uvo)
@ -482,7 +494,7 @@ trait UsersApp {
case Some(user) => { case Some(user) => {
val vu = new VoiceUser(msg.voiceUserId, msg.userId, msg.callerIdName, val vu = new VoiceUser(msg.voiceUserId, msg.userId, msg.callerIdName,
msg.callerIdNum, joined = true, locked = false, msg.callerIdNum, joined = true, locked = false,
msg.muted, msg.talking, msg.listenOnly) msg.muted, msg.talking, msg.avatarURL, msg.listenOnly)
val nu = user.copy(voiceUser = vu, listenOnly = msg.listenOnly) val nu = user.copy(voiceUser = vu, listenOnly = msg.listenOnly)
usersModel.addUser(nu) usersModel.addUser(nu)
@ -512,7 +524,7 @@ trait UsersApp {
val vu = new VoiceUser(msg.voiceUserId, msg.userId, msg.callerIdName, val vu = new VoiceUser(msg.voiceUserId, msg.userId, msg.callerIdName,
msg.callerIdNum, joined = true, locked = false, msg.callerIdNum, joined = true, locked = false,
msg.muted, msg.talking, msg.listenOnly) msg.muted, msg.talking, msg.avatarURL, msg.listenOnly)
val nu = user.copy(voiceUser = vu, listenOnly = msg.listenOnly) val nu = user.copy(voiceUser = vu, listenOnly = msg.listenOnly)
usersModel.addUser(nu) usersModel.addUser(nu)
@ -552,7 +564,7 @@ trait UsersApp {
* Reset user's voice status. * Reset user's voice status.
*/ */
val vu = new VoiceUser(user.userID, user.userID, user.name, user.name, val vu = new VoiceUser(user.userID, user.userID, user.name, user.name,
joined = false, locked = false, muted = false, talking = false, listenOnly = false) joined = false, locked = false, muted = false, talking = false, user.avatarURL, listenOnly = false)
val nu = user.copy(voiceUser = vu, phoneUser = false, listenOnly = false) val nu = user.copy(voiceUser = vu, phoneUser = false, listenOnly = false)
usersModel.addUser(nu) usersModel.addUser(nu)

View File

@ -1,7 +1,7 @@
package org.bigbluebutton.core.apps package org.bigbluebutton.core.apps
import org.bigbluebutton.core.api._ import org.bigbluebutton.core.api._
import org.bigbluebutton.core.service.whiteboard.WhiteboardKeyUtil import org.bigbluebutton.common.messages.WhiteboardKeyUtil
import org.bigbluebutton.core.OutMessageGateway import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.LiveMeeting import org.bigbluebutton.core.LiveMeeting

View File

@ -9,7 +9,7 @@ import scala.collection.JavaConversions._
import java.util.ArrayList import java.util.ArrayList
import org.bigbluebutton.common.messages.MessagingConstants import org.bigbluebutton.common.messages.MessagingConstants
import org.bigbluebutton.core.messaging.Util import org.bigbluebutton.core.messaging.Util
import org.bigbluebutton.core.service.chat.ChatKeyUtil import org.bigbluebutton.common.messages.ChatKeyUtil
object ChatMessageToJsonConverter { object ChatMessageToJsonConverter {

View File

@ -0,0 +1,39 @@
package org.bigbluebutton.core.pubsub.senders
import org.bigbluebutton.core.api._
import org.bigbluebutton.common.messages.DeskShareStartRTMPBroadcastEventMessage
import org.bigbluebutton.common.messages.DeskShareStopRTMPBroadcastEventMessage
import org.bigbluebutton.common.messages.DeskShareNotifyViewersRTMPEventMessage
import org.bigbluebutton.common.messages.DeskShareNotifyASingleViewerEventMessage
import org.bigbluebutton.common.messages.DeskShareHangUpEventMessage
object DeskShareMessageToJsonConverter {
def getDeskShareHangUpToJson(msg: DeskShareHangUp): String = {
val newMsg = new DeskShareHangUpEventMessage(msg.meetingID, msg.fsConferenceName, TimestampGenerator.getCurrentTime.toString())
newMsg.toJson()
}
def getDeskShareNotifyASingleViewerToJson(msg: DeskShareNotifyASingleViewer): String = {
val newMsg = new DeskShareNotifyASingleViewerEventMessage(msg.meetingID, msg.userID,
msg.streamPath, msg.broadcasting, msg.videoWidth, msg.videoHeight, TimestampGenerator.getCurrentTime.toString())
newMsg.toJson()
}
def getDeskShareStartRTMPBroadcastToJson(msg: DeskShareStartRTMPBroadcast): String = {
val newMsg = new DeskShareStartRTMPBroadcastEventMessage(msg.conferenceName, msg.streamPath,
TimestampGenerator.getCurrentTime.toString())
newMsg.toJson()
}
def getDeskShareStopRTMPBroadcastToJson(msg: DeskShareStopRTMPBroadcast): String = {
val newMsg = new DeskShareStopRTMPBroadcastEventMessage(msg.conferenceName, msg.streamPath,
TimestampGenerator.getCurrentTime.toString())
newMsg.toJson()
}
def getDeskShareNotifyViewersRTMPToJson(msg: DeskShareNotifyViewersRTMP): String = {
val newMsg = new DeskShareNotifyViewersRTMPEventMessage(msg.meetingID, msg.streamPath,
msg.broadcasting, msg.videoWidth, msg.videoHeight, TimestampGenerator.getCurrentTime.toString())
newMsg.toJson()
}
}

View File

@ -23,6 +23,7 @@ object UsersMessageToJsonConverter {
wuser += "webcam_stream" -> user.webcamStreams.toArray wuser += "webcam_stream" -> user.webcamStreams.toArray
wuser += "phone_user" -> user.phoneUser wuser += "phone_user" -> user.phoneUser
wuser += "listenOnly" -> user.listenOnly wuser += "listenOnly" -> user.listenOnly
wuser += "avatarURL" -> user.avatarURL
val vuser = new scala.collection.mutable.HashMap[String, Any] val vuser = new scala.collection.mutable.HashMap[String, Any]
vuser += "userid" -> user.voiceUser.userId vuser += "userid" -> user.voiceUser.userId
@ -46,6 +47,7 @@ object UsersMessageToJsonConverter {
wuser += "name" -> user.name wuser += "name" -> user.name
wuser += "role" -> user.role.toString() wuser += "role" -> user.role.toString()
wuser += "authToken" -> user.authToken wuser += "authToken" -> user.authToken
wuser += "avatarURL" -> user.avatarURL
mapAsJavaMap(wuser) mapAsJavaMap(wuser)
} }

File diff suppressed because one or more lines are too long

View File

@ -24,6 +24,8 @@ resolvers ++= Seq(
"blindside-repos" at "http://blindside.googlecode.com/svn/repository/" "blindside-repos" at "http://blindside.googlecode.com/svn/repository/"
) )
resolvers += Resolver.sonatypeRepo("releases")
publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath+"/dev/repo/maven-repo/releases" )) ) publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath+"/dev/repo/maven-repo/releases" )) )
// We want to have our jar files in lib_managed dir. // We want to have our jar files in lib_managed dir.
@ -47,11 +49,11 @@ libraryDependencies ++= {
"com.etaty.rediscala" %% "rediscala" % "1.4.0", "com.etaty.rediscala" %% "rediscala" % "1.4.0",
"commons-codec" % "commons-codec" % "1.8", "commons-codec" % "commons-codec" % "1.8",
"joda-time" % "joda-time" % "2.3", "joda-time" % "joda-time" % "2.3",
"com.google.code.gson" % "gson" % "2.5", "com.google.code.gson" % "gson" % "1.7.1",
"redis.clients" % "jedis" % "2.1.0", "redis.clients" % "jedis" % "2.1.0",
"org.apache.commons" % "commons-lang3" % "3.2", "org.apache.commons" % "commons-lang3" % "3.2",
"org.bigbluebutton" % "bbb-common-message" % "0.0.17-SNAPSHOT", "org.bigbluebutton" % "bbb-common-message" % "0.0.18-SNAPSHOT",
"org.bigbluebutton" % "bbb-fsesl-client" % "0.0.3" "org.bigbluebutton" % "bbb-fsesl-client" % "0.0.4"
)} )}
seq(Revolver.settings: _*) seq(Revolver.settings: _*)

View File

@ -0,0 +1,73 @@
<!-- http://wiki.freeswitch.org/wiki/Mod_conference -->
<!-- None of these paths are real if you want any of these options you need to really set them up -->
<configuration name="conference.conf" description="Audio Conference">
<!-- Advertise certain presence on startup . -->
<advertise>
<room name="3001@$${domain}" status="FreeSWITCH"/>
</advertise>
<!-- These are the default keys that map when you do not specify a caller control group -->
<!-- Note: none and default are reserved names for group names. Disabled if dist-dtmf member flag is set. -->
<caller-controls>
<group name="default">
<control action="mute" digits="0"/>
<control action="deaf mute" digits="*"/>
<control action="energy up" digits="9"/>
<control action="energy equ" digits="8"/>
<control action="energy dn" digits="7"/>
<control action="vol talk up" digits="3"/>
<control action="vol talk zero" digits="2"/>
<control action="vol talk dn" digits="1"/>
<control action="vol listen up" digits="6"/>
<control action="vol listen zero" digits="5"/>
<control action="vol listen dn" digits="4"/>
<control action="hangup" digits="#"/>
</group>
</caller-controls>
<!-- Profiles are collections of settings you can reference by name. -->
<profiles>
<!-- profile used for WebRTC Desktop Sharing -->
<profile name="video-mcu-stereo">
<param name="domain" value="$${domain}"/>
<param name="rate" value="48000"/>
<param name="channels" value="2"/>
<param name="interval" value="20"/>
<param name="energy-level" value="200"/>
<!-- <param name="tts-engine" value="flite"/> -->
<!-- <param name="tts-voice" value="kal16"/> -->
<!--remove audio for when user is alone since we hit this case every time-->
<!--with -DESKSHARE conference. It has a single user only by default-->
<!--<param name="muted-sound" value="conference/conf-muted.wav"/>-->
<!--<param name="unmuted-sound" value="conference/conf-unmuted.wav"/>-->
<!-- <param name="alone-sound" value="conference/conf-alone.wav"/> -->
<!-- <param name="moh-sound" value="local_stream://stereo"/> -->
<!--<param name="enter-sound" value="tone_stream://%(200,0,500,600,700)"/>-->
<!--<param name="exit-sound" value="tone_stream://%(500,0,300,200,100,50,25)"/>-->
<!--<param name="kicked-sound" value="conference/conf-kicked.wav"/>-->
<!--<param name="locked-sound" value="conference/conf-locked.wav"/>-->
<!--<param name="is-locked-sound" value="conference/conf-is-locked.wav"/>-->
<!--<param name="is-unlocked-sound" value="conference/conf-is-unlocked.wav"/>-->
<!--<param name="pin-sound" value="conference/conf-pin.wav"/>-->
<!--<param name="bad-pin-sound" value="conference/conf-bad-pin.wav"/>-->
<param name="caller-id-name" value="$${outbound_caller_name}"/>
<param name="caller-id-number" value="$${outbound_caller_id}"/>
<param name="comfort-noise" value="false"/>
<param name="conference-flags" value="video-floor-only|video-required-for-canvas|rfc-4579|livearray-sync|minimize-video-encoding"/>
<param name="video-mode" value="mux"/> <!-- other values for video-mode are transcode or passthrough -->
<param name="video-layout-name" value="1x1"/> <!-- 1x1 since we only have 1 video stream -->
<param name="video-layout-name" value="group:grid"/>
<param name="video-canvas-size" value="1920x1080"/>
<param name="video-canvas-bgcolor" value="#333333"/>
<param name="video-layout-bgcolor" value="#000000"/>
<param name="video-codec-bandwidth" value="1mb"/>
<param name="video-fps" value="15"/>
</profile>
</profiles>
</configuration>

View File

@ -0,0 +1,30 @@
<configuration name="verto.conf" description="HTML5 Verto Endpoint">
<settings>
<param name="debug" value="10"/>
</settings>
<profiles>
<profile name="mine">
<param name="bind-local" value="0.0.0.0:8081"/>
<param name="bind-local" value="0.0.0.0:8082" secure="true"/>
<param name="force-register-domain" value="$${domain}"/>
<param name="secure-combined" value="$${certs_dir}/wss.pem"/>
<param name="secure-chain" value="$${certs_dir}/wss.pem"/>
<param name="userauth" value="true"/>
<!-- setting this to true will allow anyone to register even with no account so use with care -->
<param name="blind-reg" value="false"/>
<param name="mcast-ip" value="224.1.1.1"/>
<param name="mcast-port" value="1337"/>
<param name="rtp-ip" value="$${local_ip_v4}"/>
<!-- <param name="ext-rtp-ip" value=""/> -->
<param name="local-network" value="localnet.auto"/>
<param name="outbound-codec-string" value="opus,vp8"/>
<param name="inbound-codec-string" value="opus,vp8"/>
<param name="apply-candidate-acl" value="wan.auto"/>
<param name="timer-name" value="soft"/>
</profile>
</profiles>
</configuration>

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
NOTICE:
This context is usually accessed via authenticated callers on the sip profile on port 5060
or transfered callers from the public context which arrived via the sip profile on port 5080.
Authenticated users will use the user_context variable on the user to determine what context
they can access. You can also add a user in the directory with the cidr= attribute acl.conf.xml
will build the domains ACL using this value.
-->
<!-- http://wiki.freeswitch.org/wiki/Dialplan_XML -->
<include>
<context name="default">
<extension name="public_extensions">
<condition field="destination_number" expression="^\d{5}$">
<action application="log" data="INFO AAAAAA transferring to $1 XML public!!"/>
<action application="transfer" data="${destination_number} XML public"/>
</condition>
</extension>
<extension name="public_extensions">
<condition field="destination_number" expression="^(\d{5})(-screen)$">
<action application="log" data="INFO BB $1 $2 BBBB transferring to $1 XML public!!"/>
<action application="transfer" data="$1 XML public"/>
</condition>
</extension>
<!-- other extensions -->
</context>
</include>

View File

@ -0,0 +1,32 @@
<!--
NOTICE:
This context is usually accessed via the external sip profile listening on port 5080.
It is recommended to have separate inbound and outbound contexts. Not only for security
but clearing up why you would need to do such a thing. You don't want outside un-authenticated
callers hitting your default context which allows dialing calls thru your providers and results
in Toll Fraud.
-->
<!-- http://wiki.freeswitch.org/wiki/Dialplan_XML -->
<include>
<context name="public">
<!-- other extensions -->
<extension name="public_extensions">
<condition field="destination_number" expression="^\d{5}$">
<action application="log" data="INFO ************ redirecting ${destination_number} to ${destination_number}-DESKSHARE@video-mcu-stereo ***********" />
<action application="answer"/>
<action application="conference" data="${destination_number}-DESKSHARE@video-mcu-stereo"/>
</condition>
</extension>
<!--
You can place files in the public directory to get included.
-->
<X-PRE-PROCESS cmd="include" data="public/*.xml"/>
</context>
</include>

View File

@ -7,6 +7,9 @@ import org.bigbluebutton.common.messages.MuteUserInVoiceConfRequestMessage;
import org.bigbluebutton.common.messages.StartRecordingVoiceConfRequestMessage; import org.bigbluebutton.common.messages.StartRecordingVoiceConfRequestMessage;
import org.bigbluebutton.common.messages.StopRecordingVoiceConfRequestMessage; import org.bigbluebutton.common.messages.StopRecordingVoiceConfRequestMessage;
import org.bigbluebutton.common.messages.TransferUserToVoiceConfRequestMessage; import org.bigbluebutton.common.messages.TransferUserToVoiceConfRequestMessage;
import org.bigbluebutton.common.messages.DeskShareStartRTMPBroadcastEventMessage;
import org.bigbluebutton.common.messages.DeskShareStopRTMPBroadcastEventMessage;
import org.bigbluebutton.common.messages.DeskShareHangUpEventMessage;
import org.bigbluebutton.freeswitch.voice.freeswitch.FreeswitchApplication; import org.bigbluebutton.freeswitch.voice.freeswitch.FreeswitchApplication;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
@ -58,12 +61,39 @@ public class RedisMessageReceiver {
case StopRecordingVoiceConfRequestMessage.STOP_RECORD_VOICE_CONF_REQUEST: case StopRecordingVoiceConfRequestMessage.STOP_RECORD_VOICE_CONF_REQUEST:
processStopRecordingVoiceConfRequestMessage(message); processStopRecordingVoiceConfRequestMessage(message);
break; break;
case DeskShareStartRTMPBroadcastEventMessage.DESKSHARE_START_RTMP_BROADCAST_MESSAGE:
System.out.println("RedisMessageReceiver got DESKSHARE_START_RTMP_BROADCAST_MESSAGE");
processDeskShareStartRTMPBroadcastEventMessage(message);
break;
case DeskShareStopRTMPBroadcastEventMessage.DESKSHARE_STOP_RTMP_BROADCAST_MESSAGE:
System.out.println("RedisMessageReceiver got DESKSHARE_STOP_RTMP_BROADCAST_MESSAGE");
processDeskShareStopRTMPBroadcastEventMessage(message);
break;
case DeskShareHangUpEventMessage.DESKSHARE_HANG_UP_MESSAGE:
System.out.println("RedisMessageReceiver got DESKSHARE_HANG_UP_MESSAGE");
processDeskShareHangUpEventMessage(message);
break;
} }
} }
} }
} }
} }
private void processDeskShareStartRTMPBroadcastEventMessage(String json) {
DeskShareStartRTMPBroadcastEventMessage msg = DeskShareStartRTMPBroadcastEventMessage.fromJson(json);
fsApp.deskShareBroadcastRTMP(msg.conferenceName, msg.streamUrl, msg.timestamp, true);
}
private void processDeskShareStopRTMPBroadcastEventMessage(String json) {
DeskShareStopRTMPBroadcastEventMessage msg = DeskShareStopRTMPBroadcastEventMessage.fromJson(json);
fsApp.deskShareBroadcastRTMP(msg.conferenceName, msg.streamUrl, msg.timestamp, false);
}
private void processDeskShareHangUpEventMessage(String json) {
DeskShareHangUpEventMessage msg = DeskShareHangUpEventMessage.fromJson(json);
fsApp.deskShareHangUp(msg.conferenceName, msg.fsConferenceName, msg.timestamp);
}
private void processEjectAllVoiceUsersRequestMessage(String json) { private void processEjectAllVoiceUsersRequestMessage(String json) {
EjectAllUsersFromVoiceConfRequestMessage msg = EjectAllUsersFromVoiceConfRequestMessage EjectAllUsersFromVoiceConfRequestMessage msg = EjectAllUsersFromVoiceConfRequestMessage
.fromJson(json); .fromJson(json);

View File

@ -24,7 +24,10 @@ import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.bigbluebutton.freeswitch.voice.events.DeskShareStartedEvent;
import org.bigbluebutton.freeswitch.voice.events.DeskShareEndedEvent;
import org.bigbluebutton.freeswitch.voice.events.ConferenceEventListener; import org.bigbluebutton.freeswitch.voice.events.ConferenceEventListener;
import org.bigbluebutton.freeswitch.voice.events.DeskShareRTMPBroadcastEvent;
import org.bigbluebutton.freeswitch.voice.events.VoiceConferenceEvent; import org.bigbluebutton.freeswitch.voice.events.VoiceConferenceEvent;
import org.bigbluebutton.freeswitch.voice.events.VoiceStartRecordingEvent; import org.bigbluebutton.freeswitch.voice.events.VoiceStartRecordingEvent;
import org.bigbluebutton.freeswitch.voice.events.VoiceUserJoinedEvent; import org.bigbluebutton.freeswitch.voice.events.VoiceUserJoinedEvent;
@ -61,7 +64,7 @@ public class FreeswitchConferenceEventListener implements ConferenceEventListene
System.out.println("************** FreeswitchConferenceEventListener received voiceUserJoined "); System.out.println("************** FreeswitchConferenceEventListener received voiceUserJoined ");
VoiceUserJoinedEvent evt = (VoiceUserJoinedEvent) event; VoiceUserJoinedEvent evt = (VoiceUserJoinedEvent) event;
vcs.userJoinedVoiceConf(evt.getRoom(), evt.getVoiceUserId(), evt.getUserId(), evt.getCallerIdName(), vcs.userJoinedVoiceConf(evt.getRoom(), evt.getVoiceUserId(), evt.getUserId(), evt.getCallerIdName(),
evt.getCallerIdNum(), evt.getMuted(), evt.getSpeaking()); evt.getCallerIdNum(), evt.getMuted(), evt.getSpeaking(), evt.getAvatarURL());
} else if (event instanceof VoiceUserLeftEvent) { } else if (event instanceof VoiceUserLeftEvent) {
System.out.println("************** FreeswitchConferenceEventListener received VoiceUserLeftEvent "); System.out.println("************** FreeswitchConferenceEventListener received VoiceUserLeftEvent ");
VoiceUserLeftEvent evt = (VoiceUserLeftEvent) event; VoiceUserLeftEvent evt = (VoiceUserLeftEvent) event;
@ -78,6 +81,26 @@ public class FreeswitchConferenceEventListener implements ConferenceEventListene
VoiceStartRecordingEvent evt = (VoiceStartRecordingEvent) event; VoiceStartRecordingEvent evt = (VoiceStartRecordingEvent) event;
System.out.println("************** FreeswitchConferenceEventListener VoiceStartRecordingEvent recording=[" + evt.startRecord() + "]"); System.out.println("************** FreeswitchConferenceEventListener VoiceStartRecordingEvent recording=[" + evt.startRecord() + "]");
vcs.voiceConfRecordingStarted(evt.getRoom(), evt.getRecordingFilename(), evt.startRecord(), evt.getTimestamp()); vcs.voiceConfRecordingStarted(evt.getRoom(), evt.getRecordingFilename(), evt.startRecord(), evt.getTimestamp());
} else if (event instanceof DeskShareStartedEvent) {
DeskShareStartedEvent evt = (DeskShareStartedEvent) event;
System.out.println("************** FreeswitchConferenceEventListener DeskShareStartedEvent");
vcs.deskShareStarted(evt.getRoom(), evt.getCallerIdNum(), evt.getCallerIdName());
} else if (event instanceof DeskShareEndedEvent) {
DeskShareEndedEvent evt = (DeskShareEndedEvent) event;
System.out.println("************** FreeswitchConferenceEventListener DeskShareEndedEvent");
vcs.deskShareEnded(evt.getRoom(), evt.getCallerIdNum(), evt.getCallerIdName());
} else if (event instanceof DeskShareRTMPBroadcastEvent) {
if (((DeskShareRTMPBroadcastEvent) event).getBroadcast()) {
DeskShareRTMPBroadcastEvent evt = (DeskShareRTMPBroadcastEvent) event;
System.out.println("************** FreeswitchConferenceEventListener DeskShareRTMPBroadcastStartedEvent");
vcs.deskShareRTMPBroadcastStarted(evt.getRoom(), evt.getBroadcastingStreamUrl(),
evt.getVideoWidth(), evt.getVideoHeight(), evt.getTimestamp());
} else {
DeskShareRTMPBroadcastEvent evt = (DeskShareRTMPBroadcastEvent) event;
System.out.println("************** FreeswitchConferenceEventListener DeskShareRTMPBroadcastStoppedEvent");
vcs.deskShareRTMPBroadcastStopped(evt.getRoom(), evt.getBroadcastingStreamUrl(),
evt.getVideoWidth(), evt.getVideoHeight(), evt.getTimestamp());
}
} }
} }
}; };

View File

@ -3,10 +3,14 @@ package org.bigbluebutton.freeswitch.voice;
public interface IVoiceConferenceService { public interface IVoiceConferenceService {
void voiceConfRecordingStarted(String voiceConfId, String recordStream, Boolean recording, String timestamp); void voiceConfRecordingStarted(String voiceConfId, String recordStream, Boolean recording, String timestamp);
void userJoinedVoiceConf(String voiceConfId, String voiceUserId, String userId, String callerIdName, void userJoinedVoiceConf(String voiceConfId, String voiceUserId, String userId, String callerIdName,
String callerIdNum, Boolean muted, Boolean speaking); String callerIdNum, Boolean muted, Boolean speaking, String avatarURL);
void userLeftVoiceConf(String voiceConfId, String voiceUserId); void userLeftVoiceConf(String voiceConfId, String voiceUserId);
void userLockedInVoiceConf(String voiceConfId, String voiceUserId, Boolean locked); void userLockedInVoiceConf(String voiceConfId, String voiceUserId, Boolean locked);
void userMutedInVoiceConf(String voiceConfId, String voiceUserId, Boolean muted); void userMutedInVoiceConf(String voiceConfId, String voiceUserId, Boolean muted);
void userTalkingInVoiceConf(String voiceConfId, String voiceUserId, Boolean talking); void userTalkingInVoiceConf(String voiceConfId, String voiceUserId, Boolean talking);
void deskShareStarted(String voiceConfId, String callerIdNum, String callerIdName);
void deskShareEnded(String voiceConfId, String callerIdNum, String callerIdName);
void deskShareRTMPBroadcastStarted(String room, String streamname, Integer videoWidth, Integer videoHeight, String timestamp);
void deskShareRTMPBroadcastStopped(String room, String streamname, Integer videoWidth, Integer videoHeight, String timestamp);
} }

View File

@ -0,0 +1,39 @@
/**
* 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.freeswitch.voice.events;
public class DeskShareEndedEvent extends VoiceConferenceEvent {
private final String callerIdNum;
private final String callerIdName;
public DeskShareEndedEvent(String room, String callerIdNum, String callerIdName) {
super(room);
this.callerIdName = callerIdName;
this.callerIdNum = callerIdNum;
}
public String getCallerIdNum() {
return callerIdNum;
}
public String getCallerIdName() {
return callerIdName;
}
}

View File

@ -0,0 +1,68 @@
/**
* 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.freeswitch.voice.events;
public class DeskShareRTMPBroadcastEvent extends VoiceConferenceEvent {
private String timestamp;
private boolean broadcast;
private String streamUrl;
private Integer vw;
private Integer vh;
private final String DESKSHARE_SUFFIX = "-DESKSHARE";
public DeskShareRTMPBroadcastEvent(String room, boolean broadcast) {
super(room);
this.broadcast = broadcast;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
public void setBroadcastingStreamUrl(String streamUrl) {
this.streamUrl = streamUrl;
}
public void setVideoWidth(Integer vw) {this.vw = vw;}
public void setVideoHeight(Integer vh) {this.vh = vh;}
public Integer getVideoHeight() {return vh;}
public Integer getVideoWidth() {return vw;}
public String getTimestamp() {
return timestamp;
}
public String getBroadcastingStreamUrl()
{
if (streamUrl.endsWith(DESKSHARE_SUFFIX)) {
streamUrl = streamUrl.replace(DESKSHARE_SUFFIX, "");
}
return streamUrl;
}
public boolean getBroadcast() {
return broadcast;
}
}

View File

@ -0,0 +1,39 @@
/**
* 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.freeswitch.voice.events;
public class DeskShareStartedEvent extends VoiceConferenceEvent {
private final String callerIdNum;
private final String callerIdName;
public DeskShareStartedEvent(String room, String callerIdNum, String callerIdName) {
super(room);
this.callerIdName = callerIdName;
this.callerIdNum = callerIdNum;
}
public String getCallerIdNum() {
return callerIdNum;
}
public String getCallerIdName() {
return callerIdName;
}
}

View File

@ -27,10 +27,11 @@ public class VoiceUserJoinedEvent extends VoiceConferenceEvent {
private final Boolean speaking; private final Boolean speaking;
private final Boolean locked = false; private final Boolean locked = false;
private final String userId; private final String userId;
private final String avatarURL;
public VoiceUserJoinedEvent(String userId, String voiceUserId, String room, public VoiceUserJoinedEvent(String userId, String voiceUserId, String room,
String callerIdNum, String callerIdName, String callerIdNum, String callerIdName,
Boolean muted, Boolean speaking) { Boolean muted, Boolean speaking, String avatarURL) {
super(room); super(room);
this.userId = userId; this.userId = userId;
this.voiceUserId = voiceUserId; this.voiceUserId = voiceUserId;
@ -38,6 +39,7 @@ public class VoiceUserJoinedEvent extends VoiceConferenceEvent {
this.callerIdNum = callerIdNum; this.callerIdNum = callerIdNum;
this.muted = muted; this.muted = muted;
this.speaking = speaking; this.speaking = speaking;
this.avatarURL = avatarURL;
} }
public String getUserId() { public String getUserId() {
@ -67,4 +69,8 @@ public class VoiceUserJoinedEvent extends VoiceConferenceEvent {
public Boolean isLocked() { public Boolean isLocked() {
return locked; return locked;
} }
public String getAvatarURL() {
return avatarURL;
}
} }

View File

@ -22,7 +22,6 @@ import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.bigbluebutton.freeswitch.voice.events.ConferenceEventListener; import org.bigbluebutton.freeswitch.voice.events.ConferenceEventListener;
import org.bigbluebutton.freeswitch.voice.freeswitch.actions.BroadcastConferenceCommand; import org.bigbluebutton.freeswitch.voice.freeswitch.actions.BroadcastConferenceCommand;
import org.bigbluebutton.freeswitch.voice.freeswitch.actions.EjectAllUsersCommand; import org.bigbluebutton.freeswitch.voice.freeswitch.actions.EjectAllUsersCommand;
@ -31,6 +30,7 @@ import org.bigbluebutton.freeswitch.voice.freeswitch.actions.GetAllUsersCommand;
import org.bigbluebutton.freeswitch.voice.freeswitch.actions.MuteUserCommand; import org.bigbluebutton.freeswitch.voice.freeswitch.actions.MuteUserCommand;
import org.bigbluebutton.freeswitch.voice.freeswitch.actions.RecordConferenceCommand; import org.bigbluebutton.freeswitch.voice.freeswitch.actions.RecordConferenceCommand;
import org.bigbluebutton.freeswitch.voice.freeswitch.actions.TransferUsetToMeetingCommand; import org.bigbluebutton.freeswitch.voice.freeswitch.actions.TransferUsetToMeetingCommand;
import org.bigbluebutton.freeswitch.voice.freeswitch.actions.*;
import org.freeswitch.esl.client.inbound.Client; import org.freeswitch.esl.client.inbound.Client;
import org.freeswitch.esl.client.inbound.InboundConnectionFailure; import org.freeswitch.esl.client.inbound.InboundConnectionFailure;
import org.freeswitch.esl.client.manager.ManagerConnection; import org.freeswitch.esl.client.manager.ManagerConnection;
@ -157,4 +157,22 @@ public class ConnectionManager {
rcc.handleResponse(response, conferenceEventListener); rcc.handleResponse(response, conferenceEventListener);
} }
} }
public void broadcastRTMP(DeskShareBroadcastRTMPCommand rtmp) {
Client c = manager.getESLClient();
if (c.canSend()) {
System.out.println("ConnectionManager: send to FS: broadcastRTMP " + rtmp.getCommandArgs());
EslMessage response = c.sendSyncApiCommand(rtmp.getCommand(), rtmp.getCommandArgs());
rtmp.handleResponse(response, conferenceEventListener);
}
}
public void hangUp(DeskShareHangUpCommand huCmd) {
Client c = manager.getESLClient();
if (c.canSend()) {
System.out.println("ConnectionManager: send to FS: hangUp " + huCmd.getCommandArgs());
EslMessage response = c.sendSyncApiCommand(huCmd.getCommand(), huCmd.getCommandArgs());
huCmd.handleResponse(response, conferenceEventListener);
}
}
} }

View File

@ -7,6 +7,10 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.bigbluebutton.freeswitch.voice.events.ConferenceEventListener; import org.bigbluebutton.freeswitch.voice.events.ConferenceEventListener;
import org.bigbluebutton.freeswitch.voice.events.DeskShareEndedEvent;
import org.bigbluebutton.freeswitch.voice.events.DeskShareStartedEvent;
import org.bigbluebutton.freeswitch.voice.events.DeskShareRTMPBroadcastEvent;
import org.bigbluebutton.freeswitch.voice.events.VoiceConferenceEvent;
import org.bigbluebutton.freeswitch.voice.events.VoiceStartRecordingEvent; import org.bigbluebutton.freeswitch.voice.events.VoiceStartRecordingEvent;
import org.bigbluebutton.freeswitch.voice.events.VoiceUserJoinedEvent; import org.bigbluebutton.freeswitch.voice.events.VoiceUserJoinedEvent;
import org.bigbluebutton.freeswitch.voice.events.VoiceUserLeftEvent; import org.bigbluebutton.freeswitch.voice.events.VoiceUserLeftEvent;
@ -23,6 +27,10 @@ public class ESLEventListener implements IEslEventListener {
private static final String START_RECORDING_EVENT = "start-recording"; private static final String START_RECORDING_EVENT = "start-recording";
private static final String STOP_RECORDING_EVENT = "stop-recording"; private static final String STOP_RECORDING_EVENT = "stop-recording";
private static final String DESKSHARE_CONFERENCE_NAME_SUFFIX = "-DESKSHARE";
private static final String DESKSHARE_CALLER_NAME_SUFFIX = " (Screen)";
private static final String DESKSHARE_CALLER_ID_SUFFIX = " (screen)";
private final ConferenceEventListener conferenceEventListener; private final ConferenceEventListener conferenceEventListener;
public ESLEventListener(ConferenceEventListener conferenceEventListener) { public ESLEventListener(ConferenceEventListener conferenceEventListener) {
@ -68,13 +76,23 @@ public class ESLEventListener implements IEslEventListener {
return; return;
} }
// Deskstop sharing conferences have their name in the form ddddd-DESKSHARE
// Deskstop sharing conferences have the user with the desktop video displayed in this way:
// username (Screen) and usernum (screen)
if (confName.endsWith(DESKSHARE_CONFERENCE_NAME_SUFFIX) &&
callerId.endsWith(DESKSHARE_CALLER_ID_SUFFIX) &&
callerIdName.endsWith(DESKSHARE_CALLER_NAME_SUFFIX)) {
DeskShareStartedEvent dsStart = new DeskShareStartedEvent(confName, callerId, callerIdName);
conferenceEventListener.handleConferenceEvent(dsStart);
}
Matcher matcher = CALLERNAME_PATTERN.matcher(callerIdName); Matcher matcher = CALLERNAME_PATTERN.matcher(callerIdName);
if (matcher.matches()) { if (matcher.matches()) {
voiceUserId = matcher.group(1).trim(); voiceUserId = matcher.group(1).trim();
callerIdName = matcher.group(2).trim(); callerIdName = matcher.group(2).trim();
} }
VoiceUserJoinedEvent pj = new VoiceUserJoinedEvent(voiceUserId, memberId.toString(), confName, callerId, callerIdName, muted, speaking); VoiceUserJoinedEvent pj = new VoiceUserJoinedEvent(voiceUserId, memberId.toString(), confName, callerId, callerIdName, muted, speaking, "");
conferenceEventListener.handleConferenceEvent(pj); conferenceEventListener.handleConferenceEvent(pj);
} }
@ -82,6 +100,19 @@ public class ESLEventListener implements IEslEventListener {
public void conferenceEventLeave(String uniqueId, String confName, int confSize, EslEvent event) { public void conferenceEventLeave(String uniqueId, String confName, int confSize, EslEvent event) {
Integer memberId = this.getMemberIdFromEvent(event); Integer memberId = this.getMemberIdFromEvent(event);
System.out.println("User left voice conference, user=[" + memberId.toString() + "], conf=[" + confName + "]"); System.out.println("User left voice conference, user=[" + memberId.toString() + "], conf=[" + confName + "]");
String callerId = this.getCallerIdFromEvent(event);
String callerIdName = this.getCallerIdNameFromEvent(event);
// Deskstop sharing conferences have their name in the form ddddd-DESKSHARE
// Deskstop sharing conferences have the user with the desktop video displayed in this way:
// username (Screen) and usernum (screen)
if (confName.endsWith(DESKSHARE_CONFERENCE_NAME_SUFFIX) &&
callerId.endsWith(DESKSHARE_CALLER_ID_SUFFIX) &&
callerIdName.endsWith(DESKSHARE_CALLER_NAME_SUFFIX)) {
DeskShareEndedEvent dsEnd = new DeskShareEndedEvent(confName, callerId, callerIdName);
conferenceEventListener.handleConferenceEvent(dsEnd);
}
VoiceUserLeftEvent pl = new VoiceUserLeftEvent(memberId.toString(), confName); VoiceUserLeftEvent pl = new VoiceUserLeftEvent(memberId.toString(), confName);
conferenceEventListener.handleConferenceEvent(pl); conferenceEventListener.handleConferenceEvent(pl);
} }
@ -144,24 +175,52 @@ public class ESLEventListener implements IEslEventListener {
return; return;
} }
System.out.println("Handling conferenceEventRecord " + action);
if (action.equals(START_RECORDING_EVENT)) { if (action.equals(START_RECORDING_EVENT)) {
if (confName.endsWith(DESKSHARE_CONFERENCE_NAME_SUFFIX)){
if (isRTMPStream(event)) {
DeskShareRTMPBroadcastEvent rtmp = new DeskShareRTMPBroadcastEvent(confName, true);
rtmp.setBroadcastingStreamUrl(getStreamUrl(event));
rtmp.setVideoHeight(Integer.parseInt(getBroadcastParameter(event, "vh")));
rtmp.setVideoWidth(Integer.parseInt(getBroadcastParameter(event, "vw")));
rtmp.setTimestamp(genTimestamp().toString());
System.out.println("DeskShare conference broadcast started. url=["
+ getStreamUrl(event) + "], conf=[" + confName + "]");
conferenceEventListener.handleConferenceEvent(rtmp);
}
} else {
VoiceStartRecordingEvent sre = new VoiceStartRecordingEvent(confName, true); VoiceStartRecordingEvent sre = new VoiceStartRecordingEvent(confName, true);
sre.setRecordingFilename(getRecordFilenameFromEvent(event)); sre.setRecordingFilename(getRecordFilenameFromEvent(event));
sre.setTimestamp(genTimestamp().toString()); sre.setTimestamp(genTimestamp().toString());
System.out.println("Voice conference recording started. file=[" + getRecordFilenameFromEvent(event) + "], conf=[" + confName + "]"); System.out.println("Voice conference recording started. file=["
+ getRecordFilenameFromEvent(event) + "], conf=[" + confName + "]");
conferenceEventListener.handleConferenceEvent(sre); conferenceEventListener.handleConferenceEvent(sre);
}
} else if (action.equals(STOP_RECORDING_EVENT)) { } else if (action.equals(STOP_RECORDING_EVENT)) {
VoiceStartRecordingEvent srev = new VoiceStartRecordingEvent(confName, false); if (confName.endsWith(DESKSHARE_CONFERENCE_NAME_SUFFIX)){
srev.setRecordingFilename(getRecordFilenameFromEvent(event)); if (isRTMPStream(event)) {
srev.setTimestamp(genTimestamp().toString()); DeskShareRTMPBroadcastEvent rtmp = new DeskShareRTMPBroadcastEvent(confName, false);
rtmp.setBroadcastingStreamUrl(getStreamUrl(event));
rtmp.setVideoHeight(Integer.parseInt(getBroadcastParameter(event, "vh")));
rtmp.setVideoWidth(Integer.parseInt(getBroadcastParameter(event, "vw")));
rtmp.setTimestamp(genTimestamp().toString());
System.out.println("Voice conference recording stopped. file=[" + getRecordFilenameFromEvent(event) + "], conf=[" + confName + "]"); System.out.println("DeskShare conference broadcast stopped. url=["
conferenceEventListener.handleConferenceEvent(srev); + getStreamUrl(event) + "], conf=[" + confName + "]");
conferenceEventListener.handleConferenceEvent(rtmp);
}
} else { } else {
VoiceStartRecordingEvent sre = new VoiceStartRecordingEvent(confName, false);
sre.setRecordingFilename(getRecordFilenameFromEvent(event));
sre.setTimestamp(genTimestamp().toString());
System.out.println("Voice conference recording stopped. file=["
+ getRecordFilenameFromEvent(event) + "], conf=[" + confName + "]");
conferenceEventListener.handleConferenceEvent(sre);
}
}
else {
System.out.println("Processing UNKNOWN conference Action " + action + "]"); System.out.println("Processing UNKNOWN conference Action " + action + "]");
} }
} }
@ -195,4 +254,48 @@ public class ESLEventListener implements IEslEventListener {
private String getRecordFilenameFromEvent(EslEvent e) { private String getRecordFilenameFromEvent(EslEvent e) {
return e.getEventHeaders().get("Path"); return e.getEventHeaders().get("Path");
} }
// Distinguish between recording to a file:
// /path/to/a/file.mp4
// and broadcasting a stream:
// {channels=2,samplerate=48000,vw=1920,vh=1080,fps=15.00}rtmp://192.168.0.109/live/abc/dev-test
private Boolean isRTMPStream(EslEvent e) {
String path = e.getEventHeaders().get("Path");
if (path.contains("rtmp") && path.contains("channels")
&& path.contains("samplerate") && path.contains("vw")
&& path.contains("vh") && path.contains("fps")) {
return true;
} else {
return false;
}
}
// returns a String so that we can parse to an int or double depending on the param
private String getBroadcastParameter(EslEvent e, String param) {
String path = e.getEventHeaders().get("Path");
if (isRTMPStream(e)) {
String temp = path.substring(path.indexOf("{") + 1, path.indexOf("}"));
String[] arr = temp.split(",");
for (int i = 0; i < 5; i++) {
if (arr[i].startsWith(param)) {
return arr[i].substring(arr[i].indexOf('=') + 1);
}
}
return "0";
} else {
return "0";
}
}
// Obtain the rtmp url from the event (if any):
private String getStreamUrl(EslEvent e) {
String path = e.getEventHeaders().get("Path");
if (isRTMPStream(e)){
return path.substring(path.lastIndexOf("}") + 1);
} else {
return "";
}
}
} }

View File

@ -1,7 +1,7 @@
/** /**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ * BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
* *
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). * 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 * 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 * terms of the GNU Lesser General Public License as published by the Free Software
@ -24,7 +24,6 @@ import java.util.concurrent.Executor;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.bigbluebutton.freeswitch.voice.freeswitch.actions.BroadcastConferenceCommand; import org.bigbluebutton.freeswitch.voice.freeswitch.actions.BroadcastConferenceCommand;
import org.bigbluebutton.freeswitch.voice.freeswitch.actions.EjectAllUsersCommand; import org.bigbluebutton.freeswitch.voice.freeswitch.actions.EjectAllUsersCommand;
import org.bigbluebutton.freeswitch.voice.freeswitch.actions.EjectUserCommand; import org.bigbluebutton.freeswitch.voice.freeswitch.actions.EjectUserCommand;
@ -33,6 +32,7 @@ import org.bigbluebutton.freeswitch.voice.freeswitch.actions.GetAllUsersCommand;
import org.bigbluebutton.freeswitch.voice.freeswitch.actions.MuteUserCommand; import org.bigbluebutton.freeswitch.voice.freeswitch.actions.MuteUserCommand;
import org.bigbluebutton.freeswitch.voice.freeswitch.actions.RecordConferenceCommand; import org.bigbluebutton.freeswitch.voice.freeswitch.actions.RecordConferenceCommand;
import org.bigbluebutton.freeswitch.voice.freeswitch.actions.TransferUsetToMeetingCommand; import org.bigbluebutton.freeswitch.voice.freeswitch.actions.TransferUsetToMeetingCommand;
import org.bigbluebutton.freeswitch.voice.freeswitch.actions.*;
public class FreeswitchApplication { public class FreeswitchApplication {
@ -62,17 +62,6 @@ public class FreeswitchApplication {
} }
} }
public void getAllUsers(String voiceConfId) {
GetAllUsersCommand prc = new GetAllUsersCommand(voiceConfId, USER);
queueMessage(prc);
}
public void muteUser(String voiceConfId, String voiceUserId, Boolean mute) {
MuteUserCommand mpc = new MuteUserCommand(voiceConfId, voiceUserId,
mute, USER);
queueMessage(mpc);
}
public void transferUserToMeeting(String voiceConfId, public void transferUserToMeeting(String voiceConfId,
String targetVoiceConfId, String voiceUserId) { String targetVoiceConfId, String voiceUserId) {
TransferUsetToMeetingCommand tutmc = new TransferUsetToMeetingCommand( TransferUsetToMeetingCommand tutmc = new TransferUsetToMeetingCommand(
@ -80,82 +69,6 @@ public class FreeswitchApplication {
queueMessage(tutmc); queueMessage(tutmc);
} }
public void eject(String voiceConfId, String voiceUserId) {
EjectUserCommand mpc = new EjectUserCommand(voiceConfId, voiceUserId,
USER);
queueMessage(mpc);
}
public void ejectAll(String voiceConfId) {
EjectAllUsersCommand mpc = new EjectAllUsersCommand(voiceConfId, USER);
queueMessage(mpc);
}
private Long genTimestamp() {
return TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
}
public void startRecording(String voiceConfId, String meetingid) {
String RECORD_DIR = "/var/freeswitch/meetings";
String voicePath = RECORD_DIR + File.separatorChar + meetingid + "-"
+ genTimestamp() + ".wav";
RecordConferenceCommand rcc = new RecordConferenceCommand(voiceConfId,
USER, true, voicePath);
queueMessage(rcc);
}
public void stopRecording(String voiceConfId, String meetingid,
String voicePath) {
RecordConferenceCommand rcc = new RecordConferenceCommand(voiceConfId,
USER, false, voicePath);
queueMessage(rcc);
}
private void sendMessageToFreeswitch(final FreeswitchCommand command) {
Runnable task = new Runnable() {
public void run() {
if (command instanceof GetAllUsersCommand) {
GetAllUsersCommand cmd = (GetAllUsersCommand) command;
System.out
.println("Sending PopulateRoomCommand for conference = ["
+ cmd.getRoom() + "]");
manager.getUsers(cmd);
} else if (command instanceof MuteUserCommand) {
MuteUserCommand cmd = (MuteUserCommand) command;
System.out
.println("Sending MuteParticipantCommand for conference = ["
+ cmd.getRoom() + "]");
manager.mute(cmd);
} else if (command instanceof EjectUserCommand) {
EjectUserCommand cmd = (EjectUserCommand) command;
System.out
.println("Sending EjectParticipantCommand for conference = ["
+ cmd.getRoom() + "]");
manager.eject(cmd);
} else if (command instanceof EjectAllUsersCommand) {
EjectAllUsersCommand cmd = (EjectAllUsersCommand) command;
System.out
.println("Sending EjectAllUsersCommand for conference = ["
+ cmd.getRoom() + "]");
manager.ejectAll(cmd);
} else if (command instanceof TransferUsetToMeetingCommand) {
TransferUsetToMeetingCommand cmd = (TransferUsetToMeetingCommand) command;
System.out
.println("Sending TransferUsetToMeetingCommand for conference = ["
+ cmd.getRoom() + "]");
manager.tranfer(cmd);
} else if (command instanceof RecordConferenceCommand) {
manager.record((RecordConferenceCommand) command);
} else if (command instanceof BroadcastConferenceCommand) {
manager.broadcast((BroadcastConferenceCommand) command);
}
}
};
runExec.execute(task);
}
public void start() { public void start() {
sendMessages = true; sendMessages = true;
Runnable sender = new Runnable() { Runnable sender = new Runnable() {
@ -169,15 +82,94 @@ public class FreeswitchApplication {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
}; };
msgSenderExec.execute(sender); msgSenderExec.execute(sender);
} }
public void getAllUsers(String voiceConfId) {
GetAllUsersCommand prc = new GetAllUsersCommand(voiceConfId, USER);
queueMessage(prc);
}
public void muteUser(String voiceConfId, String voiceUserId, Boolean mute) {
MuteUserCommand mpc = new MuteUserCommand(voiceConfId, voiceUserId, mute, USER);
queueMessage(mpc);
}
public void eject(String voiceConfId, String voiceUserId) {
EjectUserCommand mpc = new EjectUserCommand(voiceConfId, voiceUserId, USER);
queueMessage(mpc);
}
public void ejectAll(String voiceConfId) {
EjectAllUsersCommand mpc = new EjectAllUsersCommand(voiceConfId, USER);
queueMessage(mpc);
}
private Long genTimestamp() {
return TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
}
public void startRecording(String voiceConfId, String meetingid){
String RECORD_DIR = "/var/freeswitch/meetings";
String voicePath = RECORD_DIR + File.separatorChar + meetingid + "-" + genTimestamp() + ".wav";
RecordConferenceCommand rcc = new RecordConferenceCommand(voiceConfId, USER, true, voicePath);
queueMessage(rcc);
}
public void stopRecording(String voiceConfId, String meetingid, String voicePath){
RecordConferenceCommand rcc = new RecordConferenceCommand(voiceConfId, USER, false, voicePath);
queueMessage(rcc);
}
public void deskShareBroadcastRTMP(String voiceConfId, String streamUrl, String timestamp, Boolean broadcast){
DeskShareBroadcastRTMPCommand rtmp = new DeskShareBroadcastRTMPCommand(voiceConfId, USER, streamUrl, timestamp, broadcast);
queueMessage(rtmp);
}
public void deskShareHangUp(String voiceConfId, String fsConferenceName, String timestamp){
DeskShareHangUpCommand huCmd = new DeskShareHangUpCommand(voiceConfId, fsConferenceName, USER, timestamp);
queueMessage(huCmd);
}
private void sendMessageToFreeswitch(final FreeswitchCommand command) {
Runnable task = new Runnable() {
public void run() {
if (command instanceof GetAllUsersCommand) {
GetAllUsersCommand cmd = (GetAllUsersCommand) command;
System.out.println("Sending PopulateRoomCommand for conference = [" + cmd.getRoom() + "]");
manager.getUsers(cmd);
} else if (command instanceof MuteUserCommand) {
MuteUserCommand cmd = (MuteUserCommand) command;
System.out.println("Sending MuteParticipantCommand for conference = [" + cmd.getRoom() + "]");
manager.mute(cmd);
} else if (command instanceof EjectUserCommand) {
EjectUserCommand cmd = (EjectUserCommand) command;
System.out.println("Sending EjectParticipantCommand for conference = [" + cmd.getRoom() + "]");
manager.eject(cmd);
} else if (command instanceof EjectAllUsersCommand) {
EjectAllUsersCommand cmd = (EjectAllUsersCommand) command;
System.out.println("Sending EjectAllUsersCommand for conference = [" + cmd.getRoom() + "]");
manager.ejectAll(cmd);
} else if (command instanceof RecordConferenceCommand) {
manager.record((RecordConferenceCommand) command);
} else if (command instanceof DeskShareBroadcastRTMPCommand) {
manager.broadcastRTMP((DeskShareBroadcastRTMPCommand)command);
} else if (command instanceof DeskShareHangUpCommand) {
DeskShareHangUpCommand cmd = (DeskShareHangUpCommand) command;
manager.hangUp(cmd);
} else if (command instanceof BroadcastConferenceCommand) {
manager.broadcast((BroadcastConferenceCommand) command);
}
}
};
runExec.execute(task);
}
public void stop() { public void stop() {
sendMessages = false; sendMessages = false;
} }
} }

View File

@ -0,0 +1,58 @@
/**
* 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.freeswitch.voice.freeswitch.actions;
import org.bigbluebutton.freeswitch.voice.events.ConferenceEventListener;
import org.freeswitch.esl.client.transport.message.EslMessage;
public class DeskShareBroadcastRTMPCommand extends FreeswitchCommand {
private String broadcastPath;
private boolean broadcast;
private String timestamp;
private final String DESKSHARE_SUFFIX = "-DESKSHARE";
public DeskShareBroadcastRTMPCommand(String room, String requesterId, String broadcastPath, String timestamp, boolean broadcast){
super(room, requesterId);
this.broadcastPath = broadcastPath;
this.broadcast = broadcast;
this.timestamp = timestamp;
}
@Override
public String getCommandArgs() {
String action = "norecord";
if (broadcast) {
action = "record";
}
String room = getRoom();
if (!room.endsWith(DESKSHARE_SUFFIX)) {
room = room + DESKSHARE_SUFFIX;
}
return SPACE + room + SPACE + action + SPACE + broadcastPath;
}
public void handleResponse(EslMessage response, ConferenceEventListener eventListener) {
//Test for Known Conference
System.out.println("\nDeskShareBroadcastRTMPCommand\n");
}
}

View File

@ -0,0 +1,35 @@
package org.bigbluebutton.freeswitch.voice.freeswitch.actions;
import org.bigbluebutton.freeswitch.voice.events.ConferenceEventListener;
import org.freeswitch.esl.client.transport.message.EslMessage;
/**
* Created by anton on 07/01/16.
*/
public class DeskShareHangUpCommand extends FreeswitchCommand {
private String timestamp;
private String fsConferenceName;
private final String DESKSHARE_SUFFIX = "-DESKSHARE";
public DeskShareHangUpCommand(String room, String fsConferenceName, String requesterId, String timestamp){
super(room, requesterId);
this.timestamp = timestamp;
this.fsConferenceName = fsConferenceName;
}
@Override
public String getCommandArgs() {
String action = "kick all";
if(!fsConferenceName.endsWith(DESKSHARE_SUFFIX)) {
fsConferenceName = fsConferenceName + DESKSHARE_SUFFIX;
}
return SPACE + fsConferenceName + SPACE + action;
}
public void handleResponse(EslMessage response, ConferenceEventListener eventListener) {
System.out.println("\nDeskShareHangUpCommand\n");
}
}

View File

@ -0,0 +1,50 @@
/**
* 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.freeswitch.voice.freeswitch.actions;
import org.bigbluebutton.freeswitch.voice.events.ConferenceEventListener;
import org.freeswitch.esl.client.transport.message.EslMessage;
public class DeskShareRecordCommand extends FreeswitchCommand {
private String recordPath;
private boolean record;
public DeskShareRecordCommand(String room, String requesterId, boolean record, String recordPath){
super(room, requesterId);
this.recordPath = recordPath;
this.record = record;
}
@Override
public String getCommandArgs() {
String action = "norecord";
if (record)
action = "record";
System.out.println("\n\n\n\n\n DESKSHARE RECORD " + record + "\n\n\n\n");
return SPACE + getRoom() + SPACE + action + SPACE + recordPath;
}
public void handleResponse(EslMessage response, ConferenceEventListener eventListener) {
//Test for Known Conference
System.out.println("\n\n\n\n\nLALALALLALA\n\n\n\n");
}
}

View File

@ -99,7 +99,7 @@ public class GetAllUsersCommand extends FreeswitchCommand {
} }
pj = new VoiceUserJoinedEvent(voiceUserId, member.getId().toString(), confXML.getConferenceRoom(), pj = new VoiceUserJoinedEvent(voiceUserId, member.getId().toString(), confXML.getConferenceRoom(),
callerId, callerIdName, member.getMuted(), member.getSpeaking()); callerId, callerIdName, member.getMuted(), member.getSpeaking(), null);
eventListener.handleConferenceEvent(pj); eventListener.handleConferenceEvent(pj);
} }

View File

@ -2,11 +2,20 @@ package org.bigbluebutton.freeswitch
import org.bigbluebutton.freeswitch.voice.IVoiceConferenceService import org.bigbluebutton.freeswitch.voice.IVoiceConferenceService
import org.bigbluebutton.endpoint.redis.RedisPublisher import org.bigbluebutton.endpoint.redis.RedisPublisher
import org.bigbluebutton.common.messages._ import org.bigbluebutton.common.messages.VoiceConfRecordingStartedMessage
import org.bigbluebutton.common.messages.UserJoinedVoiceConfMessage
import org.bigbluebutton.common.messages.UserLeftVoiceConfMessage
import org.bigbluebutton.common.messages.UserMutedInVoiceConfMessage
import org.bigbluebutton.common.messages.UserTalkingInVoiceConfMessage
import org.bigbluebutton.common.messages.DeskShareStartedEventMessage
import org.bigbluebutton.common.messages.DeskShareStoppedEventMessage
import org.bigbluebutton.common.messages.DeskShareRTMPBroadcastStartedEventMessage
import org.bigbluebutton.common.messages.DeskShareRTMPBroadcastStoppedEventMessage
class VoiceConferenceService(sender: RedisPublisher) extends IVoiceConferenceService { class VoiceConferenceService(sender: RedisPublisher) extends IVoiceConferenceService {
val FROM_VOICE_CONF_SYSTEM_CHAN = "bigbluebutton:from-voice-conf:system"; val FROM_VOICE_CONF_SYSTEM_CHAN = "bigbluebutton:from-voice-conf:system";
private final val DESKSHARE_CONFERENCE_NAME_SUFFIX = "-DESKSHARE"
def voiceConfRecordingStarted(voiceConfId: String, recordStream: String, recording: java.lang.Boolean, timestamp: String) { def voiceConfRecordingStarted(voiceConfId: String, recordStream: String, recording: java.lang.Boolean, timestamp: String) {
val msg = new VoiceConfRecordingStartedMessage(voiceConfId, recordStream, recording, timestamp) val msg = new VoiceConfRecordingStartedMessage(voiceConfId, recordStream, recording, timestamp)
@ -14,9 +23,9 @@ class VoiceConferenceService(sender: RedisPublisher) extends IVoiceConferenceSer
} }
def userJoinedVoiceConf(voiceConfId: String, voiceUserId: String, userId: String, callerIdName: String, def userJoinedVoiceConf(voiceConfId: String, voiceUserId: String, userId: String, callerIdName: String,
callerIdNum: String, muted: java.lang.Boolean, talking: java.lang.Boolean) { callerIdNum: String, muted: java.lang.Boolean, talking: java.lang.Boolean, avatarURL: String) {
// println("******** FreeswitchConferenceService received voiceUserJoined vui=[" + userId + "] wui=[" + webUserId + "]") // println("******** FreeswitchConferenceService received voiceUserJoined vui=[" + userId + "] wui=[" + webUserId + "]")
val msg = new UserJoinedVoiceConfMessage(voiceConfId, voiceUserId, userId, callerIdName, callerIdNum, muted, talking) val msg = new UserJoinedVoiceConfMessage(voiceConfId, voiceUserId, userId, callerIdName, callerIdNum, muted, talking, avatarURL)
sender.publish(FROM_VOICE_CONF_SYSTEM_CHAN, msg.toJson()) sender.publish(FROM_VOICE_CONF_SYSTEM_CHAN, msg.toJson())
} }
@ -41,4 +50,33 @@ class VoiceConferenceService(sender: RedisPublisher) extends IVoiceConferenceSer
val msg = new UserTalkingInVoiceConfMessage(voiceConfId, voiceUserId, talking) val msg = new UserTalkingInVoiceConfMessage(voiceConfId, voiceUserId, talking)
sender.publish(FROM_VOICE_CONF_SYSTEM_CHAN, msg.toJson()) sender.publish(FROM_VOICE_CONF_SYSTEM_CHAN, msg.toJson())
} }
def deskShareStarted(voiceConfId: String, callerIdNum: String, callerIdName: String) {
val trimmedVoiceConfId = voiceConfId.replace(DESKSHARE_CONFERENCE_NAME_SUFFIX, "")
println("******** FreeswitchConferenceService send deskShareStarted to BBB " + trimmedVoiceConfId)
val msg = new DeskShareStartedEventMessage(trimmedVoiceConfId, callerIdNum, callerIdName)
sender.publish(FROM_VOICE_CONF_SYSTEM_CHAN, msg.toJson())
}
def deskShareEnded(voiceConfId: String, callerIdNum: String, callerIdName: String) {
val trimmedVoiceConfId = voiceConfId.replace(DESKSHARE_CONFERENCE_NAME_SUFFIX, "")
println("******** FreeswitchConferenceService send deskShareStopped to BBB " + trimmedVoiceConfId)
val msg = new DeskShareStoppedEventMessage(trimmedVoiceConfId, callerIdNum, callerIdName)
sender.publish(FROM_VOICE_CONF_SYSTEM_CHAN, msg.toJson())
}
def deskShareRTMPBroadcastStarted(voiceConfId: String, streamname: String, vw: java.lang.Integer, vh: java.lang.Integer, timestamp: String) {
val trimmedVoiceConfId = voiceConfId.replace(DESKSHARE_CONFERENCE_NAME_SUFFIX, "")
println("******** FreeswitchConferenceService send deskShareRTMPBroadcastStarted to BBB " + trimmedVoiceConfId)
val msg = new DeskShareRTMPBroadcastStartedEventMessage(trimmedVoiceConfId, streamname, vw, vh, timestamp)
sender.publish(FROM_VOICE_CONF_SYSTEM_CHAN, msg.toJson())
}
def deskShareRTMPBroadcastStopped(voiceConfId: String, streamname: String, vw: java.lang.Integer, vh: java.lang.Integer, timestamp: String) {
val trimmedVoiceConfId = voiceConfId.replace(DESKSHARE_CONFERENCE_NAME_SUFFIX, "")
println("******** FreeswitchConferenceService send deskShareRTMPBroadcastStopped to BBB " + trimmedVoiceConfId)
val msg = new DeskShareRTMPBroadcastStoppedEventMessage(trimmedVoiceConfId, streamname, vw, vh, timestamp)
sender.publish(FROM_VOICE_CONF_SYSTEM_CHAN, msg.toJson())
}
} }

View File

@ -98,7 +98,7 @@ if (request.getParameterMap().isEmpty()) {
String ip = BigBlueButtonURL.split("\\/bigbluebutton")[0]; String ip = BigBlueButtonURL.split("\\/bigbluebutton")[0];
// redirect towards the html5 client which is waiting for the following parameters // redirect towards the html5 client which is waiting for the following parameters
String html5url = ip + "/html5client/" + meetingId + "/" + userId + "/" + authToken; String html5url = ip + "/html5client/join/" + meetingId + "/" + userId + "/" + authToken;
if (joinURL.startsWith("http://") || joinURL.startsWith("https://")) { if (joinURL.startsWith("http://") || joinURL.startsWith("https://")) {
%> %>

File diff suppressed because it is too large Load Diff

View File

@ -1,137 +0,0 @@
format version: 5
output mode:
1 items
0 -> multiple
output directories:
2 items
D:\bbb\bbb-common-message\src\test\java -> D:\bbb\bbb-common-message\target\test-classes
D:\bbb\bbb-common-message\src\test\scala -> D:\bbb\bbb-common-message\target\test-classes
compile options:
8 items
0 -> -javabootclasspath
1 -> C:\Program Files\Java\jdk1.7.0_80\jre\lib\resources.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\rt.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\jce.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\zipfs.jar
2 -> -javaextdirs
3 ->
4 -> -bootclasspath
5 -> D:\Ghazi\Softs\eclipse-scala\plugins\org.scala-lang.scala-library_2.11.7.v20150622-112736-1fbce4612c.jar
6 -> -encoding
7 -> UTF-8
javac options:
0 items
compiler version:
1 items
0 -> 2.11.7
compile order:
1 items
0 -> Mixed
name hashing:
1 items
0 -> false
products:
1 items
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\common\messages\StartCustomPollRequestMessageTest.java -> D:\bbb\bbb-common-message\target\test-classes\org\bigbluebutton\common\messages\StartCustomPollRequestMessageTest.class
binary dependencies:
3 items
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\common\messages\StartCustomPollRequestMessageTest.java -> C:\Program Files\Java\jre1.8.0_74\lib\rt.jar
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\common\messages\StartCustomPollRequestMessageTest.java -> D:\bbb\bbb-common-message\lib_managed\jars\com.google.code.gson\gson\gson-1.7.1.jar
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\common\messages\StartCustomPollRequestMessageTest.java -> D:\bbb\bbb-common-message\lib_managed\jars\junit\junit\junit-4.11.jar
direct source dependencies:
1 items
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\common\messages\StartCustomPollRequestMessageTest.java -> D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\common\messages\StartCustomPollRequestMessageTest.java
direct external dependencies:
3 items
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\common\messages\StartCustomPollRequestMessageTest.java -> org.bigbluebutton.common.messages.MessageHeader
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\common\messages\StartCustomPollRequestMessageTest.java -> org.bigbluebutton.common.messages.StartCustomPollRequestMessage
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\common\messages\StartCustomPollRequestMessageTest.java -> org.bigbluebutton.common.messages.payload.StartCustomPollRequestMessagePayload
public inherited source dependencies:
0 items
public inherited external dependencies:
0 items
member reference internal dependencies:
0 items
member reference external dependencies:
0 items
inheritance internal dependencies:
0 items
inheritance external dependencies:
0 items
class names:
1 items
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\common\messages\StartCustomPollRequestMessageTest.java -> org.bigbluebutton.common.messages.StartCustomPollRequestMessageTest
used names:
0 items
product stamps:
1 items
D:\bbb\bbb-common-message\target\test-classes\org\bigbluebutton\common\messages\StartCustomPollRequestMessageTest.class -> lastModified(1458139331787)
source stamps:
8 items
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\common\messages\StartCustomPollRequestMessageTest.java -> hash(30de8c7c976e4a9ec060fb37ccdd975eb08acd4e)
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\messages\BreakoutRoomsListTest.java -> hash(7277621ead94ec31af85b4e688a6838622f917d7)
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\messages\CreateBreakoutRoomRequestTest.java -> hash(00d1388f6ba3942b96bf718705c58e8749884ba0)
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\messages\CreateBreakoutRoomsRequestTest.java -> hash(613e4f0b3da37a9d4e3524b7042b4ad7bc43ff3f)
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\messages\CreateMeetingRequestTest.java -> hash(0b173a7414b06d0d2f58300ba0fc782ffd5eec50)
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\messages\ValidateAuthTokenReplyTest.java -> hash(a83d0096f4a9119943f5e47ae0140c361964bea8)
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\messages\ValidateAuthTokenRequestTest.java -> hash(dee673384778e690d38b75e4da0740163a5e4ac1)
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\messages\ValidateAuthTokenRequestTimedoutTest.java -> hash(a87da3d1d11948c7863797a73684154372fb3d5e)
binary stamps:
3 items
C:\Program Files\Java\jre1.8.0_74\lib\rt.jar -> lastModified(1455481607050)
D:\bbb\bbb-common-message\lib_managed\jars\com.google.code.gson\gson\gson-1.7.1.jar -> lastModified(1440005808493)
D:\bbb\bbb-common-message\lib_managed\jars\junit\junit\junit-4.11.jar -> lastModified(1440005808536)
class names:
3 items
C:\Program Files\Java\jre1.8.0_74\lib\rt.jar -> java.lang.Object
D:\bbb\bbb-common-message\lib_managed\jars\com.google.code.gson\gson\gson-1.7.1.jar -> com.google.gson.Gson
D:\bbb\bbb-common-message\lib_managed\jars\junit\junit\junit-4.11.jar -> org.junit.Assert
internal apis:
8 items
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\common\messages\StartCustomPollRequestMessageTest.java ->
rO0ABXNyABB4c2J0aS5hcGkuU291cmNlFlpwRASfbtoCAAZJAAdhcGlIYXNoWgAIaGFzTWFjcm9MABhfaW50ZXJuYWxPbmx5X25hbWVIYXNoZXN0ACRMeHNidGkvYXBpL19pbnRlcm5hbE9ubHlfTmFtZUhhc2hlcztMAANhcGl0ABVMeHNidGkvYXBpL1NvdXJjZUFQSTtMAAtjb21waWxhdGlvbnQAF0x4c2J0aS9hcGkvQ29tcGlsYXRpb247WwAEaGFzaHQAAltCeHA0b5kCAHNyACJ4c2J0aS5hcGkuX2ludGVybmFsT25seV9OYW1lSGFzaGVzVNq+mfrU7EwCAAJbAA9pbXBsaWNpdE1lbWJlcnN0ACNbTHhzYnRpL2FwaS9faW50ZXJuYWxPbmx5X05hbWVIYXNoO1sADnJlZ3VsYXJNZW1iZXJzcQB+AAd4cHVyACNbTHhzYnRpLmFwaS5faW50ZXJuYWxPbmx5X05hbWVIYXNoO0lagLbdlov0AgAAeHAAAAAAdXEAfgAJAAAAAHNyABN4c2J0aS5hcGkuU291cmNlQVBJuV6n+SkjOKQCAAJbAAtkZWZpbml0aW9uc3QAF1tMeHNidGkvYXBpL0RlZmluaXRpb247WwAIcGFja2FnZXN0ABRbTHhzYnRpL2FwaS9QYWNrYWdlO3hwdXIAF1tMeHNidGkuYXBpLkRlZmluaXRpb247iMlc57TjXg4CAAB4cAAAAAJzcgATeHNidGkuYXBpLkNsYXNzTGlrZYM0HKHfsJdsAgAETAAOZGVmaW5pdGlvblR5cGV0ABpMeHNidGkvYXBpL0RlZmluaXRpb25UeXBlO1sAEHNhdmVkQW5ub3RhdGlvbnN0ABNbTGphdmEvbGFuZy9TdHJpbmc7TAAIc2VsZlR5cGV0ABBMeHNidGkvYXBpL0xhenk7TAAJc3RydWN0dXJlcQB+ABV4cgAheHNidGkuYXBpLlBhcmFtZXRlcml6ZWREZWZpbml0aW9u+RFusdVQPOICAAFbAA50eXBlUGFyYW1ldGVyc3QAGltMeHNidGkvYXBpL1R5cGVQYXJhbWV0ZXI7eHIAFHhzYnRpLmFwaS5EZWZpbml0aW9uhyob6HFC40YCAARMAAZhY2Nlc3N0ABJMeHNidGkvYXBpL0FjY2VzcztbAAthbm5vdGF0aW9uc3QAF1tMeHNidGkvYXBpL0Fubm90YXRpb247TAAJbW9kaWZpZXJzdAAVTHhzYnRpL2FwaS9Nb2RpZmllcnM7TAAEbmFtZXQAEkxqYXZhL2xhbmcvU3RyaW5nO3hwc3IAEHhzYnRpLmFwaS5QdWJsaWO6WD2ubC1gQgIAAHhyABB4c2J0aS5hcGkuQWNjZXNz3WKa+B1jMUgCAAB4cHVyABdbTHhzYnRpLmFwaS5Bbm5vdGF0aW9uO+uX6xkQ9o1IAgAAeHAAAAAAc3IAE3hzYnRpLmFwaS5Nb2RpZmllcnPHERMhaZzcJAIAAUIABWZsYWdzeHAAdABDb3JnLmJpZ2JsdWVidXR0b24uY29tbW9uLm1lc3NhZ2VzLlN0YXJ0Q3VzdG9tUG9sbFJlcXVlc3RNZXNzYWdlVGVzdHVyABpbTHhzYnRpLmFwaS5UeXBlUGFyYW1ldGVyO9ltJg8onfK2AgAAeHAAAAAAfnIAGHhzYnRpLmFwaS5EZWZpbml0aW9uVHlwZQAAAAAAAAAAEgAAeHIADmphdmEubGFuZy5FbnVtAAAAAAAAAAASAAB4cHQACENsYXNzRGVmdXIAE1tMamF2YS5sYW5nLlN0cmluZzut0lbn6R17RwIAAHhwAAAAAnQADm9yZy5qdW5pdC5UZXN0dAAMc2NhbGEudGhyb3dzc3IAE3hzYnRpLlNhZmVMYXp5JEltcGw7kU8R9EVMyQIAA1oACGJpdG1hcCQwTAACX3R0ABJMamF2YS9sYW5nL09iamVjdDtMAARldmFsdAARTHNjYWxhL0Z1bmN0aW9uMDt4cgAWeHNidGkuYXBpLkFic3RyYWN0TGF6edN3tQFfu+egAgAAeHABc3IAE3hzYnRpLmFwaS5FbXB0eVR5cGW8/Z5GSTuJJAIAAHhyABR4c2J0aS5hcGkuU2ltcGxlVHlwZXJ4YoghI79AAgAAeHIADnhzYnRpLmFwaS5UeXBlP2rZIRZJqsoCAAB4cHBzcQB+ADABc3IAE3hzYnRpLmFwaS5TdHJ1Y3R1cmWpqvmAk2/YAAIAA0wACGRlY2xhcmVkcQB+ABVMAAlpbmhlcml0ZWRxAH4AFUwAB3BhcmVudHNxAH4AFXhxAH4AN3NxAH4AMAF1cQB+ABAAAAAAcHNxAH4AMAF1cQB+ABAAAAAAcHNxAH4AMAF1cgARW0x4c2J0aS5hcGkuVHlwZTt0/6Vae/npQQIAAHhwAAAAAXNyABR4c2J0aS5hcGkuUHJvamVjdGlvbvPSjVTpRaQtAgACTAACaWRxAH4AHEwABnByZWZpeHQAFkx4c2J0aS9hcGkvU2ltcGxlVHlwZTt4cQB+ADZ0AAZPYmplY3RzcgATeHNidGkuYXBpLlNpbmdsZXRvbvynX/jPVuRGAgABTAAEcGF0aHQAEEx4c2J0aS9hcGkvUGF0aDt4cQB+ADZzcgAOeHNidGkuYXBpLlBhdGibPVwIzqUnhAIAAVsACmNvbXBvbmVudHN0ABpbTHhzYnRpL2FwaS9QYXRoQ29tcG9uZW50O3hwdXIAGltMeHNidGkuYXBpLlBhdGhDb21wb25lbnQ7Q9oJdC1nFnQCAAB4cAAAAANzcgAMeHNidGkuYXBpLklkmDJsizdTxEACAAFMAAJpZHEAfgAceHIAF3hzYnRpLmFwaS5QYXRoQ29tcG9uZW50X5oiWy6Gn7wCAAB4cHQABGphdmFzcQB+AE90AARsYW5nc3IADnhzYnRpLmFwaS5UaGlz2wntpsxaQFwCAAB4cQB+AFBwcHNxAH4AEnEAfgAgcQB+ACJxAH4AJHEAfgAlcQB+ACd+cQB+ACh0AAZNb2R1bGV1cQB+ACwAAAAAc3EAfgAwAXEAfgA4cHNxAH4AMAFzcQB+ADpzcQB+ADABdXEAfgAQAAAAAHBzcQB+ADABdXEAfgAQAAAAAHBzcQB+ADABdXEAfgBBAAAAAHBwdXIAFFtMeHNidGkuYXBpLlBhY2thZ2U7WxMZN3CnJ6ECAAB4cAAAAAFzcgAReHNidGkuYXBpLlBhY2thZ2V+WY/2rs45WAIAAUwABG5hbWVxAH4AHHhwdAAhb3JnLmJpZ2JsdWVidXR0b24uY29tbW9uLm1lc3NhZ2Vzc3IAFXhzYnRpLmFwaS5Db21waWxhdGlvbu364MNq6KBCAgACSgAJc3RhcnRUaW1lWwAHb3V0cHV0c3QAGltMeHNidGkvYXBpL091dHB1dFNldHRpbmc7eHAAAAFTf+B7nXVyABpbTHhzYnRpLmFwaS5PdXRwdXRTZXR0aW5nO39qwvOnh6VCAgAAeHAAAAACc3IAF3hzYnRpLmFwaS5PdXRwdXRTZXR0aW5netmaR3T7HXsCAAJMAA9vdXRwdXREaXJlY3RvcnlxAH4AHEwAD3NvdXJjZURpcmVjdG9yeXEAfgAceHB0AC1EOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHRhcmdldFx0ZXN0LWNsYXNzZXN0AChEOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHNyY1x0ZXN0XHNjYWxhc3EAfgBudAAtRDpcYmJiXGJiYi1jb21tb24tbWVzc2FnZVx0YXJnZXRcdGVzdC1jbGFzc2VzdAAnRDpcYmJiXGJiYi1jb21tb24tbWVzc2FnZVxzcmNcdGVzdFxqYXZhdXIAAltCrPMX+AYIVOACAAB4cAAAABQw3ox8l25KnsBg+zfM3ZdesIrNTg==
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\messages\BreakoutRoomsListTest.java ->
rO0ABXNyABB4c2J0aS5hcGkuU291cmNlFlpwRASfbtoCAAZJAAdhcGlIYXNoWgAIaGFzTWFjcm9MABhfaW50ZXJuYWxPbmx5X25hbWVIYXNoZXN0ACRMeHNidGkvYXBpL19pbnRlcm5hbE9ubHlfTmFtZUhhc2hlcztMAANhcGl0ABVMeHNidGkvYXBpL1NvdXJjZUFQSTtMAAtjb21waWxhdGlvbnQAF0x4c2J0aS9hcGkvQ29tcGlsYXRpb247WwAEaGFzaHQAAltCeHC4IVHqAHNyACJ4c2J0aS5hcGkuX2ludGVybmFsT25seV9OYW1lSGFzaGVzVNq+mfrU7EwCAAJbAA9pbXBsaWNpdE1lbWJlcnN0ACNbTHhzYnRpL2FwaS9faW50ZXJuYWxPbmx5X05hbWVIYXNoO1sADnJlZ3VsYXJNZW1iZXJzcQB+AAd4cHVyACNbTHhzYnRpLmFwaS5faW50ZXJuYWxPbmx5X05hbWVIYXNoO0lagLbdlov0AgAAeHAAAAAAdXEAfgAJAAAAAHNyABN4c2J0aS5hcGkuU291cmNlQVBJuV6n+SkjOKQCAAJbAAtkZWZpbml0aW9uc3QAF1tMeHNidGkvYXBpL0RlZmluaXRpb247WwAIcGFja2FnZXN0ABRbTHhzYnRpL2FwaS9QYWNrYWdlO3hwdXIAF1tMeHNidGkuYXBpLkRlZmluaXRpb247iMlc57TjXg4CAAB4cAAAAAB1cgAUW0x4c2J0aS5hcGkuUGFja2FnZTtbExk3cKcnoQIAAHhwAAAAAHNyABV4c2J0aS5hcGkuQ29tcGlsYXRpb27t+uDDauigQgIAAkoACXN0YXJ0VGltZVsAB291dHB1dHN0ABpbTHhzYnRpL2FwaS9PdXRwdXRTZXR0aW5nO3hwAAABU3/ge511cgAaW0x4c2J0aS5hcGkuT3V0cHV0U2V0dGluZzt/asLzp4elQgIAAHhwAAAAAnNyABd4c2J0aS5hcGkuT3V0cHV0U2V0dGluZ3rZmkd0+x17AgACTAAPb3V0cHV0RGlyZWN0b3J5dAASTGphdmEvbGFuZy9TdHJpbmc7TAAPc291cmNlRGlyZWN0b3J5cQB+ABp4cHQALUQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2VcdGFyZ2V0XHRlc3QtY2xhc3Nlc3QAKEQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2Vcc3JjXHRlc3Rcc2NhbGFzcQB+ABl0AC1EOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHRhcmdldFx0ZXN0LWNsYXNzZXN0ACdEOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHNyY1x0ZXN0XGphdmF1cgACW0Ks8xf4BghU4AIAAHhwAAAAFHJ3Yh6tlOwxr4W05oimg4Yi+RfX
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\messages\CreateBreakoutRoomRequestTest.java ->
rO0ABXNyABB4c2J0aS5hcGkuU291cmNlFlpwRASfbtoCAAZJAAdhcGlIYXNoWgAIaGFzTWFjcm9MABhfaW50ZXJuYWxPbmx5X25hbWVIYXNoZXN0ACRMeHNidGkvYXBpL19pbnRlcm5hbE9ubHlfTmFtZUhhc2hlcztMAANhcGl0ABVMeHNidGkvYXBpL1NvdXJjZUFQSTtMAAtjb21waWxhdGlvbnQAF0x4c2J0aS9hcGkvQ29tcGlsYXRpb247WwAEaGFzaHQAAltCeHC4IVHqAHNyACJ4c2J0aS5hcGkuX2ludGVybmFsT25seV9OYW1lSGFzaGVzVNq+mfrU7EwCAAJbAA9pbXBsaWNpdE1lbWJlcnN0ACNbTHhzYnRpL2FwaS9faW50ZXJuYWxPbmx5X05hbWVIYXNoO1sADnJlZ3VsYXJNZW1iZXJzcQB+AAd4cHVyACNbTHhzYnRpLmFwaS5faW50ZXJuYWxPbmx5X05hbWVIYXNoO0lagLbdlov0AgAAeHAAAAAAdXEAfgAJAAAAAHNyABN4c2J0aS5hcGkuU291cmNlQVBJuV6n+SkjOKQCAAJbAAtkZWZpbml0aW9uc3QAF1tMeHNidGkvYXBpL0RlZmluaXRpb247WwAIcGFja2FnZXN0ABRbTHhzYnRpL2FwaS9QYWNrYWdlO3hwdXIAF1tMeHNidGkuYXBpLkRlZmluaXRpb247iMlc57TjXg4CAAB4cAAAAAB1cgAUW0x4c2J0aS5hcGkuUGFja2FnZTtbExk3cKcnoQIAAHhwAAAAAHNyABV4c2J0aS5hcGkuQ29tcGlsYXRpb27t+uDDauigQgIAAkoACXN0YXJ0VGltZVsAB291dHB1dHN0ABpbTHhzYnRpL2FwaS9PdXRwdXRTZXR0aW5nO3hwAAABU3/ge511cgAaW0x4c2J0aS5hcGkuT3V0cHV0U2V0dGluZzt/asLzp4elQgIAAHhwAAAAAnNyABd4c2J0aS5hcGkuT3V0cHV0U2V0dGluZ3rZmkd0+x17AgACTAAPb3V0cHV0RGlyZWN0b3J5dAASTGphdmEvbGFuZy9TdHJpbmc7TAAPc291cmNlRGlyZWN0b3J5cQB+ABp4cHQALUQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2VcdGFyZ2V0XHRlc3QtY2xhc3Nlc3QAKEQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2Vcc3JjXHRlc3Rcc2NhbGFzcQB+ABl0AC1EOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHRhcmdldFx0ZXN0LWNsYXNzZXN0ACdEOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHNyY1x0ZXN0XGphdmF1cgACW0Ks8xf4BghU4AIAAHhwAAAAFADROI9ro5Qrlr9xhwXFjodJiEug
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\messages\CreateBreakoutRoomsRequestTest.java ->
rO0ABXNyABB4c2J0aS5hcGkuU291cmNlFlpwRASfbtoCAAZJAAdhcGlIYXNoWgAIaGFzTWFjcm9MABhfaW50ZXJuYWxPbmx5X25hbWVIYXNoZXN0ACRMeHNidGkvYXBpL19pbnRlcm5hbE9ubHlfTmFtZUhhc2hlcztMAANhcGl0ABVMeHNidGkvYXBpL1NvdXJjZUFQSTtMAAtjb21waWxhdGlvbnQAF0x4c2J0aS9hcGkvQ29tcGlsYXRpb247WwAEaGFzaHQAAltCeHC4IVHqAHNyACJ4c2J0aS5hcGkuX2ludGVybmFsT25seV9OYW1lSGFzaGVzVNq+mfrU7EwCAAJbAA9pbXBsaWNpdE1lbWJlcnN0ACNbTHhzYnRpL2FwaS9faW50ZXJuYWxPbmx5X05hbWVIYXNoO1sADnJlZ3VsYXJNZW1iZXJzcQB+AAd4cHVyACNbTHhzYnRpLmFwaS5faW50ZXJuYWxPbmx5X05hbWVIYXNoO0lagLbdlov0AgAAeHAAAAAAdXEAfgAJAAAAAHNyABN4c2J0aS5hcGkuU291cmNlQVBJuV6n+SkjOKQCAAJbAAtkZWZpbml0aW9uc3QAF1tMeHNidGkvYXBpL0RlZmluaXRpb247WwAIcGFja2FnZXN0ABRbTHhzYnRpL2FwaS9QYWNrYWdlO3hwdXIAF1tMeHNidGkuYXBpLkRlZmluaXRpb247iMlc57TjXg4CAAB4cAAAAAB1cgAUW0x4c2J0aS5hcGkuUGFja2FnZTtbExk3cKcnoQIAAHhwAAAAAHNyABV4c2J0aS5hcGkuQ29tcGlsYXRpb27t+uDDauigQgIAAkoACXN0YXJ0VGltZVsAB291dHB1dHN0ABpbTHhzYnRpL2FwaS9PdXRwdXRTZXR0aW5nO3hwAAABU3/ge511cgAaW0x4c2J0aS5hcGkuT3V0cHV0U2V0dGluZzt/asLzp4elQgIAAHhwAAAAAnNyABd4c2J0aS5hcGkuT3V0cHV0U2V0dGluZ3rZmkd0+x17AgACTAAPb3V0cHV0RGlyZWN0b3J5dAASTGphdmEvbGFuZy9TdHJpbmc7TAAPc291cmNlRGlyZWN0b3J5cQB+ABp4cHQALUQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2VcdGFyZ2V0XHRlc3QtY2xhc3Nlc3QAKEQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2Vcc3JjXHRlc3Rcc2NhbGFzcQB+ABl0AC1EOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHRhcmdldFx0ZXN0LWNsYXNzZXN0ACdEOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHNyY1x0ZXN0XGphdmF1cgACW0Ks8xf4BghU4AIAAHhwAAAAFGE+Tws9o3qdTjUktwQrSte8Q/8/
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\messages\CreateMeetingRequestTest.java ->
rO0ABXNyABB4c2J0aS5hcGkuU291cmNlFlpwRASfbtoCAAZJAAdhcGlIYXNoWgAIaGFzTWFjcm9MABhfaW50ZXJuYWxPbmx5X25hbWVIYXNoZXN0ACRMeHNidGkvYXBpL19pbnRlcm5hbE9ubHlfTmFtZUhhc2hlcztMAANhcGl0ABVMeHNidGkvYXBpL1NvdXJjZUFQSTtMAAtjb21waWxhdGlvbnQAF0x4c2J0aS9hcGkvQ29tcGlsYXRpb247WwAEaGFzaHQAAltCeHC4IVHqAHNyACJ4c2J0aS5hcGkuX2ludGVybmFsT25seV9OYW1lSGFzaGVzVNq+mfrU7EwCAAJbAA9pbXBsaWNpdE1lbWJlcnN0ACNbTHhzYnRpL2FwaS9faW50ZXJuYWxPbmx5X05hbWVIYXNoO1sADnJlZ3VsYXJNZW1iZXJzcQB+AAd4cHVyACNbTHhzYnRpLmFwaS5faW50ZXJuYWxPbmx5X05hbWVIYXNoO0lagLbdlov0AgAAeHAAAAAAdXEAfgAJAAAAAHNyABN4c2J0aS5hcGkuU291cmNlQVBJuV6n+SkjOKQCAAJbAAtkZWZpbml0aW9uc3QAF1tMeHNidGkvYXBpL0RlZmluaXRpb247WwAIcGFja2FnZXN0ABRbTHhzYnRpL2FwaS9QYWNrYWdlO3hwdXIAF1tMeHNidGkuYXBpLkRlZmluaXRpb247iMlc57TjXg4CAAB4cAAAAAB1cgAUW0x4c2J0aS5hcGkuUGFja2FnZTtbExk3cKcnoQIAAHhwAAAAAHNyABV4c2J0aS5hcGkuQ29tcGlsYXRpb27t+uDDauigQgIAAkoACXN0YXJ0VGltZVsAB291dHB1dHN0ABpbTHhzYnRpL2FwaS9PdXRwdXRTZXR0aW5nO3hwAAABU3/ge511cgAaW0x4c2J0aS5hcGkuT3V0cHV0U2V0dGluZzt/asLzp4elQgIAAHhwAAAAAnNyABd4c2J0aS5hcGkuT3V0cHV0U2V0dGluZ3rZmkd0+x17AgACTAAPb3V0cHV0RGlyZWN0b3J5dAASTGphdmEvbGFuZy9TdHJpbmc7TAAPc291cmNlRGlyZWN0b3J5cQB+ABp4cHQALUQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2VcdGFyZ2V0XHRlc3QtY2xhc3Nlc3QAKEQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2Vcc3JjXHRlc3Rcc2NhbGFzcQB+ABl0AC1EOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHRhcmdldFx0ZXN0LWNsYXNzZXN0ACdEOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHNyY1x0ZXN0XGphdmF1cgACW0Ks8xf4BghU4AIAAHhwAAAAFAsXOnQUsG0NL1gwC6D8eC/9XuxQ
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\messages\ValidateAuthTokenReplyTest.java ->
rO0ABXNyABB4c2J0aS5hcGkuU291cmNlFlpwRASfbtoCAAZJAAdhcGlIYXNoWgAIaGFzTWFjcm9MABhfaW50ZXJuYWxPbmx5X25hbWVIYXNoZXN0ACRMeHNidGkvYXBpL19pbnRlcm5hbE9ubHlfTmFtZUhhc2hlcztMAANhcGl0ABVMeHNidGkvYXBpL1NvdXJjZUFQSTtMAAtjb21waWxhdGlvbnQAF0x4c2J0aS9hcGkvQ29tcGlsYXRpb247WwAEaGFzaHQAAltCeHC4IVHqAHNyACJ4c2J0aS5hcGkuX2ludGVybmFsT25seV9OYW1lSGFzaGVzVNq+mfrU7EwCAAJbAA9pbXBsaWNpdE1lbWJlcnN0ACNbTHhzYnRpL2FwaS9faW50ZXJuYWxPbmx5X05hbWVIYXNoO1sADnJlZ3VsYXJNZW1iZXJzcQB+AAd4cHVyACNbTHhzYnRpLmFwaS5faW50ZXJuYWxPbmx5X05hbWVIYXNoO0lagLbdlov0AgAAeHAAAAAAdXEAfgAJAAAAAHNyABN4c2J0aS5hcGkuU291cmNlQVBJuV6n+SkjOKQCAAJbAAtkZWZpbml0aW9uc3QAF1tMeHNidGkvYXBpL0RlZmluaXRpb247WwAIcGFja2FnZXN0ABRbTHhzYnRpL2FwaS9QYWNrYWdlO3hwdXIAF1tMeHNidGkuYXBpLkRlZmluaXRpb247iMlc57TjXg4CAAB4cAAAAAB1cgAUW0x4c2J0aS5hcGkuUGFja2FnZTtbExk3cKcnoQIAAHhwAAAAAHNyABV4c2J0aS5hcGkuQ29tcGlsYXRpb27t+uDDauigQgIAAkoACXN0YXJ0VGltZVsAB291dHB1dHN0ABpbTHhzYnRpL2FwaS9PdXRwdXRTZXR0aW5nO3hwAAABU3/ge511cgAaW0x4c2J0aS5hcGkuT3V0cHV0U2V0dGluZzt/asLzp4elQgIAAHhwAAAAAnNyABd4c2J0aS5hcGkuT3V0cHV0U2V0dGluZ3rZmkd0+x17AgACTAAPb3V0cHV0RGlyZWN0b3J5dAASTGphdmEvbGFuZy9TdHJpbmc7TAAPc291cmNlRGlyZWN0b3J5cQB+ABp4cHQALUQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2VcdGFyZ2V0XHRlc3QtY2xhc3Nlc3QAKEQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2Vcc3JjXHRlc3Rcc2NhbGFzcQB+ABl0AC1EOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHRhcmdldFx0ZXN0LWNsYXNzZXN0ACdEOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHNyY1x0ZXN0XGphdmF1cgACW0Ks8xf4BghU4AIAAHhwAAAAFKg9AJb0qRGZQ/XkeuAUDDYZZL6o
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\messages\ValidateAuthTokenRequestTest.java ->
rO0ABXNyABB4c2J0aS5hcGkuU291cmNlFlpwRASfbtoCAAZJAAdhcGlIYXNoWgAIaGFzTWFjcm9MABhfaW50ZXJuYWxPbmx5X25hbWVIYXNoZXN0ACRMeHNidGkvYXBpL19pbnRlcm5hbE9ubHlfTmFtZUhhc2hlcztMAANhcGl0ABVMeHNidGkvYXBpL1NvdXJjZUFQSTtMAAtjb21waWxhdGlvbnQAF0x4c2J0aS9hcGkvQ29tcGlsYXRpb247WwAEaGFzaHQAAltCeHC4IVHqAHNyACJ4c2J0aS5hcGkuX2ludGVybmFsT25seV9OYW1lSGFzaGVzVNq+mfrU7EwCAAJbAA9pbXBsaWNpdE1lbWJlcnN0ACNbTHhzYnRpL2FwaS9faW50ZXJuYWxPbmx5X05hbWVIYXNoO1sADnJlZ3VsYXJNZW1iZXJzcQB+AAd4cHVyACNbTHhzYnRpLmFwaS5faW50ZXJuYWxPbmx5X05hbWVIYXNoO0lagLbdlov0AgAAeHAAAAAAdXEAfgAJAAAAAHNyABN4c2J0aS5hcGkuU291cmNlQVBJuV6n+SkjOKQCAAJbAAtkZWZpbml0aW9uc3QAF1tMeHNidGkvYXBpL0RlZmluaXRpb247WwAIcGFja2FnZXN0ABRbTHhzYnRpL2FwaS9QYWNrYWdlO3hwdXIAF1tMeHNidGkuYXBpLkRlZmluaXRpb247iMlc57TjXg4CAAB4cAAAAAB1cgAUW0x4c2J0aS5hcGkuUGFja2FnZTtbExk3cKcnoQIAAHhwAAAAAHNyABV4c2J0aS5hcGkuQ29tcGlsYXRpb27t+uDDauigQgIAAkoACXN0YXJ0VGltZVsAB291dHB1dHN0ABpbTHhzYnRpL2FwaS9PdXRwdXRTZXR0aW5nO3hwAAABU3/ge511cgAaW0x4c2J0aS5hcGkuT3V0cHV0U2V0dGluZzt/asLzp4elQgIAAHhwAAAAAnNyABd4c2J0aS5hcGkuT3V0cHV0U2V0dGluZ3rZmkd0+x17AgACTAAPb3V0cHV0RGlyZWN0b3J5dAASTGphdmEvbGFuZy9TdHJpbmc7TAAPc291cmNlRGlyZWN0b3J5cQB+ABp4cHQALUQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2VcdGFyZ2V0XHRlc3QtY2xhc3Nlc3QAKEQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2Vcc3JjXHRlc3Rcc2NhbGFzcQB+ABl0AC1EOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHRhcmdldFx0ZXN0LWNsYXNzZXN0ACdEOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHNyY1x0ZXN0XGphdmF1cgACW0Ks8xf4BghU4AIAAHhwAAAAFN7mczhHeOaQ04t15NoHQBY6XkrB
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\messages\ValidateAuthTokenRequestTimedoutTest.java ->
rO0ABXNyABB4c2J0aS5hcGkuU291cmNlFlpwRASfbtoCAAZJAAdhcGlIYXNoWgAIaGFzTWFjcm9MABhfaW50ZXJuYWxPbmx5X25hbWVIYXNoZXN0ACRMeHNidGkvYXBpL19pbnRlcm5hbE9ubHlfTmFtZUhhc2hlcztMAANhcGl0ABVMeHNidGkvYXBpL1NvdXJjZUFQSTtMAAtjb21waWxhdGlvbnQAF0x4c2J0aS9hcGkvQ29tcGlsYXRpb247WwAEaGFzaHQAAltCeHC4IVHqAHNyACJ4c2J0aS5hcGkuX2ludGVybmFsT25seV9OYW1lSGFzaGVzVNq+mfrU7EwCAAJbAA9pbXBsaWNpdE1lbWJlcnN0ACNbTHhzYnRpL2FwaS9faW50ZXJuYWxPbmx5X05hbWVIYXNoO1sADnJlZ3VsYXJNZW1iZXJzcQB+AAd4cHVyACNbTHhzYnRpLmFwaS5faW50ZXJuYWxPbmx5X05hbWVIYXNoO0lagLbdlov0AgAAeHAAAAAAdXEAfgAJAAAAAHNyABN4c2J0aS5hcGkuU291cmNlQVBJuV6n+SkjOKQCAAJbAAtkZWZpbml0aW9uc3QAF1tMeHNidGkvYXBpL0RlZmluaXRpb247WwAIcGFja2FnZXN0ABRbTHhzYnRpL2FwaS9QYWNrYWdlO3hwdXIAF1tMeHNidGkuYXBpLkRlZmluaXRpb247iMlc57TjXg4CAAB4cAAAAAB1cgAUW0x4c2J0aS5hcGkuUGFja2FnZTtbExk3cKcnoQIAAHhwAAAAAHNyABV4c2J0aS5hcGkuQ29tcGlsYXRpb27t+uDDauigQgIAAkoACXN0YXJ0VGltZVsAB291dHB1dHN0ABpbTHhzYnRpL2FwaS9PdXRwdXRTZXR0aW5nO3hwAAABU3/ge511cgAaW0x4c2J0aS5hcGkuT3V0cHV0U2V0dGluZzt/asLzp4elQgIAAHhwAAAAAnNyABd4c2J0aS5hcGkuT3V0cHV0U2V0dGluZ3rZmkd0+x17AgACTAAPb3V0cHV0RGlyZWN0b3J5dAASTGphdmEvbGFuZy9TdHJpbmc7TAAPc291cmNlRGlyZWN0b3J5cQB+ABp4cHQALUQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2VcdGFyZ2V0XHRlc3QtY2xhc3Nlc3QAKEQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2Vcc3JjXHRlc3Rcc2NhbGFzcQB+ABl0AC1EOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHRhcmdldFx0ZXN0LWNsYXNzZXN0ACdEOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHNyY1x0ZXN0XGphdmF1cgACW0Ks8xf4BghU4AIAAHhwAAAAFKh9o9HRGUjHhjeXpzaEFUNy+z1e
external apis:
3 items
org.bigbluebutton.common.messages.MessageHeader ->
rO0ABXNyABB4c2J0aS5hcGkuU291cmNlFlpwRASfbtoCAAZJAAdhcGlIYXNoWgAIaGFzTWFjcm9MABhfaW50ZXJuYWxPbmx5X25hbWVIYXNoZXN0ACRMeHNidGkvYXBpL19pbnRlcm5hbE9ubHlfTmFtZUhhc2hlcztMAANhcGl0ABVMeHNidGkvYXBpL1NvdXJjZUFQSTtMAAtjb21waWxhdGlvbnQAF0x4c2J0aS9hcGkvQ29tcGlsYXRpb247WwAEaGFzaHQAAltCeHC1jHPaAHNyACJ4c2J0aS5hcGkuX2ludGVybmFsT25seV9OYW1lSGFzaGVzVNq+mfrU7EwCAAJbAA9pbXBsaWNpdE1lbWJlcnN0ACNbTHhzYnRpL2FwaS9faW50ZXJuYWxPbmx5X05hbWVIYXNoO1sADnJlZ3VsYXJNZW1iZXJzcQB+AAd4cHVyACNbTHhzYnRpLmFwaS5faW50ZXJuYWxPbmx5X05hbWVIYXNoO0lagLbdlov0AgAAeHAAAAAAdXEAfgAJAAAAAHNyABN4c2J0aS5hcGkuU291cmNlQVBJuV6n+SkjOKQCAAJbAAtkZWZpbml0aW9uc3QAF1tMeHNidGkvYXBpL0RlZmluaXRpb247WwAIcGFja2FnZXN0ABRbTHhzYnRpL2FwaS9QYWNrYWdlO3hwdXIAF1tMeHNidGkuYXBpLkRlZmluaXRpb247iMlc57TjXg4CAAB4cAAAAAJzcgATeHNidGkuYXBpLkNsYXNzTGlrZYM0HKHfsJdsAgAETAAOZGVmaW5pdGlvblR5cGV0ABpMeHNidGkvYXBpL0RlZmluaXRpb25UeXBlO1sAEHNhdmVkQW5ub3RhdGlvbnN0ABNbTGphdmEvbGFuZy9TdHJpbmc7TAAIc2VsZlR5cGV0ABBMeHNidGkvYXBpL0xhenk7TAAJc3RydWN0dXJlcQB+ABV4cgAheHNidGkuYXBpLlBhcmFtZXRlcml6ZWREZWZpbml0aW9u+RFusdVQPOICAAFbAA50eXBlUGFyYW1ldGVyc3QAGltMeHNidGkvYXBpL1R5cGVQYXJhbWV0ZXI7eHIAFHhzYnRpLmFwaS5EZWZpbml0aW9uhyob6HFC40YCAARMAAZhY2Nlc3N0ABJMeHNidGkvYXBpL0FjY2VzcztbAAthbm5vdGF0aW9uc3QAF1tMeHNidGkvYXBpL0Fubm90YXRpb247TAAJbW9kaWZpZXJzdAAVTHhzYnRpL2FwaS9Nb2RpZmllcnM7TAAEbmFtZXQAEkxqYXZhL2xhbmcvU3RyaW5nO3hwc3IAEHhzYnRpLmFwaS5QdWJsaWO6WD2ubC1gQgIAAHhyABB4c2J0aS5hcGkuQWNjZXNz3WKa+B1jMUgCAAB4cHVyABdbTHhzYnRpLmFwaS5Bbm5vdGF0aW9uO+uX6xkQ9o1IAgAAeHAAAAAAc3IAE3hzYnRpLmFwaS5Nb2RpZmllcnPHERMhaZzcJAIAAUIABWZsYWdzeHAAdAAvb3JnLmJpZ2JsdWVidXR0b24uY29tbW9uLm1lc3NhZ2VzLk1lc3NhZ2VIZWFkZXJ1cgAaW0x4c2J0aS5hcGkuVHlwZVBhcmFtZXRlcjvZbSYPKJ3ytgIAAHhwAAAAAH5yABh4c2J0aS5hcGkuRGVmaW5pdGlvblR5cGUAAAAAAAAAABIAAHhyAA5qYXZhLmxhbmcuRW51bQAAAAAAAAAAEgAAeHB0AAhDbGFzc0RlZnVyABNbTGphdmEubGFuZy5TdHJpbmc7rdJW5+kde0cCAAB4cAAAAAF0AAxzY2FsYS50aHJvd3NzcgATeHNidGkuU2FmZUxhenkkSW1wbDuRTxH0RUzJAgADWgAIYml0bWFwJDBMAAJfdHQAEkxqYXZhL2xhbmcvT2JqZWN0O0wABGV2YWx0ABFMc2NhbGEvRnVuY3Rpb24wO3hyABZ4c2J0aS5hcGkuQWJzdHJhY3RMYXp503e1AV+756ACAAB4cAFzcgATeHNidGkuYXBpLkVtcHR5VHlwZbz9nkZJO4kkAgAAeHIAFHhzYnRpLmFwaS5TaW1wbGVUeXBlcnhiiCEjv0ACAAB4cgAOeHNidGkuYXBpLlR5cGU/atkhFkmqygIAAHhwcHNxAH4ALwFzcgATeHNidGkuYXBpLlN0cnVjdHVyZamq+YCTb9gAAgADTAAIZGVjbGFyZWRxAH4AFUwACWluaGVyaXRlZHEAfgAVTAAHcGFyZW50c3EAfgAVeHEAfgA2c3EAfgAvAXVxAH4AEAAAAABwc3EAfgAvAXVxAH4AEAAAAABwc3EAfgAvAXVyABFbTHhzYnRpLmFwaS5UeXBlO3T/pVp7+elBAgAAeHAAAAABc3IAFHhzYnRpLmFwaS5Qcm9qZWN0aW9u89KNVOlFpC0CAAJMAAJpZHEAfgAcTAAGcHJlZml4dAAWTHhzYnRpL2FwaS9TaW1wbGVUeXBlO3hxAH4ANXQABk9iamVjdHNyABN4c2J0aS5hcGkuU2luZ2xldG9u/Kdf+M9W5EYCAAFMAARwYXRodAAQTHhzYnRpL2FwaS9QYXRoO3hxAH4ANXNyAA54c2J0aS5hcGkuUGF0aJs9XAjOpSeEAgABWwAKY29tcG9uZW50c3QAGltMeHNidGkvYXBpL1BhdGhDb21wb25lbnQ7eHB1cgAaW0x4c2J0aS5hcGkuUGF0aENvbXBvbmVudDtD2gl0LWcWdAIAAHhwAAAAA3NyAAx4c2J0aS5hcGkuSWSYMmyLN1PEQAIAAUwAAmlkcQB+ABx4cgAXeHNidGkuYXBpLlBhdGhDb21wb25lbnRfmiJbLoafvAIAAHhwdAAEamF2YXNxAH4ATnQABGxhbmdzcgAOeHNidGkuYXBpLlRoaXPbCe2mzFpAXAIAAHhxAH4AT3Bwc3EAfgAScQB+ACBxAH4AInEAfgAkcQB+ACVxAH4AJ35xAH4AKHQABk1vZHVsZXVxAH4ALAAAAABzcQB+AC8BcQB+ADdwc3EAfgAvAXNxAH4AOXNxAH4ALwF1cQB+ABAAAAAAcHNxAH4ALwF1cQB+ABAAAAAAcHNxAH4ALwF1cQB+AEAAAAAAcHB1cgAUW0x4c2J0aS5hcGkuUGFja2FnZTtbExk3cKcnoQIAAHhwAAAAAXNyABF4c2J0aS5hcGkuUGFja2FnZX5Zj/auzjlYAgABTAAEbmFtZXEAfgAceHB0ACFvcmcuYmlnYmx1ZWJ1dHRvbi5jb21tb24ubWVzc2FnZXNzcgAVeHNidGkuYXBpLkNvbXBpbGF0aW9u7frgw2rooEICAAJKAAlzdGFydFRpbWVbAAdvdXRwdXRzdAAaW0x4c2J0aS9hcGkvT3V0cHV0U2V0dGluZzt4cAAAAVLvfCYVdXIAGltMeHNidGkuYXBpLk91dHB1dFNldHRpbmc7f2rC86eHpUICAAB4cAAAAAJzcgAXeHNidGkuYXBpLk91dHB1dFNldHRpbmd62ZpHdPsdewIAAkwAD291dHB1dERpcmVjdG9yeXEAfgAcTAAPc291cmNlRGlyZWN0b3J5cQB+ABx4cHQAKEQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2VcdGFyZ2V0XGNsYXNzZXN0AChEOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHNyY1xtYWluXHNjYWxhc3EAfgBtdAAoRDpcYmJiXGJiYi1jb21tb24tbWVzc2FnZVx0YXJnZXRcY2xhc3Nlc3QAJ0Q6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2Vcc3JjXG1haW5camF2YXVyAAJbQqzzF/gGCFTgAgAAeHAAAAAUUqHbDR36cSvQL5OY+Lzv/3X5zc8=
org.bigbluebutton.common.messages.StartCustomPollRequestMessage ->
rO0ABXNyABB4c2J0aS5hcGkuU291cmNlFlpwRASfbtoCAAZJAAdhcGlIYXNoWgAIaGFzTWFjcm9MABhfaW50ZXJuYWxPbmx5X25hbWVIYXNoZXN0ACRMeHNidGkvYXBpL19pbnRlcm5hbE9ubHlfTmFtZUhhc2hlcztMAANhcGl0ABVMeHNidGkvYXBpL1NvdXJjZUFQSTtMAAtjb21waWxhdGlvbnQAF0x4c2J0aS9hcGkvQ29tcGlsYXRpb247WwAEaGFzaHQAAltCeHCUnh8qAHNyACJ4c2J0aS5hcGkuX2ludGVybmFsT25seV9OYW1lSGFzaGVzVNq+mfrU7EwCAAJbAA9pbXBsaWNpdE1lbWJlcnN0ACNbTHhzYnRpL2FwaS9faW50ZXJuYWxPbmx5X05hbWVIYXNoO1sADnJlZ3VsYXJNZW1iZXJzcQB+AAd4cHVyACNbTHhzYnRpLmFwaS5faW50ZXJuYWxPbmx5X05hbWVIYXNoO0lagLbdlov0AgAAeHAAAAAAdXEAfgAJAAAAAHNyABN4c2J0aS5hcGkuU291cmNlQVBJuV6n+SkjOKQCAAJbAAtkZWZpbml0aW9uc3QAF1tMeHNidGkvYXBpL0RlZmluaXRpb247WwAIcGFja2FnZXN0ABRbTHhzYnRpL2FwaS9QYWNrYWdlO3hwdXIAF1tMeHNidGkuYXBpLkRlZmluaXRpb247iMlc57TjXg4CAAB4cAAAAAJzcgATeHNidGkuYXBpLkNsYXNzTGlrZYM0HKHfsJdsAgAETAAOZGVmaW5pdGlvblR5cGV0ABpMeHNidGkvYXBpL0RlZmluaXRpb25UeXBlO1sAEHNhdmVkQW5ub3RhdGlvbnN0ABNbTGphdmEvbGFuZy9TdHJpbmc7TAAIc2VsZlR5cGV0ABBMeHNidGkvYXBpL0xhenk7TAAJc3RydWN0dXJlcQB+ABV4cgAheHNidGkuYXBpLlBhcmFtZXRlcml6ZWREZWZpbml0aW9u+RFusdVQPOICAAFbAA50eXBlUGFyYW1ldGVyc3QAGltMeHNidGkvYXBpL1R5cGVQYXJhbWV0ZXI7eHIAFHhzYnRpLmFwaS5EZWZpbml0aW9uhyob6HFC40YCAARMAAZhY2Nlc3N0ABJMeHNidGkvYXBpL0FjY2VzcztbAAthbm5vdGF0aW9uc3QAF1tMeHNidGkvYXBpL0Fubm90YXRpb247TAAJbW9kaWZpZXJzdAAVTHhzYnRpL2FwaS9Nb2RpZmllcnM7TAAEbmFtZXQAEkxqYXZhL2xhbmcvU3RyaW5nO3hwc3IAEHhzYnRpLmFwaS5QdWJsaWO6WD2ubC1gQgIAAHhyABB4c2J0aS5hcGkuQWNjZXNz3WKa+B1jMUgCAAB4cHVyABdbTHhzYnRpLmFwaS5Bbm5vdGF0aW9uO+uX6xkQ9o1IAgAAeHAAAAAAc3IAE3hzYnRpLmFwaS5Nb2RpZmllcnPHERMhaZzcJAIAAUIABWZsYWdzeHAAdAA/b3JnLmJpZ2JsdWVidXR0b24uY29tbW9uLm1lc3NhZ2VzLlN0YXJ0Q3VzdG9tUG9sbFJlcXVlc3RNZXNzYWdldXIAGltMeHNidGkuYXBpLlR5cGVQYXJhbWV0ZXI72W0mDyid8rYCAAB4cAAAAAB+cgAYeHNidGkuYXBpLkRlZmluaXRpb25UeXBlAAAAAAAAAAASAAB4cgAOamF2YS5sYW5nLkVudW0AAAAAAAAAABIAAHhwdAAIQ2xhc3NEZWZ1cgATW0xqYXZhLmxhbmcuU3RyaW5nO63SVufpHXtHAgAAeHAAAAABdAAMc2NhbGEudGhyb3dzc3IAE3hzYnRpLlNhZmVMYXp5JEltcGw7kU8R9EVMyQIAA1oACGJpdG1hcCQwTAACX3R0ABJMamF2YS9sYW5nL09iamVjdDtMAARldmFsdAARTHNjYWxhL0Z1bmN0aW9uMDt4cgAWeHNidGkuYXBpLkFic3RyYWN0TGF6edN3tQFfu+egAgAAeHABc3IAE3hzYnRpLmFwaS5FbXB0eVR5cGW8/Z5GSTuJJAIAAHhyABR4c2J0aS5hcGkuU2ltcGxlVHlwZXJ4YoghI79AAgAAeHIADnhzYnRpLmFwaS5UeXBlP2rZIRZJqsoCAAB4cHBzcQB+AC8Bc3IAE3hzYnRpLmFwaS5TdHJ1Y3R1cmWpqvmAk2/YAAIAA0wACGRlY2xhcmVkcQB+ABVMAAlpbmhlcml0ZWRxAH4AFUwAB3BhcmVudHNxAH4AFXhxAH4ANnNxAH4ALwF1cQB+ABAAAAAAcHNxAH4ALwF1cQB+ABAAAAAAcHNxAH4ALwF1cgARW0x4c2J0aS5hcGkuVHlwZTt0/6Vae/npQQIAAHhwAAAAAnNyABR4c2J0aS5hcGkuUHJvamVjdGlvbvPSjVTpRaQtAgACTAACaWRxAH4AHEwABnByZWZpeHQAFkx4c2J0aS9hcGkvU2ltcGxlVHlwZTt4cQB+ADV0AAZPYmplY3RzcgATeHNidGkuYXBpLlNpbmdsZXRvbvynX/jPVuRGAgABTAAEcGF0aHQAEEx4c2J0aS9hcGkvUGF0aDt4cQB+ADVzcgAOeHNidGkuYXBpLlBhdGibPVwIzqUnhAIAAVsACmNvbXBvbmVudHN0ABpbTHhzYnRpL2FwaS9QYXRoQ29tcG9uZW50O3hwdXIAGltMeHNidGkuYXBpLlBhdGhDb21wb25lbnQ7Q9oJdC1nFnQCAAB4cAAAAANzcgAMeHNidGkuYXBpLklkmDJsizdTxEACAAFMAAJpZHEAfgAceHIAF3hzYnRpLmFwaS5QYXRoQ29tcG9uZW50X5oiWy6Gn7wCAAB4cHQABGphdmFzcQB+AE50AARsYW5nc3IADnhzYnRpLmFwaS5UaGlz2wntpsxaQFwCAAB4cQB+AE9zcQB+AEJ0ABVJQmlnQmx1ZUJ1dHRvbk1lc3NhZ2VzcQB+AEZzcQB+AEl1cQB+AEwAAAAFc3EAfgBOdAADb3Jnc3EAfgBOdAANYmlnYmx1ZWJ1dHRvbnNxAH4ATnQABmNvbW1vbnNxAH4ATnQACG1lc3NhZ2VzcQB+AFVwcHNxAH4AEnEAfgAgcQB+ACJxAH4AJHEAfgAlcQB+ACd+cQB+ACh0AAZNb2R1bGV1cQB+ACwAAAAAc3EAfgAvAXEAfgA3cHNxAH4ALwFzcQB+ADlzcQB+AC8BdXEAfgAQAAAAAHBzcQB+AC8BdXEAfgAQAAAAAHBzcQB+AC8BdXEAfgBAAAAAAHBwdXIAFFtMeHNidGkuYXBpLlBhY2thZ2U7WxMZN3CnJ6ECAAB4cAAAAAFzcgAReHNidGkuYXBpLlBhY2thZ2V+WY/2rs45WAIAAUwABG5hbWVxAH4AHHhwdAAhb3JnLmJpZ2JsdWVidXR0b24uY29tbW9uLm1lc3NhZ2Vzc3IAFXhzYnRpLmFwaS5Db21waWxhdGlvbu364MNq6KBCAgACSgAJc3RhcnRUaW1lWwAHb3V0cHV0c3QAGltMeHNidGkvYXBpL091dHB1dFNldHRpbmc7eHAAAAFS73wmFXVyABpbTHhzYnRpLmFwaS5PdXRwdXRTZXR0aW5nO39qwvOnh6VCAgAAeHAAAAACc3IAF3hzYnRpLmFwaS5PdXRwdXRTZXR0aW5netmaR3T7HXsCAAJMAA9vdXRwdXREaXJlY3RvcnlxAH4AHEwAD3NvdXJjZURpcmVjdG9yeXEAfgAceHB0AChEOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHRhcmdldFxjbGFzc2VzdAAoRDpcYmJiXGJiYi1jb21tb24tbWVzc2FnZVxzcmNcbWFpblxzY2FsYXNxAH4AenQAKEQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2VcdGFyZ2V0XGNsYXNzZXN0ACdEOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHNyY1xtYWluXGphdmF1cgACW0Ks8xf4BghU4AIAAHhwAAAAFAioGqdQNl4/UhiqNwOoAfmiyZIt
org.bigbluebutton.common.messages.payload.StartCustomPollRequestMessagePayload ->
rO0ABXNyABB4c2J0aS5hcGkuU291cmNlFlpwRASfbtoCAAZJAAdhcGlIYXNoWgAIaGFzTWFjcm9MABhfaW50ZXJuYWxPbmx5X25hbWVIYXNoZXN0ACRMeHNidGkvYXBpL19pbnRlcm5hbE9ubHlfTmFtZUhhc2hlcztMAANhcGl0ABVMeHNidGkvYXBpL1NvdXJjZUFQSTtMAAtjb21waWxhdGlvbnQAF0x4c2J0aS9hcGkvQ29tcGlsYXRpb247WwAEaGFzaHQAAltCeHBDEceaAHNyACJ4c2J0aS5hcGkuX2ludGVybmFsT25seV9OYW1lSGFzaGVzVNq+mfrU7EwCAAJbAA9pbXBsaWNpdE1lbWJlcnN0ACNbTHhzYnRpL2FwaS9faW50ZXJuYWxPbmx5X05hbWVIYXNoO1sADnJlZ3VsYXJNZW1iZXJzcQB+AAd4cHVyACNbTHhzYnRpLmFwaS5faW50ZXJuYWxPbmx5X05hbWVIYXNoO0lagLbdlov0AgAAeHAAAAAAdXEAfgAJAAAAAHNyABN4c2J0aS5hcGkuU291cmNlQVBJuV6n+SkjOKQCAAJbAAtkZWZpbml0aW9uc3QAF1tMeHNidGkvYXBpL0RlZmluaXRpb247WwAIcGFja2FnZXN0ABRbTHhzYnRpL2FwaS9QYWNrYWdlO3hwdXIAF1tMeHNidGkuYXBpLkRlZmluaXRpb247iMlc57TjXg4CAAB4cAAAAAJzcgATeHNidGkuYXBpLkNsYXNzTGlrZYM0HKHfsJdsAgAETAAOZGVmaW5pdGlvblR5cGV0ABpMeHNidGkvYXBpL0RlZmluaXRpb25UeXBlO1sAEHNhdmVkQW5ub3RhdGlvbnN0ABNbTGphdmEvbGFuZy9TdHJpbmc7TAAIc2VsZlR5cGV0ABBMeHNidGkvYXBpL0xhenk7TAAJc3RydWN0dXJlcQB+ABV4cgAheHNidGkuYXBpLlBhcmFtZXRlcml6ZWREZWZpbml0aW9u+RFusdVQPOICAAFbAA50eXBlUGFyYW1ldGVyc3QAGltMeHNidGkvYXBpL1R5cGVQYXJhbWV0ZXI7eHIAFHhzYnRpLmFwaS5EZWZpbml0aW9uhyob6HFC40YCAARMAAZhY2Nlc3N0ABJMeHNidGkvYXBpL0FjY2VzcztbAAthbm5vdGF0aW9uc3QAF1tMeHNidGkvYXBpL0Fubm90YXRpb247TAAJbW9kaWZpZXJzdAAVTHhzYnRpL2FwaS9Nb2RpZmllcnM7TAAEbmFtZXQAEkxqYXZhL2xhbmcvU3RyaW5nO3hwc3IAEHhzYnRpLmFwaS5QdWJsaWO6WD2ubC1gQgIAAHhyABB4c2J0aS5hcGkuQWNjZXNz3WKa+B1jMUgCAAB4cHVyABdbTHhzYnRpLmFwaS5Bbm5vdGF0aW9uO+uX6xkQ9o1IAgAAeHAAAAAAc3IAE3hzYnRpLmFwaS5Nb2RpZmllcnPHERMhaZzcJAIAAUIABWZsYWdzeHAAdABOb3JnLmJpZ2JsdWVidXR0b24uY29tbW9uLm1lc3NhZ2VzLnBheWxvYWQuU3RhcnRDdXN0b21Qb2xsUmVxdWVzdE1lc3NhZ2VQYXlsb2FkdXIAGltMeHNidGkuYXBpLlR5cGVQYXJhbWV0ZXI72W0mDyid8rYCAAB4cAAAAAB+cgAYeHNidGkuYXBpLkRlZmluaXRpb25UeXBlAAAAAAAAAAASAAB4cgAOamF2YS5sYW5nLkVudW0AAAAAAAAAABIAAHhwdAAIQ2xhc3NEZWZ1cgATW0xqYXZhLmxhbmcuU3RyaW5nO63SVufpHXtHAgAAeHAAAAABdAAMc2NhbGEudGhyb3dzc3IAE3hzYnRpLlNhZmVMYXp5JEltcGw7kU8R9EVMyQIAA1oACGJpdG1hcCQwTAACX3R0ABJMamF2YS9sYW5nL09iamVjdDtMAARldmFsdAARTHNjYWxhL0Z1bmN0aW9uMDt4cgAWeHNidGkuYXBpLkFic3RyYWN0TGF6edN3tQFfu+egAgAAeHABc3IAE3hzYnRpLmFwaS5FbXB0eVR5cGW8/Z5GSTuJJAIAAHhyABR4c2J0aS5hcGkuU2ltcGxlVHlwZXJ4YoghI79AAgAAeHIADnhzYnRpLmFwaS5UeXBlP2rZIRZJqsoCAAB4cHBzcQB+AC8Bc3IAE3hzYnRpLmFwaS5TdHJ1Y3R1cmWpqvmAk2/YAAIAA0wACGRlY2xhcmVkcQB+ABVMAAlpbmhlcml0ZWRxAH4AFUwAB3BhcmVudHNxAH4AFXhxAH4ANnNxAH4ALwF1cQB+ABAAAAAAcHNxAH4ALwF1cQB+ABAAAAAAcHNxAH4ALwF1cgARW0x4c2J0aS5hcGkuVHlwZTt0/6Vae/npQQIAAHhwAAAAAXNyABR4c2J0aS5hcGkuUHJvamVjdGlvbvPSjVTpRaQtAgACTAACaWRxAH4AHEwABnByZWZpeHQAFkx4c2J0aS9hcGkvU2ltcGxlVHlwZTt4cQB+ADV0AAZPYmplY3RzcgATeHNidGkuYXBpLlNpbmdsZXRvbvynX/jPVuRGAgABTAAEcGF0aHQAEEx4c2J0aS9hcGkvUGF0aDt4cQB+ADVzcgAOeHNidGkuYXBpLlBhdGibPVwIzqUnhAIAAVsACmNvbXBvbmVudHN0ABpbTHhzYnRpL2FwaS9QYXRoQ29tcG9uZW50O3hwdXIAGltMeHNidGkuYXBpLlBhdGhDb21wb25lbnQ7Q9oJdC1nFnQCAAB4cAAAAANzcgAMeHNidGkuYXBpLklkmDJsizdTxEACAAFMAAJpZHEAfgAceHIAF3hzYnRpLmFwaS5QYXRoQ29tcG9uZW50X5oiWy6Gn7wCAAB4cHQABGphdmFzcQB+AE50AARsYW5nc3IADnhzYnRpLmFwaS5UaGlz2wntpsxaQFwCAAB4cQB+AE9wcHNxAH4AEnEAfgAgcQB+ACJxAH4AJHEAfgAlcQB+ACd+cQB+ACh0AAZNb2R1bGV1cQB+ACwAAAAAc3EAfgAvAXEAfgA3cHNxAH4ALwFzcQB+ADlzcQB+AC8BdXEAfgAQAAAAAHBzcQB+AC8BdXEAfgAQAAAAAHBzcQB+AC8BdXEAfgBAAAAAAHBwdXIAFFtMeHNidGkuYXBpLlBhY2thZ2U7WxMZN3CnJ6ECAAB4cAAAAAFzcgAReHNidGkuYXBpLlBhY2thZ2V+WY/2rs45WAIAAUwABG5hbWVxAH4AHHhwdAApb3JnLmJpZ2JsdWVidXR0b24uY29tbW9uLm1lc3NhZ2VzLnBheWxvYWRzcgAVeHNidGkuYXBpLkNvbXBpbGF0aW9u7frgw2rooEICAAJKAAlzdGFydFRpbWVbAAdvdXRwdXRzdAAaW0x4c2J0aS9hcGkvT3V0cHV0U2V0dGluZzt4cAAAAVLvfCYVdXIAGltMeHNidGkuYXBpLk91dHB1dFNldHRpbmc7f2rC86eHpUICAAB4cAAAAAJzcgAXeHNidGkuYXBpLk91dHB1dFNldHRpbmd62ZpHdPsdewIAAkwAD291dHB1dERpcmVjdG9yeXEAfgAcTAAPc291cmNlRGlyZWN0b3J5cQB+ABx4cHQAKEQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2VcdGFyZ2V0XGNsYXNzZXN0AChEOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHNyY1xtYWluXHNjYWxhc3EAfgBtdAAoRDpcYmJiXGJiYi1jb21tb24tbWVzc2FnZVx0YXJnZXRcY2xhc3Nlc3QAJ0Q6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2Vcc3JjXG1haW5camF2YXVyAAJbQqzzF/gGCFTgAgAAeHAAAAAUtra1/474+FAArE/LUhsDV5gbWrM=
source infos:
8 items
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\common\messages\StartCustomPollRequestMessageTest.java ->
AAAAAAAAAAA=
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\messages\BreakoutRoomsListTest.java ->
AAAAAAAAAAA=
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\messages\CreateBreakoutRoomRequestTest.java ->
AAAAAAAAAAA=
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\messages\CreateBreakoutRoomsRequestTest.java ->
AAAAAAAAAAA=
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\messages\CreateMeetingRequestTest.java ->
AAAAAAAAAAA=
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\messages\ValidateAuthTokenReplyTest.java ->
AAAAAAAAAAA=
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\messages\ValidateAuthTokenRequestTest.java ->
AAAAAAAAAAA=
D:\bbb\bbb-common-message\src\test\java\org\bigbluebutton\messages\ValidateAuthTokenRequestTimedoutTest.java ->
AAAAAAAAAAA=
compilations:
6 items
0 -> rO0ABXNyABV4c2J0aS5hcGkuQ29tcGlsYXRpb27t+uDDauigQgIAAkoACXN0YXJ0VGltZVsAB291dHB1dHN0ABpbTHhzYnRpL2FwaS9PdXRwdXRTZXR0aW5nO3hwAAABUu97VvZ1cgAaW0x4c2J0aS5hcGkuT3V0cHV0U2V0dGluZzt/asLzp4elQgIAAHhwAAAAAnNyABd4c2J0aS5hcGkuT3V0cHV0U2V0dGluZ3rZmkd0+x17AgACTAAPb3V0cHV0RGlyZWN0b3J5dAASTGphdmEvbGFuZy9TdHJpbmc7TAAPc291cmNlRGlyZWN0b3J5cQB+AAZ4cHQALUQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2VcdGFyZ2V0XHRlc3QtY2xhc3Nlc3QAKEQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2Vcc3JjXHRlc3Rcc2NhbGFzcQB+AAV0AC1EOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHRhcmdldFx0ZXN0LWNsYXNzZXN0ACdEOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHNyY1x0ZXN0XGphdmE=
1 -> rO0ABXNyABV4c2J0aS5hcGkuQ29tcGlsYXRpb27t+uDDauigQgIAAkoACXN0YXJ0VGltZVsAB291dHB1dHN0ABpbTHhzYnRpL2FwaS9PdXRwdXRTZXR0aW5nO3hwAAABUu98LnR1cgAaW0x4c2J0aS5hcGkuT3V0cHV0U2V0dGluZzt/asLzp4elQgIAAHhwAAAAAnNyABd4c2J0aS5hcGkuT3V0cHV0U2V0dGluZ3rZmkd0+x17AgACTAAPb3V0cHV0RGlyZWN0b3J5dAASTGphdmEvbGFuZy9TdHJpbmc7TAAPc291cmNlRGlyZWN0b3J5cQB+AAZ4cHQALUQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2VcdGFyZ2V0XHRlc3QtY2xhc3Nlc3QAKEQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2Vcc3JjXHRlc3Rcc2NhbGFzcQB+AAV0AC1EOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHRhcmdldFx0ZXN0LWNsYXNzZXN0ACdEOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHNyY1x0ZXN0XGphdmE=
2 -> rO0ABXNyABV4c2J0aS5hcGkuQ29tcGlsYXRpb27t+uDDauigQgIAAkoACXN0YXJ0VGltZVsAB291dHB1dHN0ABpbTHhzYnRpL2FwaS9PdXRwdXRTZXR0aW5nO3hwAAABUzbzjtV1cgAaW0x4c2J0aS5hcGkuT3V0cHV0U2V0dGluZzt/asLzp4elQgIAAHhwAAAAAnNyABd4c2J0aS5hcGkuT3V0cHV0U2V0dGluZ3rZmkd0+x17AgACTAAPb3V0cHV0RGlyZWN0b3J5dAASTGphdmEvbGFuZy9TdHJpbmc7TAAPc291cmNlRGlyZWN0b3J5cQB+AAZ4cHQALUQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2VcdGFyZ2V0XHRlc3QtY2xhc3Nlc3QAKEQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2Vcc3JjXHRlc3Rcc2NhbGFzcQB+AAV0AC1EOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHRhcmdldFx0ZXN0LWNsYXNzZXN0ACdEOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHNyY1x0ZXN0XGphdmE=
3 -> rO0ABXNyABV4c2J0aS5hcGkuQ29tcGlsYXRpb27t+uDDauigQgIAAkoACXN0YXJ0VGltZVsAB291dHB1dHN0ABpbTHhzYnRpL2FwaS9PdXRwdXRTZXR0aW5nO3hwAAABUzb2Kqd1cgAaW0x4c2J0aS5hcGkuT3V0cHV0U2V0dGluZzt/asLzp4elQgIAAHhwAAAAAnNyABd4c2J0aS5hcGkuT3V0cHV0U2V0dGluZ3rZmkd0+x17AgACTAAPb3V0cHV0RGlyZWN0b3J5dAASTGphdmEvbGFuZy9TdHJpbmc7TAAPc291cmNlRGlyZWN0b3J5cQB+AAZ4cHQALUQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2VcdGFyZ2V0XHRlc3QtY2xhc3Nlc3QAKEQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2Vcc3JjXHRlc3Rcc2NhbGFzcQB+AAV0AC1EOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHRhcmdldFx0ZXN0LWNsYXNzZXN0ACdEOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHNyY1x0ZXN0XGphdmE=
4 -> rO0ABXNyABV4c2J0aS5hcGkuQ29tcGlsYXRpb27t+uDDauigQgIAAkoACXN0YXJ0VGltZVsAB291dHB1dHN0ABpbTHhzYnRpL2FwaS9PdXRwdXRTZXR0aW5nO3hwAAABU2JpMJp1cgAaW0x4c2J0aS5hcGkuT3V0cHV0U2V0dGluZzt/asLzp4elQgIAAHhwAAAAAnNyABd4c2J0aS5hcGkuT3V0cHV0U2V0dGluZ3rZmkd0+x17AgACTAAPb3V0cHV0RGlyZWN0b3J5dAASTGphdmEvbGFuZy9TdHJpbmc7TAAPc291cmNlRGlyZWN0b3J5cQB+AAZ4cHQALUQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2VcdGFyZ2V0XHRlc3QtY2xhc3Nlc3QAKEQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2Vcc3JjXHRlc3Rcc2NhbGFzcQB+AAV0AC1EOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHRhcmdldFx0ZXN0LWNsYXNzZXN0ACdEOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHNyY1x0ZXN0XGphdmE=
5 -> rO0ABXNyABV4c2J0aS5hcGkuQ29tcGlsYXRpb27t+uDDauigQgIAAkoACXN0YXJ0VGltZVsAB291dHB1dHN0ABpbTHhzYnRpL2FwaS9PdXRwdXRTZXR0aW5nO3hwAAABU3/ge511cgAaW0x4c2J0aS5hcGkuT3V0cHV0U2V0dGluZzt/asLzp4elQgIAAHhwAAAAAnNyABd4c2J0aS5hcGkuT3V0cHV0U2V0dGluZ3rZmkd0+x17AgACTAAPb3V0cHV0RGlyZWN0b3J5dAASTGphdmEvbGFuZy9TdHJpbmc7TAAPc291cmNlRGlyZWN0b3J5cQB+AAZ4cHQALUQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2VcdGFyZ2V0XHRlc3QtY2xhc3Nlc3QAKEQ6XGJiYlxiYmItY29tbW9uLW1lc3NhZ2Vcc3JjXHRlc3Rcc2NhbGFzcQB+AAV0AC1EOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHRhcmdldFx0ZXN0LWNsYXNzZXN0ACdEOlxiYmJcYmJiLWNvbW1vbi1tZXNzYWdlXHNyY1x0ZXN0XGphdmE=

View File

@ -2,7 +2,7 @@ name := "bbb-common-message"
organization := "org.bigbluebutton" organization := "org.bigbluebutton"
version := "0.0.17-SNAPSHOT" version := "0.0.18-SNAPSHOT"
// We want to have our jar files in lib_managed dir. // We want to have our jar files in lib_managed dir.
// This way we'll have the right path when we import // This way we'll have the right path when we import
@ -51,15 +51,13 @@ publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath+"/.
// Comment this out when publishing to local maven repo using SNAPSHOT version. // Comment this out when publishing to local maven repo using SNAPSHOT version.
// To push to sonatype "sbt publishSigned" // To push to sonatype "sbt publishSigned"
/* //publishTo := {
publishTo := { // val nexus = "https://oss.sonatype.org/"
val nexus = "https://oss.sonatype.org/" // if (isSnapshot.value)
if (isSnapshot.value) // Some("snapshots" at nexus + "content/repositories/snapshots")
Some("snapshots" at nexus + "content/repositories/snapshots") // else
else // Some("releases" at nexus + "service/local/staging/deploy/maven2")
Some("releases" at nexus + "service/local/staging/deploy/maven2") //}
}
*/
// Enables publishing to maven repo // Enables publishing to maven repo
publishMavenStyle := true publishMavenStyle := true

View File

@ -32,7 +32,7 @@ public class FromJsonDecoder {
StartCustomPollRequestMessage msg = gson.fromJson(message, StartCustomPollRequestMessage.class); StartCustomPollRequestMessage msg = gson.fromJson(message, StartCustomPollRequestMessage.class);
return msg; return msg;
} else { } else {
System.out.println("Unknown message name=[" + messageName + "]"); // System.out.println("Unknown message name=[" + messageName + "]");
return null; return null;
} }
} }

View File

@ -131,4 +131,11 @@ public class Constants {
public static final String TEXT = "text"; public static final String TEXT = "text";
public static final String OWNER_ID = "owner_id"; public static final String OWNER_ID = "owner_id";
public static final String CAPTION_HISTORY = "caption_history"; public static final String CAPTION_HISTORY = "caption_history";
public static final String AVATAR_URL = "avatarURL";
public static final String STUNS = "stuns";
public static final String TURNS = "turns";
public static final String USERNAME = "username";
public static final String URL = "url";
public static final String TTL = "ttl";
public static final String PASSWORD = "password";
} }

View File

@ -0,0 +1,61 @@
package org.bigbluebutton.common.messages;
import java.util.HashMap;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
/**
* Created by anton on 21/12/15.
*/
public class DeskShareGetInfoRequestMessage {
public static final String GET_DESKTOP_SHARE_GET_INFO_REQUEST = "desktop_share_get_info_request";
public static final String VERSION = "0.0.1";
public final String meetingId;
public final String requesterId;
public final String replyTo;
public DeskShareGetInfoRequestMessage(String meetingId, String requesterId, String replyTo) {
this.meetingId = meetingId;
this.requesterId = requesterId;
this.replyTo = replyTo;
}
public String toJson() {
HashMap<String, Object> payload = new HashMap<String, Object>();
payload.put(Constants.MEETING_ID, meetingId);
payload.put(Constants.REQUESTER_ID, requesterId);
payload.put(Constants.REPLY_TO, replyTo);
java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(GET_DESKTOP_SHARE_GET_INFO_REQUEST, VERSION, null);
return MessageBuilder.buildJson(header, payload);
}
public static DeskShareGetInfoRequestMessage fromJson(String message) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
JsonObject payload = (JsonObject) obj.get("payload");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (GET_DESKTOP_SHARE_GET_INFO_REQUEST.equals(messageName)) {
if (payload.has(Constants.MEETING_ID)
&& payload.has(Constants.REPLY_TO)
&& payload.has(Constants.REQUESTER_ID)) {
String id = payload.get(Constants.MEETING_ID).getAsString();
String requesterId = payload.get(Constants.REQUESTER_ID).getAsString();
String replyTo = payload.get(Constants.REPLY_TO).getAsString();
return new DeskShareGetInfoRequestMessage(id, requesterId, replyTo);
}
}
}
}
return null;
}
}

View File

@ -0,0 +1,68 @@
package org.bigbluebutton.common.messages;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.util.HashMap;
/**
* Created by anton on 07/01/16.
*/
// akka-bbb-apps to akka-bbb-fsesl
public class DeskShareHangUpEventMessage {
public static final String DESKSHARE_HANG_UP_MESSAGE = "deskshare_hang_up_message";
public static final String VERSION = "0.0.1";
public static final String CONFERENCE_NAME = "conference_name";
public static final String FS_CONFERENCE_NAME = "fs_conference_name";
public static final String TIMESTAMP = "timestamp";
public final String conferenceName;
public final String timestamp;
public final String fsConferenceName;
public DeskShareHangUpEventMessage(String conferenceName, String fsConferenceName, String timestamp) {
this.conferenceName = conferenceName;
this.fsConferenceName = fsConferenceName;
this.timestamp = timestamp;
}
public String toJson() {
HashMap<String, Object> payload = new HashMap<String, Object>();
payload.put(CONFERENCE_NAME, conferenceName);
payload.put(FS_CONFERENCE_NAME, fsConferenceName);
payload.put(TIMESTAMP, timestamp);
java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(DESKSHARE_HANG_UP_MESSAGE, VERSION, null);
return MessageBuilder.buildJson(header, payload);
}
public static DeskShareHangUpEventMessage fromJson(String message) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
JsonObject payload = (JsonObject) obj.get("payload");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (DESKSHARE_HANG_UP_MESSAGE.equals(messageName)) {
if (payload.has(CONFERENCE_NAME)
&& payload.has(FS_CONFERENCE_NAME)
&& payload.has(TIMESTAMP)) {
String conferenceName = payload.get(CONFERENCE_NAME).getAsString();
String fsConferenceName = payload.get(FS_CONFERENCE_NAME).getAsString();
String timestamp = payload.get(TIMESTAMP).getAsString();
return new DeskShareHangUpEventMessage(conferenceName, fsConferenceName, timestamp);
}
}
}
}
return null;
}
}

View File

@ -0,0 +1,93 @@
package org.bigbluebutton.common.messages;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.util.HashMap;
//Message from bbb-akka-apps to bigbluebutton-apps (in red5)
public class DeskShareNotifyASingleViewerEventMessage {
public static final String DESK_SHARE_NOTIFY_A_SINGLE_VIEWER = "desk_share_notify_a_single_viewer";
public static final String VERSION = "0.0.1";
public static final String MEETING_ID = "meeting_id";
public static final String USER_ID = "userid";
public static final String STREAM_PATH = "stream_path";
public static final String BROADCASTING = "broadcasting";
public static final String TIMESTAMP = "timestamp";
public static final String VIDEO_WIDTH = "vw";
public static final String VIDEO_HEIGHT = "vh";
public final String meetingId;
public final String userId;
public final String streamPath;
public final boolean broadcasting;
public final String timestamp;
public final int vw;
public final int vh;
public DeskShareNotifyASingleViewerEventMessage(String meetingId, String userId, String streamPath,
boolean broadcasting, int vw, int vh, String timestamp) {
this.meetingId = meetingId;
this.userId=userId;
this.streamPath = streamPath;
this.broadcasting = broadcasting;
this.timestamp = timestamp;
this.vw = vw;
this.vh = vh;
}
public String toJson() {
HashMap<String, Object> payload = new HashMap<String, Object>();
payload.put(MEETING_ID, meetingId);
payload.put(USER_ID, userId);
payload.put(STREAM_PATH, streamPath);
payload.put(BROADCASTING, broadcasting);
payload.put(TIMESTAMP, timestamp);
payload.put(VIDEO_HEIGHT, vh);
payload.put(VIDEO_WIDTH, vw);
java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(DESK_SHARE_NOTIFY_A_SINGLE_VIEWER, VERSION, null);
return MessageBuilder.buildJson(header, payload);
}
public static DeskShareNotifyASingleViewerEventMessage fromJson(String message) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
JsonObject payload = (JsonObject) obj.get("payload");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (DESK_SHARE_NOTIFY_A_SINGLE_VIEWER.equals(messageName)) {
if (payload.has(MEETING_ID)
&& payload.has(USER_ID)
&& payload.has(BROADCASTING)
&& payload.has(TIMESTAMP)
&& payload.has(VIDEO_HEIGHT)
&& payload.has(VIDEO_WIDTH)
&& payload.has(STREAM_PATH)) {
String meetingId = payload.get(MEETING_ID).getAsString();
String userId = payload.get(USER_ID).getAsString();
String streamPath = payload.get(STREAM_PATH).getAsString();
boolean broadcasting = payload.get(BROADCASTING).getAsBoolean();
String timestamp = payload.get(TIMESTAMP).getAsString();
int vh = payload.get(VIDEO_HEIGHT).getAsInt();
int vw = payload.get(VIDEO_WIDTH).getAsInt();
return new DeskShareNotifyASingleViewerEventMessage(meetingId, userId, streamPath,
broadcasting, vw, vh, timestamp);
}
}
}
}
return null;
}
}

View File

@ -0,0 +1,83 @@
package org.bigbluebutton.common.messages;
import java.util.HashMap;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
//Message from bbb-akka-apps to bbb-apps-red5
public class DeskShareNotifyViewersRTMPEventMessage {
public static final String DESK_SHARE_NOTIFY_VIEWERS_RTMP = "desk_share_notify_viewers_rtmp";
public static final String VERSION = "0.0.1";
public static final String MEETING_ID = "meeting_id";
public static final String STREAM_PATH = "stream_path";
public static final String BROADCASTING = "broadcasting";
public static final String VIDEO_WIDTH = "vw";
public static final String VIDEO_HEIGHT = "vh";
public static final String TIMESTAMP = "timestamp";
public final String meetingId;
public final String streamPath;
public final boolean broadcasting;
public final String timestamp;
public final int vw;
public final int vh;
public DeskShareNotifyViewersRTMPEventMessage(String meetingId, String streamPath,
boolean broadcasting, int vw, int vh, String timestamp) {
this.meetingId = meetingId;
this.streamPath = streamPath;
this.broadcasting = broadcasting;
this.timestamp = timestamp;
this.vw = vw;
this.vh = vh;
}
public String toJson() {
HashMap<String, Object> payload = new HashMap<String, Object>();
payload.put(MEETING_ID, meetingId);
payload.put(STREAM_PATH, streamPath);
payload.put(BROADCASTING, broadcasting);
payload.put(TIMESTAMP, timestamp);
payload.put(VIDEO_HEIGHT, vh);
payload.put(VIDEO_WIDTH, vw);
java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(DESK_SHARE_NOTIFY_VIEWERS_RTMP, VERSION, null);
return MessageBuilder.buildJson(header, payload);
}
public static DeskShareNotifyViewersRTMPEventMessage fromJson(String message) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
JsonObject payload = (JsonObject) obj.get("payload");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (DESK_SHARE_NOTIFY_VIEWERS_RTMP.equals(messageName)) {
if (payload.has(MEETING_ID)
&& payload.has(BROADCASTING)
&& payload.has(TIMESTAMP)
&& payload.has(VIDEO_HEIGHT)
&& payload.has(VIDEO_WIDTH)
&& payload.has(STREAM_PATH)) {
String meetingId = payload.get(MEETING_ID).getAsString();
String streamPath = payload.get(STREAM_PATH).getAsString();
boolean broadcasting = payload.get(BROADCASTING).getAsBoolean();
String timestamp = payload.get(TIMESTAMP).getAsString();
int vh = payload.get(VIDEO_HEIGHT).getAsInt();
int vw = payload.get(VIDEO_WIDTH).getAsInt();
return new DeskShareNotifyViewersRTMPEventMessage(meetingId, streamPath, broadcasting, vw, vh, timestamp);
}
}
}
}
return null;
}
}

View File

@ -0,0 +1,75 @@
package org.bigbluebutton.common.messages;
import java.util.HashMap;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class DeskShareRTMPBroadcastStartedEventMessage {
public static final String DESKSHARE_RTMP_BROADCAST_STARTED_MESSAGE = "deskshare_rtmp_broadcast_started_message";
public static final String VERSION = "0.0.1";
public static final String CONFERENCE_NAME = "conference_name";
public static final String STREAMNAME = "streamname";
public static final String TIMESTAMP = "timestamp";
public static final String VIDEO_WIDTH = "vw";
public static final String VIDEO_HEIGHT = "vh";
public final String conferenceName;
public final String streamname;
public final String timestamp;
public final int vw;
public final int vh;
public DeskShareRTMPBroadcastStartedEventMessage(String conferenceName, String streamname, int vw, int vh, String timestamp) {
this.conferenceName = conferenceName;
this.streamname = streamname;
this.timestamp = timestamp;
this.vw = vw;
this.vh = vh;
}
public String toJson() {
HashMap<String, Object> payload = new HashMap<String, Object>();
payload.put(CONFERENCE_NAME, conferenceName);
payload.put(STREAMNAME, streamname);
payload.put(TIMESTAMP, timestamp);
payload.put(VIDEO_HEIGHT, vh);
payload.put(VIDEO_WIDTH, vw);
java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(DESKSHARE_RTMP_BROADCAST_STARTED_MESSAGE, VERSION, null);
return MessageBuilder.buildJson(header, payload);
}
public static DeskShareRTMPBroadcastStartedEventMessage fromJson(String message) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
JsonObject payload = (JsonObject) obj.get("payload");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (DESKSHARE_RTMP_BROADCAST_STARTED_MESSAGE.equals(messageName)) {
if (payload.has(CONFERENCE_NAME)
&& payload.has(TIMESTAMP)
&& payload.has(VIDEO_HEIGHT)
&& payload.has(VIDEO_WIDTH)
&& payload.has(STREAMNAME)) {
String conferenceName = payload.get(CONFERENCE_NAME).getAsString();
String streamname = payload.get(STREAMNAME).getAsString();
String timestamp = payload.get(TIMESTAMP).getAsString();
int vh = payload.get(VIDEO_HEIGHT).getAsInt();
int vw = payload.get(VIDEO_WIDTH).getAsInt();
return new DeskShareRTMPBroadcastStartedEventMessage(conferenceName, streamname, vw, vh, timestamp);
}
}
}
}
return null;
}
}

View File

@ -0,0 +1,76 @@
package org.bigbluebutton.common.messages;
import java.util.HashMap;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class DeskShareRTMPBroadcastStoppedEventMessage {
public static final String DESKSHARE_RTMP_BROADCAST_STOPPED_MESSAGE = "deskshare_rtmp_broadcast_stopped_message";
public static final String VERSION = "0.0.1";
public static final String CONFERENCE_NAME = "conference_name";
public static final String STREAMNAME = "streamname";
public static final String TIMESTAMP = "timestamp";
public static final String VIDEO_WIDTH = "vw";
public static final String VIDEO_HEIGHT = "vh";
public final String conferenceName;
public final String streamname;
public final String timestamp;
public final int vw;
public final int vh;
public DeskShareRTMPBroadcastStoppedEventMessage(String conferenceName, String streamname, int vw, int vh, String timestamp) {
this.conferenceName = conferenceName;
this.streamname = streamname;
this.timestamp = timestamp;
this.vw = vw;
this.vh = vh;
}
public String toJson() {
HashMap<String, Object> payload = new HashMap<String, Object>();
payload.put(CONFERENCE_NAME, conferenceName);
payload.put(STREAMNAME, streamname);
payload.put(TIMESTAMP, timestamp);
payload.put(VIDEO_HEIGHT, vh);
payload.put(VIDEO_WIDTH, vw);
java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(DESKSHARE_RTMP_BROADCAST_STOPPED_MESSAGE, VERSION, null);
return MessageBuilder.buildJson(header, payload);
}
public static DeskShareRTMPBroadcastStoppedEventMessage fromJson(String message) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
JsonObject payload = (JsonObject) obj.get("payload");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (DESKSHARE_RTMP_BROADCAST_STOPPED_MESSAGE.equals(messageName)) {
if (payload.has(CONFERENCE_NAME)
&& payload.has(TIMESTAMP)
&& payload.has(VIDEO_HEIGHT)
&& payload.has(VIDEO_WIDTH)
&& payload.has(STREAMNAME)) {
String conferenceName = payload.get(CONFERENCE_NAME).getAsString();
String streamname = payload.get(STREAMNAME).getAsString();
String timestamp = payload.get(TIMESTAMP).getAsString();
int vh = payload.get(VIDEO_HEIGHT).getAsInt();
int vw = payload.get(VIDEO_WIDTH).getAsInt();
return new DeskShareRTMPBroadcastStoppedEventMessage(conferenceName, streamname, vw, vh, timestamp);
}
}
}
}
return null;
}
}

View File

@ -0,0 +1,63 @@
package org.bigbluebutton.common.messages;
import java.util.HashMap;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class DeskShareStartRTMPBroadcastEventMessage {
public static final String DESKSHARE_START_RTMP_BROADCAST_MESSAGE = "deskshare_start_rtmp_broadcast_message";
public static final String VERSION = "0.0.1";
public static final String CONFERENCE_NAME = "conference_name";
public static final String STREAMURL = "stream_url";
public static final String TIMESTAMP = "timestamp";
public final String conferenceName;
public final String streamUrl;
public final String timestamp;
public DeskShareStartRTMPBroadcastEventMessage(String conferenceName, String streamUrl, String timestamp) {
this.conferenceName = conferenceName;
this.streamUrl = streamUrl;
this.timestamp = timestamp;
}
public String toJson() {
HashMap<String, Object> payload = new HashMap<String, Object>();
payload.put(CONFERENCE_NAME, conferenceName);
payload.put(STREAMURL, streamUrl);
payload.put(TIMESTAMP, timestamp);
java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(DESKSHARE_START_RTMP_BROADCAST_MESSAGE, VERSION, null);
return MessageBuilder.buildJson(header, payload);
}
public static DeskShareStartRTMPBroadcastEventMessage fromJson(String message) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
JsonObject payload = (JsonObject) obj.get("payload");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (DESKSHARE_START_RTMP_BROADCAST_MESSAGE.equals(messageName)) {
if (payload.has(CONFERENCE_NAME)
&& payload.has(TIMESTAMP)
&& payload.has(STREAMURL)) {
String conferenceName = payload.get(CONFERENCE_NAME).getAsString();
String streamUrl = payload.get(STREAMURL).getAsString();
String timestamp = payload.get(TIMESTAMP).getAsString();
return new DeskShareStartRTMPBroadcastEventMessage(conferenceName, streamUrl, timestamp);
}
}
}
}
return null;
}
}

View File

@ -0,0 +1,63 @@
package org.bigbluebutton.common.messages;
import java.util.HashMap;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
//Message from FreeSwitch to bbb-akka-apps
public class DeskShareStartedEventMessage {
public static final String DESKSHARE_STARTED_MESSAGE = "deskshare_start_message";
public static final String VERSION = "0.0.1";
public static final String CONFERENCE_NAME = "conference_name";
public static final String CALLER_ID = "caller_id";
public static final String CALLER_ID_NAME = "caller_id_name";
public final String conferenceName;
public final String callerId;
public final String callerIdName;
public DeskShareStartedEventMessage(String conferenceName, String callerId, String callerIdName) {
this.conferenceName = conferenceName;
this.callerId = callerId;
this.callerIdName = callerIdName;
}
public String toJson() {
HashMap<String, Object> payload = new HashMap<String, Object>();
payload.put(CONFERENCE_NAME, conferenceName);
payload.put(CALLER_ID_NAME, callerIdName);
payload.put(CALLER_ID, callerId);
java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(DESKSHARE_STARTED_MESSAGE, VERSION, null);
return MessageBuilder.buildJson(header, payload);
}
public static DeskShareStartedEventMessage fromJson(String message) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
JsonObject payload = (JsonObject) obj.get("payload");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (DESKSHARE_STARTED_MESSAGE.equals(messageName)) {
if (payload.has(CONFERENCE_NAME)
&& payload.has(CALLER_ID)
&& payload.has(CALLER_ID_NAME)) {
String conferenceName = payload.get(CONFERENCE_NAME).getAsString();
String callerId = payload.get(CALLER_ID_NAME).getAsString();
String callerIdName = payload.get(CALLER_ID_NAME).getAsString();
return new DeskShareStartedEventMessage(conferenceName, callerId, callerIdName);
}
}
}
}
return null;
}
}

View File

@ -0,0 +1,63 @@
package org.bigbluebutton.common.messages;
import java.util.HashMap;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class DeskShareStopRTMPBroadcastEventMessage {
public static final String DESKSHARE_STOP_RTMP_BROADCAST_MESSAGE = "deskshare_stop_rtmp_broadcast_message";
public static final String VERSION = "0.0.1";
public static final String CONFERENCE_NAME = "conference_name";
public static final String STREAMURL = "stream_url";
public static final String TIMESTAMP = "timestamp";
public final String conferenceName;
public final String streamUrl;
public final String timestamp;
public DeskShareStopRTMPBroadcastEventMessage(String conferenceName, String streamUrl, String timestamp) {
this.conferenceName = conferenceName;
this.streamUrl = streamUrl;
this.timestamp = timestamp;
}
public String toJson() {
HashMap<String, Object> payload = new HashMap<String, Object>();
payload.put(CONFERENCE_NAME, conferenceName);
payload.put(STREAMURL, streamUrl);
payload.put(TIMESTAMP, timestamp);
java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(DESKSHARE_STOP_RTMP_BROADCAST_MESSAGE, VERSION, null);
return MessageBuilder.buildJson(header, payload);
}
public static DeskShareStopRTMPBroadcastEventMessage fromJson(String message) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
JsonObject payload = (JsonObject) obj.get("payload");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (DESKSHARE_STOP_RTMP_BROADCAST_MESSAGE.equals(messageName)) {
if (payload.has(CONFERENCE_NAME)
&& payload.has(TIMESTAMP)
&& payload.has(STREAMURL)) {
String conferenceName = payload.get(CONFERENCE_NAME).getAsString();
String streamUrl = payload.get(STREAMURL).getAsString();
String timestamp = payload.get(TIMESTAMP).getAsString();
return new DeskShareStopRTMPBroadcastEventMessage(conferenceName, streamUrl, timestamp);
}
}
}
}
return null;
}
}

View File

@ -0,0 +1,63 @@
package org.bigbluebutton.common.messages;
import java.util.HashMap;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
//Message from FreeSwitch to bbb-akka-apps
public class DeskShareStoppedEventMessage {
public static final String DESK_SHARE_STOPPED_MESSAGE = "desk_share_stopped_message";
public static final String VERSION = "0.0.1";
public static final String CONFERENCE_NAME = "conference_name";
public static final String CALLER_ID = "caller_id";
public static final String CALLER_ID_NAME = "caller_id_name";
public final String conferenceName;
public final String callerId;
public final String callerIdName;
public DeskShareStoppedEventMessage(String conferenceName, String callerId, String callerIdName) {
this.conferenceName = conferenceName;
this.callerId = callerId;
this.callerIdName = callerIdName;
}
public String toJson() {
HashMap<String, Object> payload = new HashMap<String, Object>();
payload.put(CONFERENCE_NAME, conferenceName);
payload.put(CALLER_ID_NAME, callerIdName);
payload.put(CALLER_ID, callerId);
java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(DESK_SHARE_STOPPED_MESSAGE, VERSION, null);
return MessageBuilder.buildJson(header, payload);
}
public static DeskShareStoppedEventMessage fromJson(String message) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
JsonObject payload = (JsonObject) obj.get("payload");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (DESK_SHARE_STOPPED_MESSAGE.equals(messageName)) {
if (payload.has(CONFERENCE_NAME)
&& payload.has(CALLER_ID)
&& payload.has(CALLER_ID_NAME)) {
String conferenceName = payload.get(CONFERENCE_NAME).getAsString();
String callerId = payload.get(CALLER_ID_NAME).getAsString();
String callerIdName = payload.get(CALLER_ID_NAME).getAsString();
return new DeskShareStoppedEventMessage(conferenceName, callerId, callerIdName);
}
}
}
}
return null;
}
}

View File

@ -30,6 +30,7 @@ public class MessagingConstants {
public static final String FROM_CHAT_CHANNEL = FROM_BBB_APPS_CHANNEL + ":chat"; public static final String FROM_CHAT_CHANNEL = FROM_BBB_APPS_CHANNEL + ":chat";
public static final String FROM_WHITEBOARD_CHANNEL = FROM_BBB_APPS_CHANNEL + ":whiteboard"; public static final String FROM_WHITEBOARD_CHANNEL = FROM_BBB_APPS_CHANNEL + ":whiteboard";
public static final String FROM_CAPTION_CHANNEL = FROM_BBB_APPS_CHANNEL + ":caption"; public static final String FROM_CAPTION_CHANNEL = FROM_BBB_APPS_CHANNEL + ":caption";
public static final String FROM_DESK_SHARE_CHANNEL = FROM_BBB_APPS_CHANNEL + ":deskshare";
public static final String TO_BBB_APPS_CHANNEL = "bigbluebutton:to-bbb-apps"; public static final String TO_BBB_APPS_CHANNEL = "bigbluebutton:to-bbb-apps";
public static final String TO_BBB_APPS_PATTERN = TO_BBB_APPS_CHANNEL + ":*"; public static final String TO_BBB_APPS_PATTERN = TO_BBB_APPS_CHANNEL + ":*";
@ -45,6 +46,8 @@ public class MessagingConstants {
public static final String BBB_APPS_KEEP_ALIVE_CHANNEL = "bigbluebutton:from-bbb-apps:keepalive"; public static final String BBB_APPS_KEEP_ALIVE_CHANNEL = "bigbluebutton:from-bbb-apps:keepalive";
public static final String TO_BBB_HTML5_CHANNEL = "bigbluebutton:to-bbb-html5";
public static final String TO_VOICE_CONF_CHANNEL = "bigbluebutton:to-voice-conf"; public static final String TO_VOICE_CONF_CHANNEL = "bigbluebutton:to-voice-conf";
public static final String TO_VOICE_CONF_PATTERN = TO_VOICE_CONF_CHANNEL + ":*"; public static final String TO_VOICE_CONF_PATTERN = TO_VOICE_CONF_CHANNEL + ":*";
public static final String TO_VOICE_CONF_SYSTEM_CHAN = TO_VOICE_CONF_CHANNEL + ":system"; public static final String TO_VOICE_CONF_SYSTEM_CHAN = TO_VOICE_CONF_CHANNEL + ":system";

View File

@ -14,14 +14,16 @@ public class RegisterUserMessage implements IBigBlueButtonMessage {
public final String role; public final String role;
public final String externUserID; public final String externUserID;
public final String authToken; public final String authToken;
public final String avatarURL;
public RegisterUserMessage(String meetingID, String internalUserId, String fullname, String role, String externUserID, String authToken) { public RegisterUserMessage(String meetingID, String internalUserId, String fullname, String role, String externUserID, String authToken, String avatarURL) {
this.meetingID = meetingID; this.meetingID = meetingID;
this.internalUserId = internalUserId; this.internalUserId = internalUserId;
this.fullname = fullname; this.fullname = fullname;
this.role = role; this.role = role;
this.externUserID = externUserID; this.externUserID = externUserID;
this.authToken = authToken; this.authToken = authToken;
this.avatarURL = avatarURL;
} }
public String toJson() { public String toJson() {
@ -33,6 +35,7 @@ public class RegisterUserMessage implements IBigBlueButtonMessage {
payload.put(Constants.ROLE, role); payload.put(Constants.ROLE, role);
payload.put(Constants.EXT_USER_ID, externUserID); payload.put(Constants.EXT_USER_ID, externUserID);
payload.put(Constants.AUTH_TOKEN, authToken); payload.put(Constants.AUTH_TOKEN, authToken);
payload.put(Constants.AVATAR_URL, avatarURL);
java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(REGISTER_USER, VERSION, null); java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(REGISTER_USER, VERSION, null);
@ -60,9 +63,10 @@ public class RegisterUserMessage implements IBigBlueButtonMessage {
String role = payload.get(Constants.ROLE).getAsString(); String role = payload.get(Constants.ROLE).getAsString();
String externUserID = payload.get(Constants.EXT_USER_ID).getAsString(); String externUserID = payload.get(Constants.EXT_USER_ID).getAsString();
String authToken = payload.get(Constants.AUTH_TOKEN).getAsString(); String authToken = payload.get(Constants.AUTH_TOKEN).getAsString();
String avatarURL = payload.get(Constants.AVATAR_URL).getAsString();
//use externalUserId twice - once for external, once for internal //use externalUserId twice - once for external, once for internal
return new RegisterUserMessage(meetingID, externUserID, fullname, role, externUserID, authToken); return new RegisterUserMessage(meetingID, externUserID, fullname, role, externUserID, authToken, avatarURL);
} }
} }
} }

View File

@ -0,0 +1,74 @@
package org.bigbluebutton.common.messages;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class SendStunTurnInfoReplyMessage {
public static final String SEND_STUN_TURN_INFO_REPLY_MESSAGE = "send_stun_turn_info_reply_message";
public static final String VERSION = "0.0.1";
public final String meetingId;
public final String requesterId;
public final ArrayList<String> stuns;
public final ArrayList<Map<String, Object>> turns;
public SendStunTurnInfoReplyMessage(String meetingId, String requesterId, ArrayList<String> stuns,
ArrayList<Map<String, Object>> turns) {
this.meetingId = meetingId;
this.requesterId = requesterId;
this.stuns = stuns;
this.turns = turns;
}
public String toJson() {
HashMap<String, Object> payload = new HashMap<String, Object>();
payload.put(Constants.MEETING_ID, meetingId);
payload.put(Constants.REQUESTER_ID, requesterId);
payload.put(Constants.STUNS, stuns);
payload.put(Constants.TURNS, turns);
java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(SEND_STUN_TURN_INFO_REPLY_MESSAGE, VERSION, null);
return MessageBuilder.buildJson(header, payload);
}
public static SendStunTurnInfoReplyMessage fromJson(String message) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
JsonObject payload = (JsonObject) obj.get("payload");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (SEND_STUN_TURN_INFO_REPLY_MESSAGE.equals(messageName)) {
if (payload.has(Constants.MEETING_ID)
&& payload.has(Constants.STUNS)
&& payload.has(Constants.TURNS)
&& payload.has(Constants.REQUESTER_ID)) {
String meetingId = payload.get(Constants.MEETING_ID).getAsString();
String requesterId = payload.get(Constants.REQUESTER_ID).getAsString();
Util util = new Util();
JsonArray stunsArray = (JsonArray) payload.get(Constants.STUNS);
ArrayList<String> stunsArrayList = util.extractStuns(stunsArray);
JsonArray turnsArray = (JsonArray) payload.get(Constants.TURNS);
ArrayList<Map<String, Object>> turnsArrayList = util.extractTurns(turnsArray);
return new SendStunTurnInfoReplyMessage(meetingId, requesterId, stunsArrayList, turnsArrayList);
}
}
}
}
return null;
}
}

View File

@ -0,0 +1,58 @@
package org.bigbluebutton.common.messages;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.util.HashMap;
/**
* Created by anton on 05/02/16.
*/
public class SendStunTurnInfoRequestMessage {
public static final String SEND_STUN_TURN_INFO_REQUEST_MESSAGE = "send_stun_turn_info_request_message";
public static final String VERSION = "0.0.1";
public final String meetingId;
public final String requesterId;
public SendStunTurnInfoRequestMessage(String meetingId, String requesterId) {
this.meetingId = meetingId;
this.requesterId = requesterId;
}
public String toJson() {
HashMap<String, Object> payload = new HashMap<String, Object>();
payload.put(Constants.MEETING_ID, meetingId);
payload.put(Constants.REQUESTER_ID, requesterId);
java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(SEND_STUN_TURN_INFO_REQUEST_MESSAGE, VERSION, null);
return MessageBuilder.buildJson(header, payload);
}
public static SendStunTurnInfoRequestMessage fromJson(String message) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
JsonObject payload = (JsonObject) obj.get("payload");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (SEND_STUN_TURN_INFO_REQUEST_MESSAGE.equals(messageName)) {
if (payload.has(Constants.MEETING_ID)
&& payload.has(Constants.REQUESTER_ID)) {
String meetingId = payload.get(Constants.MEETING_ID).getAsString();
String requesterId = payload.get(Constants.REQUESTER_ID).getAsString();
return new SendStunTurnInfoRequestMessage(meetingId, requesterId);
}
}
}
}
return null;
}
}

View File

@ -16,6 +16,7 @@ public class UserJoinedVoiceConfMessage {
public static final String CALLER_ID_NUM = "caller_id_num"; public static final String CALLER_ID_NUM = "caller_id_num";
public static final String MUTED = "muted"; public static final String MUTED = "muted";
public static final String TALKING = "talking"; public static final String TALKING = "talking";
public static final String AVATAR_URL = "avatarURL";
public final String voiceConfId; public final String voiceConfId;
public final String voiceUserId; public final String voiceUserId;
@ -24,9 +25,10 @@ public class UserJoinedVoiceConfMessage {
public final String callerIdNum; public final String callerIdNum;
public final Boolean muted; public final Boolean muted;
public final Boolean talking; public final Boolean talking;
public final String avatarURL;
public UserJoinedVoiceConfMessage(String voiceConfId, String voiceUserId, String userId, public UserJoinedVoiceConfMessage(String voiceConfId, String voiceUserId, String userId,
String callerIdName, String callerIdNum, Boolean muted, Boolean talking) { String callerIdName, String callerIdNum, Boolean muted, Boolean talking, String avatarURL) {
this.voiceConfId = voiceConfId; this.voiceConfId = voiceConfId;
this.voiceUserId = voiceUserId; this.voiceUserId = voiceUserId;
this.userId = userId; this.userId = userId;
@ -34,6 +36,7 @@ public class UserJoinedVoiceConfMessage {
this.callerIdNum = callerIdNum; this.callerIdNum = callerIdNum;
this.muted = muted; this.muted = muted;
this.talking = talking; this.talking = talking;
this.avatarURL = avatarURL;
} }
public String toJson() { public String toJson() {
@ -45,6 +48,7 @@ public class UserJoinedVoiceConfMessage {
payload.put(CALLER_ID_NUM, callerIdNum); payload.put(CALLER_ID_NUM, callerIdNum);
payload.put(MUTED, muted); payload.put(MUTED, muted);
payload.put(TALKING, talking); payload.put(TALKING, talking);
payload.put(AVATAR_URL, avatarURL);
java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(USER_JOINED_VOICE_CONF, VERSION, null); java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(USER_JOINED_VOICE_CONF, VERSION, null);
@ -76,7 +80,8 @@ public class UserJoinedVoiceConfMessage {
String callerIdNum = payload.get(CALLER_ID_NUM).getAsString(); String callerIdNum = payload.get(CALLER_ID_NUM).getAsString();
Boolean muted = payload.get(MUTED).getAsBoolean(); Boolean muted = payload.get(MUTED).getAsBoolean();
Boolean talking = payload.get(TALKING).getAsBoolean(); Boolean talking = payload.get(TALKING).getAsBoolean();
return new UserJoinedVoiceConfMessage(voiceConfId, voiceUserId, userId, callerIdName, callerIdNum, muted, talking); String avatarURL = payload.get(AVATAR_URL).getAsString();
return new UserJoinedVoiceConfMessage(voiceConfId, voiceUserId, userId, callerIdName, callerIdNum, muted, talking, avatarURL);
} }
} }
} }

View File

@ -88,6 +88,7 @@ public class Util {
Boolean locked = user.get(Constants.LOCKED).getAsBoolean(); Boolean locked = user.get(Constants.LOCKED).getAsBoolean();
String extUserId = user.get(Constants.EXTERN_USERID).getAsString(); String extUserId = user.get(Constants.EXTERN_USERID).getAsString();
String role = user.get(Constants.ROLE).getAsString(); String role = user.get(Constants.ROLE).getAsString();
String avatarURL = user.get(Constants.AVATAR_URL).getAsString();
JsonArray webcamStreamJArray = user.get(Constants.WEBCAM_STREAM).getAsJsonArray(); JsonArray webcamStreamJArray = user.get(Constants.WEBCAM_STREAM).getAsJsonArray();
ArrayList<String> webcamStreams = extractWebcamStreams(webcamStreamJArray); ArrayList<String> webcamStreams = extractWebcamStreams(webcamStreamJArray);
@ -103,6 +104,7 @@ public class Util {
userMap.put("locked", locked); userMap.put("locked", locked);
userMap.put("role", role); userMap.put("role", role);
userMap.put("presenter", presenter); userMap.put("presenter", presenter);
userMap.put("avatarURL", avatarURL);
JsonObject vu = (JsonObject) user.get(Constants.VOICEUSER); JsonObject vu = (JsonObject) user.get(Constants.VOICEUSER);
@ -117,6 +119,52 @@ public class Util {
} }
public ArrayList<String> extractStuns(JsonArray stunsArray) {
ArrayList<String> collection = new ArrayList<String>();
Iterator<JsonElement> stunIter = stunsArray.iterator();
while (stunIter.hasNext()) {
JsonElement aStun = stunIter.next();
if (aStun != null) {
collection.add(aStun.getAsString());
}
}
return collection;
}
public ArrayList<Map<String, Object>> extractTurns(JsonArray turnsArray) {
ArrayList<Map<String, Object>> collection = new ArrayList<Map<String, Object>>();
Iterator<JsonElement> turnIter = turnsArray.iterator();
while (turnIter.hasNext()){
JsonElement aTurn = turnIter.next();
Map<String, Object> turnMap = extractATurn((JsonObject)aTurn);
if (turnMap != null) {
collection.add(turnMap);
}
}
return collection;
}
private Map<String,Object> extractATurn(JsonObject aTurn) {
if (aTurn.has(Constants.USERNAME)
&& aTurn.has(Constants.TTL)
&& aTurn.has(Constants.URL)
&& aTurn.has(Constants.PASSWORD)) {
Map<String, Object> turnMap = new HashMap<String, Object>();
turnMap.put(Constants.USERNAME, aTurn.get(Constants.USERNAME).getAsString());
turnMap.put(Constants.URL, aTurn.get(Constants.URL).getAsString());
turnMap.put(Constants.PASSWORD, aTurn.get(Constants.PASSWORD).getAsString());
turnMap.put(Constants.TTL, aTurn.get(Constants.TTL).getAsInt());
return turnMap;
}
return null;
}
public ArrayList<Map<String, Object>> extractChatHistory(JsonArray history) { public ArrayList<Map<String, Object>> extractChatHistory(JsonArray history) {
ArrayList<Map<String, Object>> collection = new ArrayList<Map<String, Object>>(); ArrayList<Map<String, Object>> collection = new ArrayList<Map<String, Object>>();
Iterator<JsonElement> historyIter = history.iterator(); Iterator<JsonElement> historyIter = history.iterator();
@ -637,7 +685,6 @@ public class Util {
return answerMap; return answerMap;
} }
public Map<String, Object> decodeSimplePollResult(JsonObject poll) { public Map<String, Object> decodeSimplePollResult(JsonObject poll) {
Map<String, Object> pollMap = new HashMap<String, Object>(); Map<String, Object> pollMap = new HashMap<String, Object>();

View File

@ -1,17 +1,14 @@
package org.bigbluebutton.core.service.whiteboard; package org.bigbluebutton.common.messages;
public class WhiteboardKeyUtil { public class WhiteboardKeyUtil {
public static final String TEXT_TYPE = "text"; public static final String TEXT_TYPE = "text";
public static final String PENCIL_TYPE = "pencil"; public static final String PENCIL_TYPE = "pencil";
public static final String RECTANGLE_TYPE = "rectangle"; public static final String RECTANGLE_TYPE = "rectangle";
public static final String ELLIPSE_TYPE = "ellipse"; public static final String ELLIPSE_TYPE = "ellipse";
public static final String TRIANGLE_TYPE = "triangle"; public static final String TRIANGLE_TYPE = "triangle";
public static final String LINE_TYPE = "line"; public static final String LINE_TYPE = "line";
public static final String POLL_RESULT_TYPE = "poll_result";
public static final String TEXT_CREATED_STATUS = "textCreated"; public static final String TEXT_CREATED_STATUS = "textCreated";
public static final String DRAW_START_STATUS = "DRAW_START"; public static final String DRAW_START_STATUS = "DRAW_START";
public static final String DRAW_END_STATUS = "DRAW_END"; public static final String DRAW_END_STATUS = "DRAW_END";
public static final String POLL_RESULT_TYPE = "poll_result";
} }

View File

@ -6,7 +6,7 @@ description := "BigBlueButton custom FS-ESL client built on top of FS-ESL Java l
organization := "org.bigbluebutton" organization := "org.bigbluebutton"
version := "0.0.3" version := "0.0.4"
// We want to have our jar files in lib_managed dir. // We want to have our jar files in lib_managed dir.
// This way we'll have the right path when we import // This way we'll have the right path when we import
@ -44,18 +44,15 @@ crossPaths := false
// This forbids including Scala related libraries into the dependency // This forbids including Scala related libraries into the dependency
autoScalaLibrary := false autoScalaLibrary := false
//publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath+"/.m2/repository"))) publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath+"/.m2/repository")))
//publishTo := {
publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath+"/dev/repo/maven-repo/releases" )) ) // val nexus = "https://oss.sonatype.org/"
// if (isSnapshot.value)
publishTo := { // Some("snapshots" at nexus + "content/repositories/snapshots")
val nexus = "https://oss.sonatype.org/" // else
if (isSnapshot.value) // Some("releases" at nexus + "service/local/staging/deploy/maven2")
Some("snapshots" at nexus + "content/repositories/snapshots") //}
else
Some("releases" at nexus + "service/local/staging/deploy/maven2")
}
// Enables publishing to maven repo // Enables publishing to maven repo

View File

@ -475,26 +475,21 @@ public class Client
System.out.println("##### Client member_add_file_data"); System.out.println("##### Client member_add_file_data");
listener.conferenceEventPlayFile(uniqueId, confName, confSize, event); listener.conferenceEventPlayFile(uniqueId, confName, confSize, event);
return; return;
//API has changed between freeswitch 1.4 and 1.6
} else if (eventFunc.equals("conf_api_sub_transfer") || eventFunc.equals("conference_api_sub_transfer")) { } else if (eventFunc.equals("conf_api_sub_transfer") || eventFunc.equals("conference_api_sub_transfer")) {
//Member transfered to another conf... //Member transfered to another conf...
listener.conferenceEventTransfer(uniqueId, confName, confSize, event); listener.conferenceEventTransfer(uniqueId, confName, confSize, event);
return; return;
//API has changed between freeswitch 1.4 and 1.6
} else if (eventFunc.equals("conference_add_member") || eventFunc.equals("conference_member_add")) { } else if (eventFunc.equals("conference_add_member") || eventFunc.equals("conference_member_add")) {
System.out.println("##### Client conference_add_member"); System.out.println("##### Client conference_add_member");
listener.conferenceEventJoin(uniqueId, confName, confSize, event); listener.conferenceEventJoin(uniqueId, confName, confSize, event);
return; return;
//API has changed between freeswitch 1.4 and 1.6
} else if (eventFunc.equals("conference_del_member") || eventFunc.equals("conference_member_del")) { } else if (eventFunc.equals("conference_del_member") || eventFunc.equals("conference_member_del")) {
System.out.println("##### Client conference_del_member"); System.out.println("##### Client conference_del_member");
listener.conferenceEventLeave(uniqueId, confName, confSize, event); listener.conferenceEventLeave(uniqueId, confName, confSize, event);
return; return;
//API has changed between freeswitch 1.4 and 1.6
} else if (eventFunc.equals("conf_api_sub_mute") || eventFunc.equals("conference_api_sub_mute")) { } else if (eventFunc.equals("conf_api_sub_mute") || eventFunc.equals("conference_api_sub_mute")) {
listener.conferenceEventMute(uniqueId, confName, confSize, event); listener.conferenceEventMute(uniqueId, confName, confSize, event);
return; return;
//API has changed between freeswitch 1.4 and 1.6
} else if (eventFunc.equals("conf_api_sub_unmute") || eventFunc.equals("conference_api_sub_unmute")) { } else if (eventFunc.equals("conf_api_sub_unmute") || eventFunc.equals("conference_api_sub_unmute")) {
listener.conferenceEventUnMute(uniqueId, confName, confSize, event); listener.conferenceEventUnMute(uniqueId, confName, confSize, event);
return; return;

View File

@ -179,7 +179,11 @@ public class VideoApplication extends MultiThreadedApplicationAdapter {
String meetingId = conn.getScope().getName(); String meetingId = conn.getScope().getName();
String streamId = stream.getPublishedName(); String streamId = stream.getPublishedName();
publisher.userSharedWebcamMessage(meetingId, userId, streamId); //publisher.userSharedWebcamMessage(meetingId, userId, streamId);
log.info("^^^^^^^^^^^publisher.userSharedWebcamMessage(meetingId, userId, streamId);");
VideoStreamListener listener = new VideoStreamListener(conn.getScope(), stream, recordVideoStream, userId, packetTimeout); VideoStreamListener listener = new VideoStreamListener(conn.getScope(), stream, recordVideoStream, userId, packetTimeout);
listener.setEventRecordingService(recordingService); listener.setEventRecordingService(recordingService);
stream.addStreamListener(listener); stream.addStreamListener(listener);
@ -212,7 +216,10 @@ public class VideoApplication extends MultiThreadedApplicationAdapter {
String meetingId = conn.getScope().getName(); String meetingId = conn.getScope().getName();
String streamId = stream.getPublishedName(); String streamId = stream.getPublishedName();
publisher.userUnshareWebcamRequestMessage(meetingId, userId, streamId); //publisher.userUnshareWebcamRequestMessage(meetingId, userId, streamId);
log.info("^^^^^^^^^^^publisher.userUnshareWebcamRequestMessage(meetingId, userId, streamId);");
IStreamListener listener = streamListeners.remove(scopeName + "-" + stream.getPublishedName()); IStreamListener listener = streamListeners.remove(scopeName + "-" + stream.getPublishedName());
if (listener != null) { if (listener != null) {

File diff suppressed because one or more lines are too long

View File

@ -1,75 +0,0 @@
format version: 5
output mode:
1 items
0 -> multiple
output directories:
2 items
D:\bbb\bigbluebutton-apps\src\test\resources -> D:\bbb\bigbluebutton-apps\bin
D:\bbb\bigbluebutton-apps\src\test\scala -> D:\bbb\bigbluebutton-apps\bin
compile options:
8 items
0 -> -javabootclasspath
1 -> C:\Program Files\Java\jdk1.7.0_80\jre\lib\resources.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\rt.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\jce.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\zipfs.jar
2 -> -javaextdirs
3 ->
4 -> -bootclasspath
5 -> D:\Ghazi\Softs\eclipse-scala\plugins\org.scala-lang.scala-library_2.11.7.v20150622-112736-1fbce4612c.jar
6 -> -encoding
7 -> UTF-8
javac options:
0 items
compiler version:
1 items
0 -> 2.11.7
compile order:
1 items
0 -> Mixed
name hashing:
1 items
0 -> false
products:
0 items
binary dependencies:
0 items
direct source dependencies:
0 items
direct external dependencies:
0 items
public inherited source dependencies:
0 items
public inherited external dependencies:
0 items
member reference internal dependencies:
0 items
member reference external dependencies:
0 items
inheritance internal dependencies:
0 items
inheritance external dependencies:
0 items
class names:
0 items
used names:
0 items
product stamps:
0 items
source stamps:
1 items
D:\bbb\bigbluebutton-apps\src\test\scala\org\bigbluebutton\core\apps\poll\PollTestHelper.scala -> hash(7d7b5b5d738db53e715d04615c5f0f6889a87ca1)
binary stamps:
0 items
class names:
0 items
internal apis:
1 items
D:\bbb\bigbluebutton-apps\src\test\scala\org\bigbluebutton\core\apps\poll\PollTestHelper.scala ->
rO0ABXNyABB4c2J0aS5hcGkuU291cmNlFlpwRASfbtoCAAZJAAdhcGlIYXNoWgAIaGFzTWFjcm9MABhfaW50ZXJuYWxPbmx5X25hbWVIYXNoZXN0ACRMeHNidGkvYXBpL19pbnRlcm5hbE9ubHlfTmFtZUhhc2hlcztMAANhcGl0ABVMeHNidGkvYXBpL1NvdXJjZUFQSTtMAAtjb21waWxhdGlvbnQAF0x4c2J0aS9hcGkvQ29tcGlsYXRpb247WwAEaGFzaHQAAltCeHAMaZ2IAHNyACJ4c2J0aS5hcGkuX2ludGVybmFsT25seV9OYW1lSGFzaGVzVNq+mfrU7EwCAAJbAA9pbXBsaWNpdE1lbWJlcnN0ACNbTHhzYnRpL2FwaS9faW50ZXJuYWxPbmx5X05hbWVIYXNoO1sADnJlZ3VsYXJNZW1iZXJzcQB+AAd4cHVyACNbTHhzYnRpLmFwaS5faW50ZXJuYWxPbmx5X05hbWVIYXNoO0lagLbdlov0AgAAeHAAAAAAdXEAfgAJAAAAAHNyABN4c2J0aS5hcGkuU291cmNlQVBJuV6n+SkjOKQCAAJbAAtkZWZpbml0aW9uc3QAF1tMeHNidGkvYXBpL0RlZmluaXRpb247WwAIcGFja2FnZXN0ABRbTHhzYnRpL2FwaS9QYWNrYWdlO3hwdXIAF1tMeHNidGkuYXBpLkRlZmluaXRpb247iMlc57TjXg4CAAB4cAAAAAB1cgAUW0x4c2J0aS5hcGkuUGFja2FnZTtbExk3cKcnoQIAAHhwAAAABXNyABF4c2J0aS5hcGkuUGFja2FnZX5Zj/auzjlYAgABTAAEbmFtZXQAEkxqYXZhL2xhbmcvU3RyaW5nO3hwdAAWb3JnLmJpZ2JsdWVidXR0b24uY29yZXNxAH4AFHQAEW9yZy5iaWdibHVlYnV0dG9uc3EAfgAUdAAbb3JnLmJpZ2JsdWVidXR0b24uY29yZS5hcHBzc3EAfgAUdAAgb3JnLmJpZ2JsdWVidXR0b24uY29yZS5hcHBzLnBvbGxzcQB+ABR0AANvcmdzcgAVeHNidGkuYXBpLkNvbXBpbGF0aW9u7frgw2rooEICAAJKAAlzdGFydFRpbWVbAAdvdXRwdXRzdAAaW0x4c2J0aS9hcGkvT3V0cHV0U2V0dGluZzt4cAAAAVLvfQ9fdXIAGltMeHNidGkuYXBpLk91dHB1dFNldHRpbmc7f2rC86eHpUICAAB4cAAAAAJzcgAXeHNidGkuYXBpLk91dHB1dFNldHRpbmd62ZpHdPsdewIAAkwAD291dHB1dERpcmVjdG9yeXEAfgAVTAAPc291cmNlRGlyZWN0b3J5cQB+ABV4cHQAHUQ6XGJiYlxiaWdibHVlYnV0dG9uLWFwcHNcYmludAAoRDpcYmJiXGJpZ2JsdWVidXR0b24tYXBwc1xzcmNcdGVzdFxzY2FsYXNxAH4AJXQAHUQ6XGJiYlxiaWdibHVlYnV0dG9uLWFwcHNcYmludAAsRDpcYmJiXGJpZ2JsdWVidXR0b24tYXBwc1xzcmNcdGVzdFxyZXNvdXJjZXN1cgACW0Ks8xf4BghU4AIAAHhwAAAAFH17W11zjbU+cV0EYVxfD2iJqHyh
external apis:
0 items
source infos:
1 items
D:\bbb\bigbluebutton-apps\src\test\scala\org\bigbluebutton\core\apps\poll\PollTestHelper.scala ->
AAAAAAAAAAA=
compilations:
1 items
0 -> rO0ABXNyABV4c2J0aS5hcGkuQ29tcGlsYXRpb27t+uDDauigQgIAAkoACXN0YXJ0VGltZVsAB291dHB1dHN0ABpbTHhzYnRpL2FwaS9PdXRwdXRTZXR0aW5nO3hwAAABUu99D191cgAaW0x4c2J0aS5hcGkuT3V0cHV0U2V0dGluZzt/asLzp4elQgIAAHhwAAAAAnNyABd4c2J0aS5hcGkuT3V0cHV0U2V0dGluZ3rZmkd0+x17AgACTAAPb3V0cHV0RGlyZWN0b3J5dAASTGphdmEvbGFuZy9TdHJpbmc7TAAPc291cmNlRGlyZWN0b3J5cQB+AAZ4cHQAHUQ6XGJiYlxiaWdibHVlYnV0dG9uLWFwcHNcYmludAAoRDpcYmJiXGJpZ2JsdWVidXR0b24tYXBwc1xzcmNcdGVzdFxzY2FsYXNxAH4ABXQAHUQ6XGJiYlxiaWdibHVlYnV0dG9uLWFwcHNcYmludAAsRDpcYmJiXGJpZ2JsdWVidXR0b24tYXBwc1xzcmNcdGVzdFxyZXNvdXJjZXM=

View File

@ -72,7 +72,7 @@ dependencies {
compile 'com.google.code.gson:gson:2.5' compile 'com.google.code.gson:gson:2.5'
providedCompile 'org.apache.commons:commons-lang3:3.2' providedCompile 'org.apache.commons:commons-lang3:3.2'
compile 'org.bigbluebutton:bbb-common-message:0.0.17-SNAPSHOT' compile 'org.bigbluebutton:bbb-common-message:0.0.18-SNAPSHOT'
} }
test { test {

View File

@ -0,0 +1,85 @@
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.red5.client.messaging.BroadcastClientMessage;
import org.bigbluebutton.red5.client.messaging.DirectClientMessage;
import org.bigbluebutton.red5.client.messaging.ConnectionInvokerService;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class DeskShareMessageSender {
private ConnectionInvokerService service;
public DeskShareMessageSender(ConnectionInvokerService service) {
this.service = service;
}
public void handleDeskShareMessage(String message) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
switch (messageName) {
case DeskShareNotifyViewersRTMPEventMessage.DESK_SHARE_NOTIFY_VIEWERS_RTMP:
DeskShareNotifyViewersRTMPEventMessage rtmp = DeskShareNotifyViewersRTMPEventMessage.fromJson(message);
if (rtmp != null) {
processDeskShareNotifyViewersRTMPEventMessage(rtmp);
}
break;
case DeskShareNotifyASingleViewerEventMessage.DESK_SHARE_NOTIFY_A_SINGLE_VIEWER:
DeskShareNotifyASingleViewerEventMessage singleViewerMsg = DeskShareNotifyASingleViewerEventMessage.fromJson(message);
if (singleViewerMsg != null) {
processDeskShareNotifyASingleViewerEventMessage(singleViewerMsg);
}
}
}
}
}
private void processDeskShareNotifyViewersRTMPEventMessage(DeskShareNotifyViewersRTMPEventMessage msg) {
Map<String, Object> messageInfo = new HashMap<String, Object>();
// split the string streamPath if there are params in the format:
// {channels=2,samplerate=48000,vw=1920,vh=1080,fps=5.00}rtmp://192.168.23.3/video-broadcast/.../..."
String fullPathString = msg.streamPath;
String delims = "[,{}]+";
String[] arr = fullPathString.split(delims);
String rtmpStreamPath = arr[arr.length -1];
messageInfo.put("rtmpUrl", rtmpStreamPath);
messageInfo.put("broadcasting", msg.broadcasting);
messageInfo.put("width", msg.vw);
messageInfo.put("height", msg.vh);
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "DeskShareRTMPBroadcastNotification", messageInfo);
service.sendMessage(m);
}
private void processDeskShareNotifyASingleViewerEventMessage(DeskShareNotifyASingleViewerEventMessage msg) {
Map<String, Object> messageInfo = new HashMap<String, Object>();
messageInfo.put("rtmpUrl", msg.streamPath);
messageInfo.put("broadcasting", msg.broadcasting);
messageInfo.put("width", msg.vw);
messageInfo.put("height", msg.vh);
String toUserId = msg.userId;
DirectClientMessage receiver = new DirectClientMessage(msg.meetingId, toUserId,
"DeskShareRTMPBroadcastNotification", messageInfo);
service.sendMessage(receiver);
}
}

View File

@ -233,6 +233,10 @@ public class MessagePublisher {
sender.send(MessagingConstants.TO_CHAT_CHANNEL, msg.toJson()); sender.send(MessagingConstants.TO_CHAT_CHANNEL, msg.toJson());
} }
public void requestDeskShareInfo(String meetingID, String requesterID, String replyTo) {
DeskShareGetInfoRequestMessage msg = new DeskShareGetInfoRequestMessage(meetingID, requesterID, replyTo);
sender.send(MessagingConstants.FROM_VOICE_CONF_SYSTEM_CHAN, msg.toJson());
}
public void sendWhiteboardAnnotation(String meetingID, String requesterID, Map<String, Object> annotation) { public void sendWhiteboardAnnotation(String meetingID, String requesterID, Map<String, Object> annotation) {
SendWhiteboardAnnotationRequestMessage msg = new SendWhiteboardAnnotationRequestMessage(meetingID, requesterID, annotation); SendWhiteboardAnnotationRequestMessage msg = new SendWhiteboardAnnotationRequestMessage(meetingID, requesterID, annotation);
sender.send(MessagingConstants.TO_WHITEBOARD_CHANNEL, msg.toJson()); sender.send(MessagingConstants.TO_WHITEBOARD_CHANNEL, msg.toJson());

View File

@ -8,10 +8,14 @@ import org.bigbluebutton.red5.client.UserClientMessageSender;
import org.bigbluebutton.red5.client.ChatClientMessageSender; import org.bigbluebutton.red5.client.ChatClientMessageSender;
import org.bigbluebutton.red5.client.WhiteboardClientMessageSender; import org.bigbluebutton.red5.client.WhiteboardClientMessageSender;
import org.bigbluebutton.red5.client.CaptionClientMessageSender; import org.bigbluebutton.red5.client.CaptionClientMessageSender;
import org.bigbluebutton.red5.client.DeskShareMessageSender;
import org.bigbluebutton.red5.client.messaging.ConnectionInvokerService; import org.bigbluebutton.red5.client.messaging.ConnectionInvokerService;
import org.bigbluebutton.red5.monitoring.BbbAppsIsKeepAliveHandler; import org.bigbluebutton.red5.monitoring.BbbAppsIsKeepAliveHandler;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
public class RedisPubSubMessageHandler implements MessageHandler { public class RedisPubSubMessageHandler implements MessageHandler {
private static Logger log = Red5LoggerFactory.getLogger(RedisPubSubMessageHandler.class, "bigbluebutton");
private ConnectionInvokerService service; private ConnectionInvokerService service;
private UserClientMessageSender userMessageSender; private UserClientMessageSender userMessageSender;
@ -19,6 +23,7 @@ public class RedisPubSubMessageHandler implements MessageHandler {
private ChatClientMessageSender chatMessageSender; private ChatClientMessageSender chatMessageSender;
private PresentationClientMessageSender presentationMessageSender; private PresentationClientMessageSender presentationMessageSender;
private WhiteboardClientMessageSender whiteboardMessageSender; private WhiteboardClientMessageSender whiteboardMessageSender;
private DeskShareMessageSender deskShareMessageSender;
private BbbAppsIsKeepAliveHandler bbbAppsIsKeepAliveHandler; private BbbAppsIsKeepAliveHandler bbbAppsIsKeepAliveHandler;
private PollingClientMessageSender pollingMessageSender; private PollingClientMessageSender pollingMessageSender;
private CaptionClientMessageSender captionMessageSender; private CaptionClientMessageSender captionMessageSender;
@ -30,6 +35,7 @@ public class RedisPubSubMessageHandler implements MessageHandler {
chatMessageSender = new ChatClientMessageSender(service); chatMessageSender = new ChatClientMessageSender(service);
presentationMessageSender = new PresentationClientMessageSender(service); presentationMessageSender = new PresentationClientMessageSender(service);
whiteboardMessageSender = new WhiteboardClientMessageSender(service); whiteboardMessageSender = new WhiteboardClientMessageSender(service);
deskShareMessageSender = new DeskShareMessageSender(service);
pollingMessageSender = new PollingClientMessageSender(service); pollingMessageSender = new PollingClientMessageSender(service);
captionMessageSender = new CaptionClientMessageSender(service); captionMessageSender = new CaptionClientMessageSender(service);
} }
@ -40,6 +46,7 @@ public class RedisPubSubMessageHandler implements MessageHandler {
@Override @Override
public void handleMessage(String pattern, String channel, String message) { public void handleMessage(String pattern, String channel, String message) {
// System.out.println("in red5 getting message: " + channel + " " + message);
if (channel.equalsIgnoreCase(MessagingConstants.FROM_CHAT_CHANNEL)) { if (channel.equalsIgnoreCase(MessagingConstants.FROM_CHAT_CHANNEL)) {
chatMessageSender.handleChatMessage(message); chatMessageSender.handleChatMessage(message);
} else if (channel.equalsIgnoreCase(MessagingConstants.FROM_PRESENTATION_CHANNEL)) { } else if (channel.equalsIgnoreCase(MessagingConstants.FROM_PRESENTATION_CHANNEL)) {
@ -47,11 +54,14 @@ public class RedisPubSubMessageHandler implements MessageHandler {
} else if (channel.equalsIgnoreCase(MessagingConstants.FROM_MEETING_CHANNEL)) { } else if (channel.equalsIgnoreCase(MessagingConstants.FROM_MEETING_CHANNEL)) {
meetingMessageSender.handleMeetingMessage(message); meetingMessageSender.handleMeetingMessage(message);
} else if (channel.equalsIgnoreCase(MessagingConstants.FROM_USERS_CHANNEL)) { } else if (channel.equalsIgnoreCase(MessagingConstants.FROM_USERS_CHANNEL)) {
log.info("trace 0 : " + message);
userMessageSender.handleUsersMessage(message); userMessageSender.handleUsersMessage(message);
} else if (channel.equalsIgnoreCase(MessagingConstants.FROM_WHITEBOARD_CHANNEL)) { } else if (channel.equalsIgnoreCase(MessagingConstants.FROM_WHITEBOARD_CHANNEL)) {
whiteboardMessageSender.handleWhiteboardMessage(message); whiteboardMessageSender.handleWhiteboardMessage(message);
} else if (channel.equalsIgnoreCase(MessagingConstants.FROM_SYSTEM_CHANNEL)) { } else if (channel.equalsIgnoreCase(MessagingConstants.FROM_SYSTEM_CHANNEL)) {
bbbAppsIsKeepAliveHandler.handleKeepAliveMessage(message); bbbAppsIsKeepAliveHandler.handleKeepAliveMessage(message);
} else if (channel.equalsIgnoreCase(MessagingConstants.FROM_DESK_SHARE_CHANNEL)) {
deskShareMessageSender.handleDeskShareMessage(message);
} else if (channel.equalsIgnoreCase(MessagingConstants.FROM_POLLING_CHANNEL)) { } else if (channel.equalsIgnoreCase(MessagingConstants.FROM_POLLING_CHANNEL)) {
pollingMessageSender.handlePollMessage(message); pollingMessageSender.handlePollMessage(message);
} else if (channel.equalsIgnoreCase(MessagingConstants.FROM_CAPTION_CHANNEL)) { } else if (channel.equalsIgnoreCase(MessagingConstants.FROM_CAPTION_CHANNEL)) {

View File

@ -0,0 +1,53 @@
/**
* 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.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;
import org.red5.logging.Red5LoggerFactory;
import org.red5.server.api.Red5;
import org.slf4j.Logger;
public class DesktopSharingService {
private static Logger log = Red5LoggerFactory.getLogger( DesktopSharingService.class, "bigbluebutton" );
private MessagePublisher red5BBBInGw;
private BigBlueButtonSession getBbbSession() {
return (BigBlueButtonSession) Red5.getConnectionLocal().getAttribute(Constants.SESSION);
}
public void setRed5Publisher(MessagePublisher inGW) {
red5BBBInGw = inGW;
}
public void requestDeskShareInfo() {
String meetingID = Red5.getConnectionLocal().getScope().getName();
String requesterID = getBbbSession().getInternalUserID();
// Just hardcode as we don't really need it for flash client.
String replyTo = meetingID + "/" + requesterID;
System.out.println("\nDESKTOP SHARING SERVICE _ on the way to bbb-core\n");
red5BBBInGw.requestDeskShareInfo(meetingID, requesterID, replyTo);
}
}

View File

@ -1,16 +0,0 @@
package org.bigbluebutton.red5.service;
public class WhiteboardKeyUtil {
public static final String TEXT_TYPE = "text";
public static final String PENCIL_TYPE = "pencil";
public static final String RECTANGLE_TYPE = "rectangle";
public static final String ELLIPSE_TYPE = "ellipse";
public static final String TRIANGLE_TYPE = "triangle";
public static final String LINE_TYPE = "line";
public static final String TEXT_CREATED_STATUS = "textCreated";
public static final String DRAW_START_STATUS = "DRAW_START";
public static final String DRAW_END_STATUS = "DRAW_END";
}

View File

@ -63,6 +63,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<property name="red5Publisher"> <ref bean="red5Publisher"/></property> <property name="red5Publisher"> <ref bean="red5Publisher"/></property>
</bean> </bean>
<bean id="desktopSharing.service" class="org.bigbluebutton.red5.service.DesktopSharingService">
<property name="red5Publisher"><ref bean="red5Publisher"/></property>
</bean>
<bean id="lock.service" class="org.bigbluebutton.red5.service.LockService"> <bean id="lock.service" class="org.bigbluebutton.red5.service.LockService">
<property name="red5Publisher"><ref bean="red5Publisher"/></property> <property name="red5Publisher"><ref bean="red5Publisher"/></property>
</bean> </bean>

View File

@ -141,7 +141,7 @@
</sequential> </sequential>
</target> </target>
<target name="locale"> <target name="localize">
<compileLocale locale="${LOCALE}" /> <compileLocale locale="${LOCALE}" />
</target> </target>
@ -444,8 +444,8 @@
<copy file="${PROD_RESOURCES_DIR}/BigBlueButtonTest.html" todir="${OUTPUT_DIR}" overwrite="true"/> <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}/BigBlueButton.html" todir="${OUTPUT_DIR}" overwrite="true"/>
<copy file="${PROD_RESOURCES_DIR}/DeskshareStandalone.html" todir="${OUTPUT_DIR}" overwrite="true"/> <copy file="${PROD_RESOURCES_DIR}/DeskshareStandalone.html" todir="${OUTPUT_DIR}" overwrite="true"/>
<copy file="${PROD_RESOURCES_DIR}/bbb.gif" todir="${OUTPUT_DIR}" overwrite="true"/>
<copy file="${PROD_RESOURCES_DIR}/get_flash_player.gif" 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"/> <copy file="${PROD_RESOURCES_DIR}/avatar.png" todir="${OUTPUT_DIR}" overwrite="true"/>
<copy file="${PROD_RESOURCES_DIR}/locales.xml" todir="${OUTPUT_DIR}/conf" overwrite="true"/> <copy file="${PROD_RESOURCES_DIR}/locales.xml" todir="${OUTPUT_DIR}/conf" overwrite="true"/>
<copy file="${PROD_RESOURCES_DIR}/expressInstall.swf" todir="${OUTPUT_DIR}" overwrite="true"/> <copy file="${PROD_RESOURCES_DIR}/expressInstall.swf" todir="${OUTPUT_DIR}" overwrite="true"/>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@ bbb.mainshell.locale.version = 0.9.0
bbb.mainshell.statusProgress.connecting = Свързване със сървъра bbb.mainshell.statusProgress.connecting = Свързване със сървъра
bbb.mainshell.statusProgress.loading = Зареждане на {0} модул/а bbb.mainshell.statusProgress.loading = Зареждане на {0} модул/а
bbb.mainshell.statusProgress.cannotConnectServer = Съжалявамe, не можем да се свържем със сървъра. bbb.mainshell.statusProgress.cannotConnectServer = Съжалявамe, не можем да се свържем със сървъра.
# bbb.mainshell.copyrightLabel2 = (c) 2016 <a href\='event\:http\://www.bigbluebutton.org/' target\='_blank'><u>BigBlueButton Inc.</u></a> (build {0}) bbb.mainshell.copyrightLabel2 = (c) 2016 <a href\='event\:http\://www.bigbluebutton.org/' target\='_blank'><u>BigBlueButton Inc.</u></a> (build {0})
bbb.mainshell.logBtn.toolTip = Отвори Дневник Прозорецът bbb.mainshell.logBtn.toolTip = Отвори Дневник Прозорецът
bbb.mainshell.meetingNotFound = Сесията не бе намерена bbb.mainshell.meetingNotFound = Сесията не бе намерена
bbb.mainshell.invalidAuthToken = Невалиден активационен код bbb.mainshell.invalidAuthToken = Невалиден активационен код
@ -43,7 +43,7 @@ bbb.micSettings.cancel = Отмени
bbb.micSettings.connectingtoecho = Свързване bbb.micSettings.connectingtoecho = Свързване
bbb.micSettings.connectingtoecho.error = Изпробването на аудиото се провали. Потърсете помощ от техник bbb.micSettings.connectingtoecho.error = Изпробването на аудиото се провали. Потърсете помощ от техник
bbb.micSettings.cancel.toolTip = Отмени присъединяването към разговора bbb.micSettings.cancel.toolTip = Отмени присъединяването към разговора
bbb.micSettings.access.helpButton = За обучителни видео материали, щракнете тук. Ще бъде отворена нова страница. bbb.micSettings.access.helpButton = Help (open tutorial videos in new page)
bbb.micSettings.access.title = Аудио настройки. Фокусът ще остане в този прозорец за аудио настройки, докато прозорецът се затвори. bbb.micSettings.access.title = Аудио настройки. Фокусът ще остане в този прозорец за аудио настройки, докато прозорецът се затвори.
bbb.micSettings.webrtc.title = Поддръжка на WebRTC bbb.micSettings.webrtc.title = Поддръжка на WebRTC
bbb.micSettings.webrtc.capableBrowser = Вашият браузър поддържа WebRTC. bbb.micSettings.webrtc.capableBrowser = Вашият браузър поддържа WebRTC.
@ -52,7 +52,7 @@ bbb.micSettings.webrtc.capableBrowser.dontuseit.toolTip = Моля натисн
bbb.micSettings.webrtc.notCapableBrowser = Вашият браузър не поддържа WebRTC. Моля използвайте Google Chrome (версия 32 или по-скорошна); или Mozilla Firefox (версия 26 или по-скорошна). Все пак ще можете да се включите в разговора чрез Adobe Flash Platform. bbb.micSettings.webrtc.notCapableBrowser = Вашият браузър не поддържа WebRTC. Моля използвайте Google Chrome (версия 32 или по-скорошна); или Mozilla Firefox (версия 26 или по-скорошна). Все пак ще можете да се включите в разговора чрез Adobe Flash Platform.
bbb.micSettings.webrtc.connecting = Обаждане bbb.micSettings.webrtc.connecting = Обаждане
bbb.micSettings.webrtc.waitingforice = Свързване bbb.micSettings.webrtc.waitingforice = Свързване
# bbb.micSettings.webrtc.transferring = Transferring bbb.micSettings.webrtc.transferring = Transferring
bbb.micSettings.webrtc.endingecho = Свързване към аудиото bbb.micSettings.webrtc.endingecho = Свързване към аудиото
bbb.micSettings.webrtc.endedecho = Изпробването на аудиото приключи. bbb.micSettings.webrtc.endedecho = Изпробването на аудиото приключи.
bbb.micPermissions.firefox.title = Разрешения за микрофон под Firefox bbb.micPermissions.firefox.title = Разрешения за микрофон под Firefox
@ -69,20 +69,20 @@ bbb.webrtcWarning.title = WebRTC Аудио проблем
bbb.webrtcWarning.failedError.1001 = Грешка 1001\: Връзката с WebSocket е прекъсната. bbb.webrtcWarning.failedError.1001 = Грешка 1001\: Връзката с WebSocket е прекъсната.
bbb.webrtcWarning.failedError.1002 = Грешка 1002\: Не може да се осъществи връзка с WebSocket. bbb.webrtcWarning.failedError.1002 = Грешка 1002\: Не може да се осъществи връзка с WebSocket.
bbb.webrtcWarning.failedError.1003 = Грешка 1003\: Версията на браузъра не е поддържана. bbb.webrtcWarning.failedError.1003 = Грешка 1003\: Версията на браузъра не е поддържана.
# bbb.webrtcWarning.failedError.1004 = Error 1004\: Failure on call (reason\={0}) bbb.webrtcWarning.failedError.1004 = Error 1004\: Failure on call (reason\={0})
bbb.webrtcWarning.failedError.1005 = Грешка 1005\: Повикването завърши неочаквано. bbb.webrtcWarning.failedError.1005 = Грешка 1005\: Повикването завърши неочаквано.
# bbb.webrtcWarning.failedError.1006 = Error 1006\: Call timed out bbb.webrtcWarning.failedError.1006 = Error 1006\: Call timed out
# bbb.webrtcWarning.failedError.1007 = Error 1007\: ICE negotiation failed bbb.webrtcWarning.failedError.1007 = Error 1007\: ICE negotiation failed
# bbb.webrtcWarning.failedError.1008 = Error 1008\: Transfer failed bbb.webrtcWarning.failedError.1008 = Error 1008\: Transfer failed
# bbb.webrtcWarning.failedError.1009 = Error 1009\: Could not fetch STUN/TURN server information bbb.webrtcWarning.failedError.1009 = Error 1009\: Could not fetch STUN/TURN server information
# bbb.webrtcWarning.failedError.1010 = Error 1010\: ICE negotiation timeout bbb.webrtcWarning.failedError.1010 = Error 1010\: ICE negotiation timeout
# bbb.webrtcWarning.failedError.1011 = Error 1011\: ICE gathering timeout bbb.webrtcWarning.failedError.1011 = Error 1011\: ICE gathering timeout
bbb.webrtcWarning.failedError.unknown = \ Грешка {0}\: Непознат код на грешка. bbb.webrtcWarning.failedError.unknown = \ Грешка {0}\: Непознат код на грешка.
# bbb.webrtcWarning.failedError.mediamissing = Could not get your microphone for a WebRTC call bbb.webrtcWarning.failedError.mediamissing = Could not get your microphone for a WebRTC call
# bbb.webrtcWarning.failedError.endedunexpectedly = The WebRTC echo test ended unexpectedly bbb.webrtcWarning.failedError.endedunexpectedly = The WebRTC echo test ended unexpectedly
# bbb.webrtcWarning.connection.dropped = WebRTC connection dropped bbb.webrtcWarning.connection.dropped = WebRTC connection dropped
# bbb.webrtcWarning.connection.reconnecting = Attempting to reconnect bbb.webrtcWarning.connection.reconnecting = Attempting to reconnect
# bbb.webrtcWarning.connection.reestablished = WebRTC connection re-established bbb.webrtcWarning.connection.reestablished = WebRTC connection re-established
bbb.mainToolbar.helpBtn = Помощ bbb.mainToolbar.helpBtn = Помощ
bbb.mainToolbar.logoutBtn = Изход bbb.mainToolbar.logoutBtn = Изход
bbb.mainToolbar.logoutBtn.toolTip = Изход bbb.mainToolbar.logoutBtn.toolTip = Изход
@ -105,19 +105,19 @@ bbb.mainToolbar.recordingLabel.recording = (Записва се)
bbb.mainToolbar.recordingLabel.notRecording = Не се записва bbb.mainToolbar.recordingLabel.notRecording = Не се записва
bbb.clientstatus.title = Настройки на известията bbb.clientstatus.title = Настройки на известията
bbb.clientstatus.notification = Непрочетени известия bbb.clientstatus.notification = Непрочетени известия
# bbb.clientstatus.close = Close bbb.clientstatus.close = Close
# bbb.clientstatus.tunneling.title = Firewall bbb.clientstatus.tunneling.title = Firewall
# bbb.clientstatus.tunneling.message = A firewall is preventing your client from connecting directly on port 1935 to the remote server. Recommend joining a less restrictive network for a more stable connection bbb.clientstatus.tunneling.message = A firewall is preventing your client from connecting directly on port 1935 to the remote server. Recommend joining a less restrictive network for a more stable connection
# bbb.clientstatus.browser.title = Browser Version bbb.clientstatus.browser.title = Browser Version
# bbb.clientstatus.browser.message = Your browser ({0}) is not up-to-date. Recommend updating to the latest version. bbb.clientstatus.browser.message = Your browser ({0}) is not up-to-date. Recommend updating to the latest version.
bbb.clientstatus.flash.title = Флаш плейър bbb.clientstatus.flash.title = Флаш плейър
# bbb.clientstatus.flash.message = Your Flash Player plugin ({0}) is out-of-date. Recommend updating to the latest version. bbb.clientstatus.flash.message = Your Flash Player plugin ({0}) is out-of-date. Recommend updating to the latest version.
bbb.clientstatus.webrtc.title = Аудио bbb.clientstatus.webrtc.title = Аудио
bbb.clientstatus.webrtc.message = За по-добър звук, моля използвайте браузър Firefox или Chrome. bbb.clientstatus.webrtc.message = За по-добър звук, моля използвайте браузър Firefox или Chrome.
# bbb.clientstatus.java.title = Java bbb.clientstatus.java.title = Java
# bbb.clientstatus.java.notdetected = Java version not detected. 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.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.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 = Минимизирай bbb.window.minimizeBtn.toolTip = Минимизирай
bbb.window.maximizeRestoreBtn.toolTip = Увеличи bbb.window.maximizeRestoreBtn.toolTip = Увеличи
bbb.window.closeBtn.toolTip = Затвори bbb.window.closeBtn.toolTip = Затвори
@ -135,8 +135,8 @@ bbb.users.settings.webcamSettings = Настройки на камерата
bbb.users.settings.muteAll = Заглушете всички bbb.users.settings.muteAll = Заглушете всички
bbb.users.settings.muteAllExcept = Заглушете всички с изключение на лектора bbb.users.settings.muteAllExcept = Заглушете всички с изключение на лектора
bbb.users.settings.unmuteAll = Позволете на всички да говорят bbb.users.settings.unmuteAll = Позволете на всички да говорят
# bbb.users.settings.clearAllStatus = Clear all status icons bbb.users.settings.clearAllStatus = Clear all status icons
# bbb.users.emojiStatusBtn.toolTip = Update my status icon bbb.users.emojiStatusBtn.toolTip = Update my status icon
bbb.users.roomMuted.text = Потребителите не могат да говорят bbb.users.roomMuted.text = Потребителите не могат да говорят
bbb.users.roomLocked.text = Потребителите са заключени bbb.users.roomLocked.text = Потребителите са заключени
bbb.users.pushToTalk.toolTip = Щракнете, за да говорите bbb.users.pushToTalk.toolTip = Щракнете, за да говорите
@ -145,7 +145,7 @@ bbb.users.muteMeBtnTxt.talk = Позволете говор
bbb.users.muteMeBtnTxt.mute = Заглушете bbb.users.muteMeBtnTxt.mute = Заглушете
bbb.users.muteMeBtnTxt.muted = Заглушен bbb.users.muteMeBtnTxt.muted = Заглушен
bbb.users.muteMeBtnTxt.unmuted = Позволен да говори bbb.users.muteMeBtnTxt.unmuted = Позволен да говори
# bbb.users.usersGrid.contextmenu.exportusers = Copy User Names bbb.users.usersGrid.contextmenu.exportusers = Copy User Names
bbb.users.usersGrid.accessibilityName = Потребителски списък. Използвайте клавишите със стрелки, за да навигирате. bbb.users.usersGrid.accessibilityName = Потребителски списък. Използвайте клавишите със стрелки, за да навигирате.
bbb.users.usersGrid.nameItemRenderer = Име bbb.users.usersGrid.nameItemRenderer = Име
bbb.users.usersGrid.nameItemRenderer.youIdentifier = Вие bbb.users.usersGrid.nameItemRenderer.youIdentifier = Вие
@ -153,10 +153,10 @@ bbb.users.usersGrid.statusItemRenderer = Статус
bbb.users.usersGrid.statusItemRenderer.changePresenter = Натиснете тук за да презентирате bbb.users.usersGrid.statusItemRenderer.changePresenter = Натиснете тук за да презентирате
bbb.users.usersGrid.statusItemRenderer.presenter = Лектор bbb.users.usersGrid.statusItemRenderer.presenter = Лектор
bbb.users.usersGrid.statusItemRenderer.moderator = Модератор bbb.users.usersGrid.statusItemRenderer.moderator = Модератор
# bbb.users.usersGrid.statusItemRenderer.clearStatus = Clear status bbb.users.usersGrid.statusItemRenderer.clearStatus = Clear status
bbb.users.usersGrid.statusItemRenderer.viewer = Наблюдаващ bbb.users.usersGrid.statusItemRenderer.viewer = Наблюдаващ
# bbb.users.usersGrid.statusItemRenderer.streamIcon.toolTip = Sharing webcam. bbb.users.usersGrid.statusItemRenderer.streamIcon.toolTip = Sharing webcam.
# bbb.users.usersGrid.statusItemRenderer.presIcon.toolTip = Is Presenter. bbb.users.usersGrid.statusItemRenderer.presIcon.toolTip = Is Presenter.
bbb.users.usersGrid.mediaItemRenderer = Медия bbb.users.usersGrid.mediaItemRenderer = Медия
bbb.users.usersGrid.mediaItemRenderer.talking = Говорене bbb.users.usersGrid.mediaItemRenderer.talking = Говорене
bbb.users.usersGrid.mediaItemRenderer.webcam = Споделена камера bbb.users.usersGrid.mediaItemRenderer.webcam = Споделена камера
@ -170,17 +170,17 @@ bbb.users.usersGrid.mediaItemRenderer.webcam = Споделена камера
bbb.users.usersGrid.mediaItemRenderer.micOff = Изкл. микрофон bbb.users.usersGrid.mediaItemRenderer.micOff = Изкл. микрофон
bbb.users.usersGrid.mediaItemRenderer.micOn = Вкл. микрофон bbb.users.usersGrid.mediaItemRenderer.micOn = Вкл. микрофон
bbb.users.usersGrid.mediaItemRenderer.noAudio = Не е аудио конференция bbb.users.usersGrid.mediaItemRenderer.noAudio = Не е аудио конференция
# bbb.users.emojiStatus.clear = Clear bbb.users.emojiStatus.clear = Clear
# bbb.users.emojiStatus.clear.toolTip = Clear status bbb.users.emojiStatus.clear.toolTip = Clear status
# bbb.users.emojiStatus.close = Close bbb.users.emojiStatus.close = Close
# bbb.users.emojiStatus.close.toolTip = Close status popup bbb.users.emojiStatus.close.toolTip = Close status popup
# bbb.users.emojiStatus.raiseHand = Raise hand status bbb.users.emojiStatus.raiseHand = Raise hand status
# bbb.users.emojiStatus.happy = Happy status bbb.users.emojiStatus.happy = Happy status
# bbb.users.emojiStatus.smile = Smile status bbb.users.emojiStatus.smile = Smile status
# bbb.users.emojiStatus.sad = Sad status bbb.users.emojiStatus.sad = Sad status
# bbb.users.emojiStatus.confused = Confused status bbb.users.emojiStatus.confused = Confused status
# bbb.users.emojiStatus.neutral = Neutral status bbb.users.emojiStatus.neutral = Neutral status
# bbb.users.emojiStatus.away = Away status bbb.users.emojiStatus.away = Away status
bbb.presentation.title = Презентация bbb.presentation.title = Презентация
bbb.presentation.titleWithPres = Презентация\: {0} bbb.presentation.titleWithPres = Презентация\: {0}
bbb.presentation.quickLink.label = Прозорец за презентацията bbb.presentation.quickLink.label = Прозорец за презентацията
@ -196,7 +196,7 @@ bbb.presentation.uploadcomplete = Качването завърши. Моля,
bbb.presentation.uploaded = качено. bbb.presentation.uploaded = качено.
bbb.presentation.document.supported = Каченият документ се поддържа. Започва конвертиране... bbb.presentation.document.supported = Каченият документ се поддържа. Започва конвертиране...
bbb.presentation.document.converted = Успешно конвертиране на офис документа. bbb.presentation.document.converted = Успешно конвертиране на офис документа.
# bbb.presentation.error.document.convert.failed = Error\: Unable to convert the office document. bbb.presentation.error.document.convert.failed = Error\: Unable to convert the office document.
bbb.presentation.error.io = IO Грешка\: Моля, свържете се с администратор. bbb.presentation.error.io = IO Грешка\: Моля, свържете се с администратор.
bbb.presentation.error.security = Грешка в сигурността\: Моля, свържете се с администратор. bbb.presentation.error.security = Грешка в сигурността\: Моля, свържете се с администратор.
bbb.presentation.error.convert.notsupported = Грешка\: Каченият документ не се поддържа. Моля, заредете съвместим файл. bbb.presentation.error.convert.notsupported = Грешка\: Каченият документ не се поддържа. Моля, заредете съвместим файл.
@ -242,9 +242,10 @@ bbb.chat.publicChatUsername = Всички
bbb.chat.optionsTabName = Настройки bbb.chat.optionsTabName = Настройки
bbb.chat.privateChatSelect = Прозорец Чат Избери лице за персонален чат bbb.chat.privateChatSelect = Прозорец Чат Избери лице за персонален чат
bbb.chat.private.userLeft = Потребителят е напуснал. bbb.chat.private.userLeft = Потребителят е напуснал.
# bbb.chat.private.userJoined = The user has joined. bbb.chat.private.userJoined = The user has joined.
# bbb.chat.usersList.toolTip = Select User To Open Private Chat bbb.chat.private.closeMessage = You can close this tab by using the key combination {0}.
# bbb.chat.usersList.accessibilityName = Select user to open private chat. Use the arrow keys to navigate. bbb.chat.usersList.toolTip = Select User To Open Private Chat
bbb.chat.usersList.accessibilityName = Select user to open private chat. Use the arrow keys to navigate.
bbb.chat.chatOptions = Прозорец Чат Чат опции bbb.chat.chatOptions = Прозорец Чат Чат опции
bbb.chat.fontSize = Прозорец Чат Големина на шрифта bbb.chat.fontSize = Прозорец Чат Големина на шрифта
bbb.chat.cmbFontSize.toolTip = Изберете размер на шрифта на чата bbb.chat.cmbFontSize.toolTip = Изберете размер на шрифта на чата
@ -253,14 +254,14 @@ bbb.chat.minimizeBtn.accessibilityName = Минимизирайте прозор
bbb.chat.maximizeRestoreBtn.accessibilityName = Максимизирайте прозорец Чат bbb.chat.maximizeRestoreBtn.accessibilityName = Максимизирайте прозорец Чат
bbb.chat.closeBtn.accessibilityName = Затворете прозорец Чат bbb.chat.closeBtn.accessibilityName = Затворете прозорец Чат
bbb.chat.chatTabs.accessibleNotice = Новите съобщения се показват тук. bbb.chat.chatTabs.accessibleNotice = Новите съобщения се показват тук.
# bbb.chat.chatMessage.systemMessage = System bbb.chat.chatMessage.systemMessage = System
# bbb.chat.chatMessage.tooLong = The message is {0} character(s) too long bbb.chat.chatMessage.tooLong = The message is {0} character(s) too long
bbb.publishVideo.changeCameraBtn.labelText = Смяна на камерата bbb.publishVideo.changeCameraBtn.labelText = Смяна на камерата
bbb.publishVideo.changeCameraBtn.toolTip = Прозорец за избиране на видео камера bbb.publishVideo.changeCameraBtn.toolTip = Прозорец за избиране на видео камера
bbb.publishVideo.cmbResolution.tooltip = Избери резолюция на камерата bbb.publishVideo.cmbResolution.tooltip = Избери резолюция на камерата
bbb.publishVideo.startPublishBtn.labelText = Стартиране на споделянето bbb.publishVideo.startPublishBtn.labelText = Стартиране на споделянето
bbb.publishVideo.startPublishBtn.toolTip = Започни споделяне bbb.publishVideo.startPublishBtn.toolTip = Започни споделяне
# bbb.publishVideo.startPublishBtn.errorName = Can't share webcam. Reason\: {0} bbb.publishVideo.startPublishBtn.errorName = Can't share webcam. Reason\: {0}
bbb.webcamPermissions.chrome.title = Разрешения за камера под Chrome bbb.webcamPermissions.chrome.title = Разрешения за камера под Chrome
bbb.webcamPermissions.chrome.message1 = Натиснете за да позволите на Chrome да използва вашата камера bbb.webcamPermissions.chrome.message1 = Натиснете за да позволите на Chrome да използва вашата камера
bbb.videodock.title = Закачи видео bbb.videodock.title = Закачи видео
@ -277,12 +278,12 @@ bbb.video.publish.hint.waitingApproval = Изчакване за одобрен
bbb.video.publish.hint.videoPreview = Преглед на видео bbb.video.publish.hint.videoPreview = Преглед на видео
bbb.video.publish.hint.openingCamera = Отваряне на камера... bbb.video.publish.hint.openingCamera = Отваряне на камера...
bbb.video.publish.hint.cameraDenied = Няма достъп до камерата bbb.video.publish.hint.cameraDenied = Няма достъп до камерата
# bbb.video.publish.hint.cameraIsBeingUsed = Your webcam couldn't be opened - it may be under use by another application bbb.video.publish.hint.cameraIsBeingUsed = Your webcam couldn't be opened - it may be under use by another application
bbb.video.publish.hint.publishing = Публикуване... bbb.video.publish.hint.publishing = Публикуване...
bbb.video.publish.closeBtn.accessName = Прозорец Уебкамера Затвори прозорец bbb.video.publish.closeBtn.accessName = Прозорец Уебкамера Затвори прозорец
bbb.video.publish.closeBtn.label = Отмени bbb.video.publish.closeBtn.label = Отмени
bbb.video.publish.titleBar = Прозорец Публикуване на камера bbb.video.publish.titleBar = Прозорец Публикуване на камера
# bbb.video.streamClose.toolTip = Close stream for\: {0} bbb.video.streamClose.toolTip = Close stream for\: {0}
bbb.desktopPublish.title = Споделяне на екрана\: Представяне на Презентатора bbb.desktopPublish.title = Споделяне на екрана\: Представяне на Презентатора
bbb.desktopPublish.fullscreen.tooltip = Споделете екрана си bbb.desktopPublish.fullscreen.tooltip = Споделете екрана си
bbb.desktopPublish.fullscreen.label = На цял екран bbb.desktopPublish.fullscreen.label = На цял екран
@ -292,15 +293,15 @@ bbb.desktopPublish.stop.tooltip = Затвори екрана за сподел
bbb.desktopPublish.stop.label = Затвори bbb.desktopPublish.stop.label = Затвори
bbb.desktopPublish.maximizeRestoreBtn.toolTip = Вие не можете да разширите този прозорец. bbb.desktopPublish.maximizeRestoreBtn.toolTip = Вие не можете да разширите този прозорец.
bbb.desktopPublish.closeBtn.toolTip = Спиране на споделянето и затваряне bbb.desktopPublish.closeBtn.toolTip = Спиране на споделянето и затваряне
# 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.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.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.edgePluginUnsupportedHint = Edge does not support Java Applets. You must use a different web browser (Firefox recommended) to share your desktop.
bbb.desktopPublish.minimizeBtn.toolTip = Минимизиране bbb.desktopPublish.minimizeBtn.toolTip = Минимизиране
bbb.desktopPublish.minimizeBtn.accessibilityName = Минимизиране на прозореца Публикуване на споделен екран bbb.desktopPublish.minimizeBtn.accessibilityName = Минимизиране на прозореца Публикуване на споделен екран
bbb.desktopPublish.maximizeRestoreBtn.accessibilityName = Увеличи прозорец Публикуване на споделен екран bbb.desktopPublish.maximizeRestoreBtn.accessibilityName = Увеличи прозорец Публикуване на споделен екран
# bbb.desktopPublish.chromeHint.title = Chrome may need your permission. 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.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.desktopPublish.chromeHint.button = Retry
bbb.desktopView.title = Споделяне на екрана bbb.desktopView.title = Споделяне на екрана
bbb.desktopView.fitToWindow = Вмести в прозореца bbb.desktopView.fitToWindow = Вмести в прозореца
bbb.desktopView.actualSize = Покажи в реален размер bbb.desktopView.actualSize = Покажи в реален размер
@ -328,11 +329,11 @@ bbb.layout.combo.customName = Потребителски изглед
bbb.layout.combo.remote = Отдалечен bbb.layout.combo.remote = Отдалечен
bbb.layout.save.complete = Изгледите бяха успешно съхранени bbb.layout.save.complete = Изгледите бяха успешно съхранени
bbb.layout.load.complete = Изгледите бяха успешно заредени bbb.layout.load.complete = Изгледите бяха успешно заредени
# bbb.layout.load.failed = Unable to load the layouts bbb.layout.load.failed = Unable to load the layouts
bbb.layout.name.defaultlayout = Стандартен изглед bbb.layout.name.defaultlayout = Стандартен изглед
bbb.layout.name.videochat = Видео Чат bbb.layout.name.videochat = Видео Чат
# bbb.layout.name.webcamsfocus = Webcam Meeting bbb.layout.name.webcamsfocus = Webcam Meeting
# bbb.layout.name.presentfocus = Presentation Meeting bbb.layout.name.presentfocus = Presentation Meeting
bbb.layout.name.lectureassistant = Асистент bbb.layout.name.lectureassistant = Асистент
bbb.layout.name.lecture = Лекция bbb.layout.name.lecture = Лекция
bbb.highlighter.toolbar.pencil = Молив bbb.highlighter.toolbar.pencil = Молив
@ -356,25 +357,25 @@ bbb.logout.button.label = ДА
bbb.logout.appshutdown = Приложението на сървъра беше спряно bbb.logout.appshutdown = Приложението на сървъра беше спряно
bbb.logout.asyncerror = Възникнала е асинхронна грешка bbb.logout.asyncerror = Възникнала е асинхронна грешка
bbb.logout.connectionclosed = Връзката със сървъра е била затворена bbb.logout.connectionclosed = Връзката със сървъра е била затворена
# bbb.logout.connectionfailed = The connection to the server has ended bbb.logout.connectionfailed = The connection to the server has ended
bbb.logout.rejected = Връзката до сървъра беше отказана bbb.logout.rejected = Връзката до сървъра беше отказана
bbb.logout.invalidapp = Приложението red5 не съществува bbb.logout.invalidapp = Приложението red5 не съществува
bbb.logout.unknown = Вашият клиент е загубил връзка със сървъра bbb.logout.unknown = Вашият клиент е загубил връзка със сървъра
bbb.logout.usercommand = Вие сте излезли от конференцията bbb.logout.usercommand = Вие сте излезли от конференцията
# bbb.logout.ejectedFromMeeting = A moderator has kicked you out of the meeting. bbb.logout.ejectedFromMeeting = A moderator has kicked you out of the meeting.
bbb.logout.refresh.message = Ако изходът от системата е неочакван, натиснете бутона по-долу, за да се свържете повторно. bbb.logout.refresh.message = Ако изходът от системата е неочакван, натиснете бутона по-долу, за да се свържете повторно.
bbb.logout.refresh.label = Повторно свързване bbb.logout.refresh.label = Повторно свързване
bbb.logout.confirm.title = Потвърдете, че искате да напуснете bbb.logout.confirm.title = Потвърдете, че искате да напуснете
bbb.logout.confirm.message = Сигурни ли сте, че искате да напуснете? bbb.logout.confirm.message = Сигурни ли сте, че искате да напуснете?
bbb.logout.confirm.yes = Да bbb.logout.confirm.yes = Да
bbb.logout.confirm.no = Не bbb.logout.confirm.no = Не
# bbb.connection.failure=Detected Connectivity Problems bbb.connection.failure=Detected Connectivity Problems
# bbb.connection.reconnecting=Reconnecting bbb.connection.reconnecting=Reconnecting
# bbb.connection.reestablished=Connection reestablished bbb.connection.reestablished=Connection reestablished
# bbb.connection.bigbluebutton=BigBlueButton bbb.connection.bigbluebutton=BigBlueButton
# bbb.connection.sip=SIP bbb.connection.sip=SIP
# bbb.connection.video=Video bbb.connection.video=Video
# bbb.connection.deskshare=Deskshare bbb.connection.deskshare=Deskshare
bbb.notes.title = Бележки bbb.notes.title = Бележки
bbb.notes.cmpColorPicker.toolTip = Цвят на текста bbb.notes.cmpColorPicker.toolTip = Цвят на текста
bbb.notes.saveBtn = Съхрани bbb.notes.saveBtn = Съхрани
@ -404,7 +405,7 @@ ltbcustom.bbb.highlighter.toolbar.text.accessibilityName = Превключи о
ltbcustom.bbb.highlighter.texttoolbar.textColorPicker = Цвят на текст ltbcustom.bbb.highlighter.texttoolbar.textColorPicker = Цвят на текст
ltbcustom.bbb.highlighter.texttoolbar.textSizeMenu = Размер на шрифта ltbcustom.bbb.highlighter.texttoolbar.textSizeMenu = Размер на шрифта
# bbb.accessibility.clientReady = Ready bbb.accessibility.clientReady = Ready
bbb.accessibility.chat.chatBox.reachedFirst = Достигнали сте до първото съобщение. bbb.accessibility.chat.chatBox.reachedFirst = Достигнали сте до първото съобщение.
bbb.accessibility.chat.chatBox.reachedLatest = Достигнали сте до последното съобщение. bbb.accessibility.chat.chatBox.reachedLatest = Достигнали сте до последното съобщение.
@ -412,7 +413,7 @@ bbb.accessibility.chat.chatBox.navigatedFirst = Преминали сте на
bbb.accessibility.chat.chatBox.navigatedLatest = Преминали сте към най-последното съобщение. bbb.accessibility.chat.chatBox.navigatedLatest = Преминали сте към най-последното съобщение.
bbb.accessibility.chat.chatBox.navigatedLatestRead = Преминали сте към оследното съобщение, което сте чели. bbb.accessibility.chat.chatBox.navigatedLatestRead = Преминали сте към оследното съобщение, което сте чели.
bbb.accessibility.chat.chatwindow.input = Въвеждане в чата bbb.accessibility.chat.chatwindow.input = Въвеждане в чата
# bbb.accessibility.chat.chatwindow.audibleChatNotification = Audible Chat Notification bbb.accessibility.chat.chatwindow.audibleChatNotification = Audible Chat Notification
bbb.accessibility.chat.initialDescription = Моля използвайте стрелките на клавиатурата за навигация в съобщенията bbb.accessibility.chat.initialDescription = Моля използвайте стрелките на клавиатурата за навигация в съобщенията
@ -504,8 +505,8 @@ bbb.shortcutkey.chat.changeColour = 67
bbb.shortcutkey.chat.changeColour.function = Превключи към палитрата. bbb.shortcutkey.chat.changeColour.function = Превключи към палитрата.
bbb.shortcutkey.chat.sendMessage = 83 bbb.shortcutkey.chat.sendMessage = 83
bbb.shortcutkey.chat.sendMessage.function = Изпрати съобщение bbb.shortcutkey.chat.sendMessage.function = Изпрати съобщение
# bbb.shortcutkey.chat.closePrivate = 69 bbb.shortcutkey.chat.closePrivate = 69
# bbb.shortcutkey.chat.closePrivate.function = Close private chat tab bbb.shortcutkey.chat.closePrivate.function = Close private chat tab
bbb.shortcutkey.chat.explanation = ---- bbb.shortcutkey.chat.explanation = ----
bbb.shortcutkey.chat.explanation.function = За навигиране на съобщения, трябва да фокусирате върху чат кутията. bbb.shortcutkey.chat.explanation.function = За навигиране на съобщения, трябва да фокусирате върху чат кутията.
@ -524,28 +525,28 @@ bbb.shortcutkey.chat.chatbox.goread.function = Преминете към пос
bbb.shortcutkey.chat.chatbox.debug = 71 bbb.shortcutkey.chat.chatbox.debug = 71
bbb.shortcutkey.chat.chatbox.debug.function = Временна дебъг клавишна комбинация bbb.shortcutkey.chat.chatbox.debug.function = Временна дебъг клавишна комбинация
# bbb.polling.startButton.tooltip = Start a poll bbb.polling.startButton.tooltip = Start a poll
# bbb.polling.startButton.label = Start Poll bbb.polling.startButton.label = Start Poll
bbb.polling.publishButton.label = Публикувай bbb.polling.publishButton.label = Публикувай
bbb.polling.closeButton.label = Затвори bbb.polling.closeButton.label = Затвори
# bbb.polling.pollModal.title = Live Poll Results bbb.polling.pollModal.title = Live Poll Results
# bbb.polling.customChoices.title = Enter Polling Choices bbb.polling.customChoices.title = Enter Polling Choices
# bbb.polling.respondersLabel.novotes = Waiting for responses bbb.polling.respondersLabel.novotes = Waiting for responses
# bbb.polling.respondersLabel.text = {0} Users Responded bbb.polling.respondersLabel.text = {0} Users Responded
# bbb.polling.respondersLabel.finished = Done bbb.polling.respondersLabel.finished = Done
bbb.polling.answer.Yes = Да bbb.polling.answer.Yes = Да
bbb.polling.answer.No = Не bbb.polling.answer.No = Не
# bbb.polling.answer.True = True bbb.polling.answer.True = True
# bbb.polling.answer.False = False bbb.polling.answer.False = False
# bbb.polling.answer.A = A bbb.polling.answer.A = A
# bbb.polling.answer.B = B bbb.polling.answer.B = B
# bbb.polling.answer.C = C bbb.polling.answer.C = C
# bbb.polling.answer.D = D bbb.polling.answer.D = D
# bbb.polling.answer.E = E bbb.polling.answer.E = E
# bbb.polling.answer.F = F bbb.polling.answer.F = F
# bbb.polling.answer.G = G bbb.polling.answer.G = G
# bbb.polling.results.accessible.header = Poll Results. bbb.polling.results.accessible.header = Poll Results.
# bbb.polling.results.accessible.answer = Answer {0} had {1} votes. bbb.polling.results.accessible.answer = Answer {0} had {1} votes.
bbb.publishVideo.startPublishBtn.labelText = Стартиране на споделянето bbb.publishVideo.startPublishBtn.labelText = Стартиране на споделянето
bbb.publishVideo.changeCameraBtn.labelText = Смяна на камерата bbb.publishVideo.changeCameraBtn.labelText = Смяна на камерата
@ -582,5 +583,5 @@ bbb.lockSettings.microphone = Микрофон
bbb.lockSettings.layout = Изглед bbb.lockSettings.layout = Изглед
bbb.lockSettings.title=Заключи потребителите bbb.lockSettings.title=Заключи потребителите
bbb.lockSettings.feature=Функционалност bbb.lockSettings.feature=Функционалност
# bbb.lockSettings.locked=Locked bbb.lockSettings.locked=Locked
# bbb.lockSettings.lockOnJoin=Lock On Join bbb.lockSettings.lockOnJoin=Lock On Join

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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