- generate recording path in akka-apps for audio

This commit is contained in:
Richard Alam 2017-10-26 14:07:22 -07:00
parent aafcae9d79
commit c14a946041
13 changed files with 66 additions and 17 deletions

View File

@ -82,4 +82,8 @@ services {
apps {
checkPermissions = true
}
voiceConf {
recordPath = "/var/freeswitch/meetings"
}

View File

@ -61,4 +61,6 @@ trait SystemConfiguration {
lazy val telizePort = Try(config.getInt("services.telizePort")).getOrElse(80)
lazy val applyPermissionCheck = Try(config.getBoolean("apps.checkPermissions")).getOrElse(false)
lazy val voiceConfRecordPath = Try(config.getString("voiceConf.recordPath")).getOrElse("/var/freeswitch/meetings")
}

View File

@ -1,13 +1,15 @@
package org.bigbluebutton.core.apps.voice
import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.apps.breakout.BreakoutHdlrHelpers
import org.bigbluebutton.core.models.{ VoiceUserState, VoiceUsers }
import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting, OutMsgRouter }
import org.bigbluebutton.core.util.TimeUtil
import org.bigbluebutton.core2.MeetingStatus2x
import org.bigbluebutton.core2.message.senders.MsgBuilder
trait UserJoinedVoiceConfEvtMsgHdlr extends BreakoutHdlrHelpers {
trait UserJoinedVoiceConfEvtMsgHdlr extends BreakoutHdlrHelpers with SystemConfiguration {
this: BaseMeetingActor =>
val liveMeeting: LiveMeeting
@ -62,9 +64,11 @@ trait UserJoinedVoiceConfEvtMsgHdlr extends BreakoutHdlrHelpers {
liveMeeting.props.recordProp.record &&
!MeetingStatus2x.isVoiceRecording(liveMeeting.status)) {
log.info("Send START RECORDING voice conf. meetingId=" + liveMeeting.props.meetingProp.intId
+ " voice conf=" + liveMeeting.props.voiceProp.voiceConf)
VoiceApp.startRecordingVoiceConference(liveMeeting, outGW)
val meetingId = liveMeeting.props.meetingProp.intId
val recordFile = VoiceApp.genRecordPath(voiceConfRecordPath, meetingId, TimeUtil.timeNowInMs())
log.info("Send START RECORDING voice conf. meetingId=" + meetingId + " voice conf=" + liveMeeting.props.voiceProp.voiceConf)
VoiceApp.startRecordingVoiceConference(liveMeeting, outGW, recordFile)
} else {
log.info("Not recording audio as numVoiceUsers={} and isRecording={} and recordProp={}", numVoiceUsers,
MeetingStatus2x.isVoiceRecording(liveMeeting.status), liveMeeting.props.recordProp.record)

View File

@ -1,16 +1,27 @@
package org.bigbluebutton.core.apps.voice
import java.io.File
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
import org.bigbluebutton.core2.MeetingStatus2x
import org.bigbluebutton.core2.message.senders.MsgBuilder
object VoiceApp {
def startRecordingVoiceConference(liveMeeting: LiveMeeting, outGW: OutMsgRouter): Unit = {
def genRecordPath(recordDir: String, meetingId: String, timestamp: Long): String = {
if (recordDir.endsWith("/")) {
recordDir.concat(meetingId).concat("-").concat(timestamp.toString).concat(".wav")
} else {
recordDir.concat("/").concat(meetingId).concat("-").concat(timestamp.toString).concat(".wav")
}
}
def startRecordingVoiceConference(liveMeeting: LiveMeeting, outGW: OutMsgRouter, stream: String): Unit = {
MeetingStatus2x.startRecordingVoice(liveMeeting.status)
val event = MsgBuilder.buildStartRecordingVoiceConfSysMsg(
liveMeeting.props.meetingProp.intId,
liveMeeting.props.voiceProp.voiceConf
liveMeeting.props.voiceProp.voiceConf,
stream
)
outGW.send(event)
}

View File

@ -136,6 +136,8 @@ class ReceivedJsonMsgHandlerActor(
routeVoiceMsg[UserDisconnectedFromGlobalAudioMsg](envelope, jsonNode)
case MuteMeetingCmdMsg.NAME =>
routeGenericMsg[MuteMeetingCmdMsg](envelope, jsonNode)
case VoiceConfRunningEvtMsg.NAME =>
routeVoiceMsg[VoiceConfRunningEvtMsg](envelope, jsonNode)
// Breakout rooms
case BreakoutRoomsListMsg.NAME =>

View File

@ -19,6 +19,7 @@
package org.bigbluebutton.core.record.events
import java.text.SimpleDateFormat
import java.util.Date
import scala.collection.mutable.HashMap
@ -34,7 +35,8 @@ trait RecordEvent {
final def timestampUTC(utc: Long): Unit = {
eventMap.put(TIMESTAMP_UTC, utc.toString)
eventMap.put(DATE, (new Date(utc)).toString)
val sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX")
eventMap.put(DATE, sdf.format(utc))
}
/**

View File

@ -412,14 +412,17 @@ class MeetingActor(
val now = TimeUtil.timeNowInMs()
val elapsedInMs = now - lastRecBreakSentOn
val elapsedInMin = TimeUtil.millisToMinutes(elapsedInMs)
println("******************* ElapsedInMS=" + elapsedInMs + ", elapsedInMIN=" + elapsedInMin)
if (elapsedInMin > 1) {
lastRecBreakSentOn = now
val event = MsgBuilder.buildRecordingChapterBreakSysMsg(props.meetingProp.intId, TimeUtil.timeNowInMs())
outGW.send(event)
VoiceApp.stopRecordingVoiceConference(liveMeeting, outGW)
VoiceApp.startRecordingVoiceConference(liveMeeting, outGW)
val meetingId = liveMeeting.props.meetingProp.intId
val recordFile = VoiceApp.genRecordPath(voiceConfRecordPath, meetingId, now)
VoiceApp.startRecordingVoiceConference(liveMeeting, outGW, recordFile)
}

View File

@ -1,17 +1,21 @@
package org.bigbluebutton.core.running
import java.io.{ PrintWriter, StringWriter }
import java.text.SimpleDateFormat
import java.util.Date
import akka.actor.Actor
import akka.actor.ActorLogging
import akka.actor.Props
import akka.actor.OneForOneStrategy
import akka.actor.SupervisorStrategy.Resume
import scala.concurrent.duration._
import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.common2.domain.DefaultProps
import org.bigbluebutton.core.api._
import org.bigbluebutton.core.bus.{ BigBlueButtonEvent, InternalEventBus }
import scala.concurrent.ExecutionContext.Implicits.global
object MeetingActorAudit {

View File

@ -258,11 +258,11 @@ object MsgBuilder {
BbbCommonEnvCoreMsg(envelope, event)
}
def buildStartRecordingVoiceConfSysMsg(meetingId: String, voiceConf: String): BbbCommonEnvCoreMsg = {
def buildStartRecordingVoiceConfSysMsg(meetingId: String, voiceConf: String, stream: String): BbbCommonEnvCoreMsg = {
val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka")
val envelope = BbbCoreEnvelope(StartRecordingVoiceConfSysMsg.NAME, routing)
val header = BbbCoreHeaderWithMeetingId(StartRecordingVoiceConfSysMsg.NAME, meetingId)
val body = StartRecordingVoiceConfSysMsgBody(voiceConf, meetingId)
val body = StartRecordingVoiceConfSysMsgBody(voiceConf, meetingId, stream)
val event = StartRecordingVoiceConfSysMsg(header, body)
BbbCommonEnvCoreMsg(envelope, event)
}

View File

@ -0,0 +1,20 @@
package org.bigbluebutton.core2.voiceconf
import akka.actor.{ Actor, ActorLogging, FSM }
import org.bigbluebutton.SystemConfiguration
sealed trait VoiceConfState
case object VoiceConfStarted extends VoiceConfState
case object StartRecording extends VoiceConfState
case object RecordingStarted extends VoiceConfState
case object StopRecording extends VoiceConfState
case object RecordingStopped extends VoiceConfState
case object VoiceConfStopped extends VoiceConfState
case class VoiceConfData(record: Boolean, numUsers: Int, streams: Vector[RecordStream])
case class RecordStream(stream: String, started: Boolean)
class VoiceConfActor extends Actor with ActorLogging with FSM[VoiceConfState, VoiceConfData] with SystemConfiguration {
}

View File

@ -114,10 +114,7 @@ public class FreeswitchApplication {
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";
public void startRecording(String voiceConfId, String meetingid, String voicePath) {
RecordConferenceCommand rcc = new RecordConferenceCommand(voiceConfId, USER, true, voicePath);
queueMessage(rcc);
}

View File

@ -149,7 +149,7 @@ trait RxJsonMsgDeserializer {
for {
m <- deserialize(jsonNode)
} yield {
fsApp.startRecording(m.body.voiceConf, m.body.meetingId)
fsApp.startRecording(m.body.voiceConf, m.body.meetingId, m.body.stream)
}
}

View File

@ -191,7 +191,7 @@ case class MeetingMutedEvtMsgBody(muted: Boolean, mutedBy: String)
object StartRecordingVoiceConfSysMsg { val NAME = "StartRecordingVoiceConfSysMsg" }
case class StartRecordingVoiceConfSysMsg(header: BbbCoreHeaderWithMeetingId,
body: StartRecordingVoiceConfSysMsgBody) extends BbbCoreMsg
case class StartRecordingVoiceConfSysMsgBody(voiceConf: String, meetingId: String)
case class StartRecordingVoiceConfSysMsgBody(voiceConf: String, meetingId: String, stream: String)
/**
* Sent to FS to stop recording voice conference.