use of org.red5.server.api.IConnection in project bigbluebutton by bigbluebutton.
the class Red5AppAdapter method recordStream.
/**
* A hook to record a stream. A file is written in webapps/video/streams/
* @param stream
*/
private void recordStream(IBroadcastStream stream) {
IConnection conn = Red5.getConnectionLocal();
long now = System.currentTimeMillis();
// + "-" + now; /** Comment out for now...forgot why I added this - ralam */
String recordingStreamName = stream.getPublishedName();
try {
log.info("Recording stream " + recordingStreamName);
ClientBroadcastStream cstream = (ClientBroadcastStream) this.getBroadcastStream(conn.getScope(), stream.getPublishedName());
cstream.saveAs(recordingStreamName, false);
} catch (Exception e) {
log.error("ERROR while recording stream " + e.getMessage());
e.printStackTrace();
}
}
use of org.red5.server.api.IConnection in project bigbluebutton by bigbluebutton.
the class Red5AppAdapter method streamBroadcastStart.
@Override
public void streamBroadcastStart(IBroadcastStream stream) {
IConnection conn = Red5.getConnectionLocal();
super.streamBroadcastStart(stream);
log.info("streamBroadcastStart " + stream.getPublishedName() + "]");
String streamId = stream.getPublishedName();
Matcher matcher = STREAM_ID_PATTERN.matcher(stream.getPublishedName());
if (matcher.matches()) {
String meetingId = matcher.group(1).trim();
String url = streamBaseUrl + "/" + meetingId + "/" + streamId;
app.streamStarted(meetingId, streamId, url);
boolean recordVideoStream = app.recordStream(meetingId, streamId);
if (recordVideoStream) {
recordStream(stream);
ScreenshareStreamListener listener = new ScreenshareStreamListener(recordingService, recordingDirectory);
stream.addStreamListener(listener);
streamListeners.put(conn.getScope().getName() + "-" + stream.getPublishedName(), listener);
}
Map<String, Object> logData = new HashMap<String, Object>();
logData.put("meetingId", meetingId);
logData.put("streamId", streamId);
logData.put("url", url);
logData.put("recorded", recordVideoStream);
Gson gson = new Gson();
String logStr = gson.toJson(logData);
log.info("ScreenShare broadcast started: data={}", logStr);
} else {
log.error("Invalid streamid format [{}]", streamId);
}
}
use of org.red5.server.api.IConnection in project bigbluebutton by bigbluebutton.
the class Red5AppService method setUserId.
/**
* Called from the client to pass us the userId.
*
* We need to do this as we can't have params on the connect call
* as FFMpeg won't be able to connect.
* @param userId
*/
public void setUserId(Map<String, Object> msg) {
String meetingId = Red5.getConnectionLocal().getScope().getName();
String userId = (String) msg.get("userId");
String connType = getConnectionType(Red5.getConnectionLocal().getType());
String sessionId = Red5.getConnectionLocal().getSessionId();
/**
* Find if there are any other connections owned by this user. If we find one,
* that means that the connection is old and the user reconnected. Clear the
* userId attribute so that messages would not be sent in the defunct connection.
*/
Set<IConnection> conns = Red5.getConnectionLocal().getScope().getClientConnections();
for (IConnection conn : conns) {
String connUserId = (String) conn.getAttribute("USERID");
String connSessionId = conn.getSessionId();
if (connUserId != null && connUserId.equals(userId) && !connSessionId.equals(sessionId)) {
conn.removeAttribute("USERID");
Map<String, Object> logData = new HashMap<String, Object>();
logData.put("meetingId", meetingId);
logData.put("userId", userId);
logData.put("oldConnId", connSessionId);
logData.put("newConnId", sessionId);
logData.put("event", "removing_defunct_connection");
logData.put("description", "Removing defunct connection BBB Screenshare.");
Gson gson = new Gson();
String logStr = gson.toJson(logData);
log.info("Removing defunct connection: data={}", logStr);
}
}
Red5.getConnectionLocal().setAttribute("MEETING_ID", meetingId);
Red5.getConnectionLocal().setAttribute("USERID", userId);
handler.userConnected(meetingId, userId);
Map<String, Object> logData = new HashMap<String, Object>();
logData.put("meetingId", meetingId);
logData.put("userId", userId);
logData.put("connType", connType);
logData.put("connId", sessionId);
logData.put("event", "user_joining_bbb_screenshare");
logData.put("description", "User joining BBB Screenshare.");
Gson gson = new Gson();
String logStr = gson.toJson(logData);
log.info("User joining bbb-screenshare: data={}", logStr);
}
use of org.red5.server.api.IConnection in project bigbluebutton by bigbluebutton.
the class ConnectionInvokerService method sendDirectMessage.
private void sendDirectMessage(final DirectClientMessage msg) {
Runnable sender = new Runnable() {
public void run() {
IScope meetingScope = getScope(msg.getMeetingID());
if (meetingScope != null) {
log.debug("Found scope =[{}] for meeting=[{}]", meetingScope.getName(), msg.getMeetingID());
IConnection conn = getConnection(meetingScope, msg.getUserID());
if (conn != null) {
if (conn.isConnected()) {
List<Object> params = new ArrayList<Object>();
params.add(msg.getMessageName());
params.add(msg.getMessage());
log.debug("Sending message=[{}] to meeting=[{}]", msg.getMessageName(), msg.getMeetingID());
ServiceUtils.invokeOnConnection(conn, "onMessageFromServer", params.toArray());
} else {
log.warn("Connection not connected for userid=[{}] in meeting=[{}]", msg.getUserID(), msg.getMeetingID());
}
} else {
log.warn("No connection for userid=[{}] in meeting=[{}]", msg.getUserID(), msg.getMeetingID());
}
} else {
log.error("Failed to find scope for meeting=[{}]", msg.getMeetingID());
}
}
};
runExec.execute(sender);
}
use of org.red5.server.api.IConnection in project bigbluebutton by bigbluebutton.
the class NellySipToFlashTranscoderImp method transcode.
@Override
public void transcode(byte[] audioData) {
if (audioData.length != ULAW_AUDIO_LENGTH) {
if (log.isWarnEnabled())
log.warn("Received corrupt audio. Got {}, expected {}.", audioData.length, ULAW_AUDIO_LENGTH);
return;
}
// Convert Ulaw to L16
audioCodec.codecToPcm(audioData, tempL16Buffer);
// Store into the buffer
l16Audio.put(tempL16Buffer);
if ((l16Audio.position() - viewBuffer.position()) >= L16_AUDIO_LENGTH) {
// We have enough L16 audio to generate a Nelly audio.
// Get some L16 audio
viewBuffer.get(tempNellyBuffer);
// Convert it into Nelly
encoderMap = CodecImpl.encode(encoderMap, tempNellyBuffer, nellyBytes);
// Having done all of that, we now see if we need to send the audio or drop it.
// We have to encode to build the encoderMap so that data from previous audio packet
// will be used for the next packet.
boolean sendPacket = true;
IConnection conn = Red5.getConnectionLocal();
if (conn instanceof RTMPMinaConnection) {
long pendingMessages = ((RTMPMinaConnection) conn).getPendingMessages();
if (pendingMessages > 25) {
// Message backed up probably due to slow connection to client (25 messages * 20ms ptime = 500ms audio)
sendPacket = false;
if (log.isInfoEnabled())
log.info("Dropping packet. Connection {} congested with {} pending messages (~500ms worth of audio) .", conn.getClient().getId(), pendingMessages);
}
}
if (sendPacket)
transcodedAudioListener.handleTranscodedAudioData(nellyBytes, timestamp += TS_INCREMENT);
}
if (l16Audio.position() == l16Audio.capacity()) {
// We've processed 8 Ulaw packets (5 Nelly packets), reset the buffers.
l16Audio.clear();
viewBuffer.clear();
}
}
Aggregations