diff --git a/akka-bbb-apps/.gitignore b/akka-bbb-apps/.gitignore index 1c0e395724135e398ce522ad03e88032ccb35e76..28cb15fcec03a6eafbc82ad4629c20f49812d088 100644 --- a/akka-bbb-apps/.gitignore +++ b/akka-bbb-apps/.gitignore @@ -47,3 +47,5 @@ akka-patterns-store/ lib_managed/ .cache bin/ +src/main/resources/ + diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala index da8d9d6290c5619b560514ff14c47892819e2569..78288fbcab5bbea300d4c46b48bba2f8a8c22dfb 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala @@ -148,6 +148,8 @@ class ReceivedJsonMsgHandlerActor( routeGenericMsg[MuteMeetingCmdMsg](envelope, jsonNode) case IsMeetingMutedReqMsg.NAME => routeGenericMsg[IsMeetingMutedReqMsg](envelope, jsonNode) + case CheckRunningAndRecordingVoiceConfEvtMsg.NAME => + routeVoiceMsg[CheckRunningAndRecordingVoiceConfEvtMsg](envelope, jsonNode) // Breakout rooms case BreakoutRoomsListMsg.NAME => diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala index 526e831e2313473dfeb486583eb0cb9f1d74cafd..d31ffee05308ceffdc05a0e6c2f7f571b5a0459d 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala @@ -376,10 +376,12 @@ class MeetingActor( case m: UserConnectedToGlobalAudioMsg => handleUserConnectedToGlobalAudioMsg(m) case m: UserDisconnectedFromGlobalAudioMsg => handleUserDisconnectedFromGlobalAudioMsg(m) case m: VoiceConfRunningEvtMsg => handleVoiceConfRunningEvtMsg(m) + case m: CheckRunningAndRecordingVoiceConfEvtMsg => + handleCheckRunningAndRecordingVoiceConfEvtMsg(m) // Layout - case m: GetCurrentLayoutReqMsg => handleGetCurrentLayoutReqMsg(m) - case m: BroadcastLayoutMsg => handleBroadcastLayoutMsg(m) + case m: GetCurrentLayoutReqMsg => handleGetCurrentLayoutReqMsg(m) + case m: BroadcastLayoutMsg => handleBroadcastLayoutMsg(m) // Lock Settings case m: ChangeLockSettingsInMeetingCmdMsg => @@ -532,12 +534,28 @@ class MeetingActor( sendRttTraceTest() setRecordingChapterBreak() + checkVoiceConfIsRunningAndRecording() processUserInactivityAudit() flagRegisteredUsersWhoHasNotJoined() checkIfNeetToEndMeetingWhenNoAuthedUsers(liveMeeting) } + var lastVoiceRecordingAndRunningCheck = System.currentTimeMillis() + def checkVoiceConfIsRunningAndRecording(): Unit = { + val now = System.currentTimeMillis() + val elapsedTime = now - lastVoiceRecordingAndRunningCheck; + val timeToCheck = elapsedTime > 30000 // 30seconds + if (props.recordProp.record && timeToCheck) { + lastVoiceRecordingAndRunningCheck = now + val event = MsgBuilder.buildCheckRunningAndRecordingToVoiceConfSysMsg( + props.meetingProp.intId, + props.voiceProp.voiceConf + ) + outGW.send(event) + } + } + var lastRecBreakSentOn = expiryTracker.startedOnInMs def setRecordingChapterBreak(): Unit = { @@ -707,4 +725,21 @@ class MeetingActor( } } } + + def handleCheckRunningAndRecordingVoiceConfEvtMsg(msg: CheckRunningAndRecordingVoiceConfEvtMsg): Unit = { + if (liveMeeting.props.recordProp.record && + msg.body.isRunning && + !msg.body.isRecording) { + // Voice conference is running but not recording. We should start recording. + // But first, see if we have recording streams and stop those. + VoiceApp.stopRecordingVoiceConference(liveMeeting, outGW) + + // Let us start recording. + val meetingId = liveMeeting.props.meetingProp.intId + val recordFile = VoiceApp.genRecordPath(voiceConfRecordPath, meetingId, TimeUtil.timeNowInMs()) + log.info("Forcing START RECORDING voice conf. meetingId=" + meetingId + " voice conf=" + liveMeeting.props.voiceProp.voiceConf) + + VoiceApp.startRecordingVoiceConference(liveMeeting, outGW, recordFile) + } + } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/AnalyticsActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/AnalyticsActor.scala index 6d3b2587fba42e5baa29410fb1b58d3c208ca2bb..a975d0560a7b2bc10f248ed5167d113d5e703842 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/AnalyticsActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/AnalyticsActor.scala @@ -123,6 +123,10 @@ class AnalyticsActor extends Actor with ActorLogging { // Recording case m: RecordingChapterBreakSysMsg => logMessage(msg) + case m: VoiceRecordingStartedEvtMsg => logMessage(msg) + case m: VoiceRecordingStoppedEvtMsgBody => logMessage(msg) + //case m: CheckRunningAndRecordingToVoiceConfSysMsg => logMessage(msg) + //case m: CheckRunningAndRecordingVoiceConfEvtMsg => logMessage(msg) case m: GetLockSettingsRespMsg => logMessage(msg) case m: ChangeLockSettingsInMeetingCmdMsg => logMessage(msg) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/FromAkkaAppsMsgSenderActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/FromAkkaAppsMsgSenderActor.scala index abb577ac35c114f843329b59a70e9c362810c79c..36a4a2cdaef529721eed75b71e10a5781fc644d4 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/FromAkkaAppsMsgSenderActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/FromAkkaAppsMsgSenderActor.scala @@ -48,6 +48,8 @@ class FromAkkaAppsMsgSenderActor(msgSender: MessageSender) msgSender.send(toVoiceConfRedisChannel, json) case TransferUserToVoiceConfSysMsg.NAME => msgSender.send(toVoiceConfRedisChannel, json) + case CheckRunningAndRecordingToVoiceConfSysMsg.NAME => + msgSender.send(toVoiceConfRedisChannel, json) //================================================================== // Send chat, presentation, and whiteboard in different channels so as not to diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/MeetingStatus2x.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/MeetingStatus2x.scala index bea9bd62575c113b030059b21881886bb260f5fa..9228d659a9e2696b13ed2b3d837da924c6901ab6 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/MeetingStatus2x.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/MeetingStatus2x.scala @@ -22,13 +22,6 @@ case class MeetingExtensionProp(maxExtensions: Int = 2, numExtensions: Int = 0, object MeetingStatus2x { - def isVoiceRecording(status: MeetingStatus2x): Boolean = { - status.voiceRecordings.values.find(s => s.recording) match { - case Some(rec) => true - case None => false - } - } - def isExtensionAllowed(status: MeetingStatus2x): Boolean = status.extension.numExtensions < status.extension.maxExtensions def incNumExtension(status: MeetingStatus2x): Int = { if (status.extension.numExtensions < status.extension.maxExtensions) { @@ -56,6 +49,13 @@ object MeetingStatus2x { def getLastAuthedUserLeftOn(status: MeetingStatus2x): Long = status.lastAuthedUserLeftOn def resetLastAuthedUserLeftOn(status: MeetingStatus2x) = status.lastAuthedUserLeftOn = 0L + def isVoiceRecording(status: MeetingStatus2x): Boolean = { + status.voiceRecordings.values.find(s => s.recording) match { + case Some(rec) => true + case None => false + } + } + def voiceRecordingStart(status2x: MeetingStatus2x, stream: String): VoiceRecordingStream = { val vrs = new VoiceRecordingStream(stream, recording = false, createdOn = System.currentTimeMillis, ackedOn = None, stoppedOn = None) status2x.voiceRecordings += vrs.stream -> vrs @@ -111,7 +111,8 @@ object MeetingStatus2x { } class MeetingStatus2x { - private var voiceRecordings: collection.immutable.HashMap[String, VoiceRecordingStream] = new collection.immutable.HashMap[String, VoiceRecordingStream] + private var voiceRecordings: collection.immutable.HashMap[String, VoiceRecordingStream] = + new collection.immutable.HashMap[String, VoiceRecordingStream] private var audioSettingsInited = false private var permissionsInited = false diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala index ac693a9b1c1dc71a4cad8998a4192d3ed8c53384..33839c0f27a1f78f1b10238c452e0a9a48b80f72 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala @@ -289,6 +289,15 @@ object MsgBuilder { BbbCommonEnvCoreMsg(envelope, event) } + def buildCheckRunningAndRecordingToVoiceConfSysMsg(meetingId: String, voiceConf: String): BbbCommonEnvCoreMsg = { + val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka") + val envelope = BbbCoreEnvelope(CheckRunningAndRecordingToVoiceConfSysMsg.NAME, routing) + val header = BbbCoreHeaderWithMeetingId(CheckRunningAndRecordingToVoiceConfSysMsg.NAME, meetingId) + val body = CheckRunningAndRecordingToVoiceConfSysMsgBody(voiceConf, meetingId) + val event = CheckRunningAndRecordingToVoiceConfSysMsg(header, body) + BbbCommonEnvCoreMsg(envelope, event) + } + def buildStartRecordingVoiceConfSysMsg(meetingId: String, voiceConf: String, stream: String): BbbCommonEnvCoreMsg = { val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka") val envelope = BbbCoreEnvelope(StartRecordingVoiceConfSysMsg.NAME, routing) diff --git a/akka-bbb-fsesl/.gitignore b/akka-bbb-fsesl/.gitignore index 1c0e395724135e398ce522ad03e88032ccb35e76..446435b9730b5d3b3015b15fd29f20a054ea6a2c 100644 --- a/akka-bbb-fsesl/.gitignore +++ b/akka-bbb-fsesl/.gitignore @@ -47,3 +47,4 @@ akka-patterns-store/ lib_managed/ .cache bin/ +src/main/resources/ diff --git a/akka-bbb-fsesl/run-dev.sh b/akka-bbb-fsesl/run-dev.sh new file mode 100755 index 0000000000000000000000000000000000000000..d08b052304fdb361a2df6fbfa8942bf72e65bf66 --- /dev/null +++ b/akka-bbb-fsesl/run-dev.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +rm -rf src/main/resources +cp -R src/universal/conf src/main/resources +sbt run + diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/FreeswitchConferenceEventListener.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/FreeswitchConferenceEventListener.java index 445d169314e2734ea80ede261535ceff3ffce736..a0386f5225bdd42f9e845d1302454a4b4f620684 100755 --- a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/FreeswitchConferenceEventListener.java +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/FreeswitchConferenceEventListener.java @@ -88,7 +88,17 @@ public class FreeswitchConferenceEventListener implements ConferenceEventListene vcs.deskShareRTMPBroadcastStopped(evt.getRoom(), evt.getBroadcastingStreamUrl(), evt.getVideoWidth(), evt.getVideoHeight(), evt.getTimestamp()); } + } else if (event instanceof VoiceConfRunningAndRecordingEvent) { + VoiceConfRunningAndRecordingEvent evt = (VoiceConfRunningAndRecordingEvent) event; + if (evt.running && ! evt.recording) { + log.warn("Voice conf running but not recording. conf=" + evt.getRoom() + + ",running=" + evt.running + + ",rec=" + evt.recording); + } + + vcs.voiceConfRunningAndRecording(evt.getRoom(), evt.running, evt.recording); } + } }; diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/IVoiceConferenceService.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/IVoiceConferenceService.java index dd7fb1d13ec486b94bd3fc136f480402b389b965..76b43997c54d165f14ec074137499e7707451fda 100755 --- a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/IVoiceConferenceService.java +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/IVoiceConferenceService.java @@ -24,4 +24,6 @@ public interface IVoiceConferenceService { void deskShareRTMPBroadcastStopped(String room, String streamname, Integer videoWidth, Integer videoHeight, String timestamp); + void voiceConfRunningAndRecording(String room, Boolean isRunning, Boolean isRecording); + } diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceConfRunningAndRecordingEvent.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceConfRunningAndRecordingEvent.java new file mode 100755 index 0000000000000000000000000000000000000000..0d3332c55cb0b5bd6a9d095992868458542f6040 --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceConfRunningAndRecordingEvent.java @@ -0,0 +1,31 @@ +/** + * BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ + * <p> + * Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). + * <p> + * 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. + * <p> + * 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. + * <p> + * 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 VoiceConfRunningAndRecordingEvent extends VoiceConferenceEvent { + + public final boolean running; + public final boolean recording; + + public VoiceConfRunningAndRecordingEvent(String room, boolean running, boolean recording) { + super(room); + this.running = running; + this.recording = recording; + } + +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/FreeswitchApplication.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/FreeswitchApplication.java index e031107a3d2ed70ea1519267d11f8b9ce4111199..36af8398a32e1651e8698c41e5ea40f5d3450b01 100755 --- a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/FreeswitchApplication.java +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/FreeswitchApplication.java @@ -103,12 +103,14 @@ public class FreeswitchApplication implements IDelayedCommandListener{ msgSenderExec.execute(sender); } + public void checkRunningAndRecording(String voiceConfId, String meetingId) { + ConferenceCheckRecordCommand ccrc = new ConferenceCheckRecordCommand(voiceConfId, meetingId); + queueMessage(ccrc); + } + public void getAllUsers(String voiceConfId) { GetAllUsersCommand prc = new GetAllUsersCommand(voiceConfId, USER); queueMessage(prc); - - ConferenceCheckRecordCommand ccrc = new ConferenceCheckRecordCommand(voiceConfId, USER); - queueMessage(ccrc); } public void muteUser(String voiceConfId, String voiceUserId, Boolean mute) { diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/CheckIfConfIsRunningCommand.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/CheckIfConfIsRunningCommand.java index 934e57826bcf6c865b7035368f40a0df7a8180ad..68df9d59228d5f3f7bbf56eeb14524129db267c5 100755 --- a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/CheckIfConfIsRunningCommand.java +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/CheckIfConfIsRunningCommand.java @@ -60,7 +60,7 @@ public class CheckIfConfIsRunningCommand extends FreeswitchCommand { String firstLine = response.getBodyLines().get(0); - log.info("Check conference first line response: " + firstLine); + //log.info("Check conference first line response: " + firstLine); //E.g. Conference 85115 not found if(!firstLine.startsWith("<?xml")) { diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/ConferenceCheckRecordCommand.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/ConferenceCheckRecordCommand.java index 56c887d4755946c24ea3fed43f519d8360e06a7f..b9c648a74320fe3c2a0bee2e95caae002336a6da 100755 --- a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/ConferenceCheckRecordCommand.java +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/actions/ConferenceCheckRecordCommand.java @@ -1,11 +1,24 @@ package org.bigbluebutton.freeswitch.voice.freeswitch.actions; +import org.apache.commons.lang3.StringUtils; import org.bigbluebutton.freeswitch.voice.events.ConferenceEventListener; +import org.bigbluebutton.freeswitch.voice.events.VoiceConfRunningAndRecordingEvent; +import org.bigbluebutton.freeswitch.voice.freeswitch.response.ConferenceMember; +import org.bigbluebutton.freeswitch.voice.freeswitch.response.XMLResponseConferenceListParser; import org.freeswitch.esl.client.transport.message.EslMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.SAXException; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import java.io.ByteArrayInputStream; +import java.io.IOException; import java.util.Iterator; public class ConferenceCheckRecordCommand extends FreeswitchCommand { + private static Logger log = LoggerFactory.getLogger(ConferenceCheckRecordCommand.class); public ConferenceCheckRecordCommand(String room, String requesterId) { super(room, requesterId); @@ -13,14 +26,69 @@ public class ConferenceCheckRecordCommand extends FreeswitchCommand { @Override public String getCommandArgs() { - return room + " chkrecord"; + //return room + " chkrecord"; + return getRoom() + SPACE + "xml_list"; } public void handleResponse(EslMessage response, ConferenceEventListener eventListener) { - Iterator iterator = response.getBodyLines().iterator(); - while(iterator.hasNext()) { - System.out.println(iterator.next()); + String firstLine = response.getBodyLines().get(0); + //log.info("Check conference first line response: " + firstLine); + + if(!firstLine.startsWith("<?xml")) { + //log.info("Conference is not running and recording {}.", room); + VoiceConfRunningAndRecordingEvent voiceConfRunningAndRecordingEvent = + new VoiceConfRunningAndRecordingEvent(getRoom(), false, false); + eventListener.handleConferenceEvent(voiceConfRunningAndRecordingEvent); + return; + } + + XMLResponseConferenceListParser confXML = new XMLResponseConferenceListParser(); + //get a factory + SAXParserFactory spf = SAXParserFactory.newInstance(); + try { + + boolean running = false; + boolean recording = false; + + //get a new instance of parser + SAXParser sp = spf.newSAXParser(); + + //Hack turning body lines back into string then to ByteStream.... BLAH! + String responseBody = StringUtils.join(response.getBodyLines(), "\n"); + //http://mark.koli.ch/2009/02/resolving-orgxmlsaxsaxparseexception-content-is-not-allowed-in-prolog.html + //This Sux! + responseBody = responseBody.trim().replaceFirst("^([\\W]+)<","<"); + + ByteArrayInputStream bs = new ByteArrayInputStream(responseBody.getBytes()); + sp.parse(bs, confXML); + + Integer numUsers = confXML.getConferenceList().size(); + if (numUsers > 0) { + //log.info("Check conference response: " + responseBody); + running = true; + + for (ConferenceMember member : confXML.getConferenceList()) { + if ("caller".equals(member.getMemberType())) { + // We don't need this. If there is at least one user in the conference, + // then it is running. (ralam Oct 16, 2019) + + } else if ("recording_node".equals(member.getMemberType())) { + recording = true; + } + } + } + + VoiceConfRunningAndRecordingEvent voiceConfRunningAndRecordingEvent = + new VoiceConfRunningAndRecordingEvent(getRoom(), running, recording); + eventListener.handleConferenceEvent(voiceConfRunningAndRecordingEvent); + + }catch(SAXException se) { + log.error("Cannot parse response. ", se); + }catch(ParserConfigurationException pce) { + log.error("ParserConfigurationException. ", pce); + }catch (IOException ie) { + log.error("Cannot parse response. IO Exception. ", ie); } } } diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/response/XMLResponseConferenceListParser.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/response/XMLResponseConferenceListParser.java index 48d7df3b48d412429bc34476b04f6db128036097..7fbbd1a99dc06ad5d7187b1cda93ba815fe0f6b0 100755 --- a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/response/XMLResponseConferenceListParser.java +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/response/XMLResponseConferenceListParser.java @@ -93,7 +93,6 @@ public class XMLResponseConferenceListParser extends DefaultHandler { tempVal = ""; if(qName.equalsIgnoreCase("member")) { String memberType = attributes.getValue("type"); - System.out.println("******************* Member Type = " + memberType); //create a new instance of ConferenceMember tempMember = new ConferenceMember(); diff --git a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/RxJsonMsgDeserializer.scala b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/RxJsonMsgDeserializer.scala index 7e69fdbdc10b237694bd5cee21227a172db5c767..1170cd5e07fc0e040de96db73fe557a0ae654e8e 100755 --- a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/RxJsonMsgDeserializer.scala +++ b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/RxJsonMsgDeserializer.scala @@ -9,6 +9,24 @@ trait RxJsonMsgDeserializer { object JsonDeserializer extends Deserializer + def routeCheckRunningAndRecordingToVoiceConfSysMsg(envelope: BbbCoreEnvelope, jsonNode: JsonNode): Unit = { + def deserialize(jsonNode: JsonNode): Option[CheckRunningAndRecordingToVoiceConfSysMsg] = { + val (result, error) = JsonDeserializer.toBbbCommonMsg[CheckRunningAndRecordingToVoiceConfSysMsg](jsonNode) + result match { + case Some(msg) => Some(msg.asInstanceOf[CheckRunningAndRecordingToVoiceConfSysMsg]) + case None => + log.error("Failed to deserialize message: error: {} \n msg: {}", error, jsonNode) + None + } + } + + for { + m <- deserialize(jsonNode) + } yield { + fsApp.checkRunningAndRecording(m.body.voiceConf, m.body.meetingId) + } + } + def routeDeskshareStartRtmpBroadcastVoiceConfMsg(envelope: BbbCoreEnvelope, jsonNode: JsonNode): Unit = { def deserialize(jsonNode: JsonNode): Option[ScreenshareStartRtmpBroadcastVoiceConfMsg] = { val (result, error) = JsonDeserializer.toBbbCommonMsg[ScreenshareStartRtmpBroadcastVoiceConfMsg](jsonNode) diff --git a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/RxJsonMsgHdlrActor.scala b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/RxJsonMsgHdlrActor.scala index 546c361cbbea807226d2b95426c5c515d237b449..0dba78515ab1618ba14ab8da3e07eca08257d0b0 100755 --- a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/RxJsonMsgHdlrActor.scala +++ b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/RxJsonMsgHdlrActor.scala @@ -52,6 +52,8 @@ class RxJsonMsgHdlrActor(val fsApp: FreeswitchApplication) extends Actor with Ac routeDeskshareStopRtmpBroadcastVoiceConfMsg(envelope, jsonNode) case ScreenshareStartRtmpBroadcastVoiceConfMsg.NAME => routeDeskshareStartRtmpBroadcastVoiceConfMsg(envelope, jsonNode) + case CheckRunningAndRecordingToVoiceConfSysMsg.NAME => + routeCheckRunningAndRecordingToVoiceConfSysMsg(envelope, jsonNode) case _ => // do nothing } } diff --git a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/VoiceConferenceService.scala b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/VoiceConferenceService.scala index 6ca12d87907706ebcecd481e28cb6772da9afd5c..81dee9e5b88dd4c18bfba80809535e31ad760c4e 100755 --- a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/VoiceConferenceService.scala +++ b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/VoiceConferenceService.scala @@ -10,6 +10,18 @@ class VoiceConferenceService(sender: RedisPublisher) extends IVoiceConferenceSer val FROM_VOICE_CONF_SYSTEM_CHAN = "bigbluebutton:from-voice-conf:system" + def voiceConfRunningAndRecording(voiceConfId: String, isRunning: java.lang.Boolean, isRecording: java.lang.Boolean) { + val header = BbbCoreVoiceConfHeader(CheckRunningAndRecordingVoiceConfEvtMsg.NAME, voiceConfId) + val body = CheckRunningAndRecordingVoiceConfEvtMsgBody(voiceConfId, isRunning.booleanValue(), isRecording.booleanValue()) + val envelope = BbbCoreEnvelope(CheckRunningAndRecordingVoiceConfEvtMsg.NAME, Map("voiceConf" -> voiceConfId)) + + val msg = new CheckRunningAndRecordingVoiceConfEvtMsg(header, body) + val msgEvent = BbbCommonEnvCoreMsg(envelope, msg) + + val json = JsonUtil.toJson(msgEvent) + sender.publish(fromVoiceConfRedisChannel, json) + } + def voiceConfRecordingStarted(voiceConfId: String, recordStream: String, recording: java.lang.Boolean, timestamp: String) { val header = BbbCoreVoiceConfHeader(RecordingStartedVoiceConfEvtMsg.NAME, voiceConfId) val body = RecordingStartedVoiceConfEvtMsgBody(voiceConfId, recordStream, recording.booleanValue(), timestamp) @@ -24,7 +36,6 @@ class VoiceConferenceService(sender: RedisPublisher) extends IVoiceConferenceSer } def voiceConfRunning(voiceConfId: String, running: java.lang.Boolean): Unit = { - println("*************######## Conference voiceConfId=" + voiceConfId + " running=" + running) val header = BbbCoreVoiceConfHeader(VoiceConfRunningEvtMsg.NAME, voiceConfId) val body = VoiceConfRunningEvtMsgBody(voiceConfId, running.booleanValue()) val envelope = BbbCoreEnvelope(VoiceConfRunningEvtMsg.NAME, Map("voiceConf" -> voiceConfId)) diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/VoiceConfMsgs.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/VoiceConfMsgs.scala index c228dbae478893b222d8d4dc228fd65a0d441439..6e4154769ddf715149edfa972a868e30c9b93132 100755 --- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/VoiceConfMsgs.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/VoiceConfMsgs.scala @@ -253,6 +253,26 @@ case class TransferUserToVoiceConfSysMsg( ) extends BbbCoreMsg case class TransferUserToVoiceConfSysMsgBody(fromVoiceConf: String, toVoiceConf: String, voiceUserId: String) +/** + * Sent to FS to check if voice conference is running and recording. + */ +object CheckRunningAndRecordingToVoiceConfSysMsg { val NAME = "CheckRunningAndRecordingToVoiceConfSysMsg" } +case class CheckRunningAndRecordingToVoiceConfSysMsg( + header: BbbCoreHeaderWithMeetingId, + body: CheckRunningAndRecordingToVoiceConfSysMsgBody +) extends BbbCoreMsg +case class CheckRunningAndRecordingToVoiceConfSysMsgBody(voiceConf: String, meetingId: String) + +/** + * Received from FS to check if voice conference is running and recording. + */ +object CheckRunningAndRecordingVoiceConfEvtMsg { val NAME = "CheckRunningAndRecordingVoiceConfEvtMsg" } +case class CheckRunningAndRecordingVoiceConfEvtMsg( + header: BbbCoreVoiceConfHeader, + body: CheckRunningAndRecordingVoiceConfEvtMsgBody +) extends VoiceStandardMsg +case class CheckRunningAndRecordingVoiceConfEvtMsgBody(voiceConf: String, isRunning: Boolean, isRecording: Boolean) + /** * Received from FS that user joined voice conference. */