diff --git a/openvidu-browser/src/OpenVidu/OpenVidu.ts b/openvidu-browser/src/OpenVidu/OpenVidu.ts index 3d2e34f5..3d2263ba 100644 --- a/openvidu-browser/src/OpenVidu/OpenVidu.ts +++ b/openvidu-browser/src/OpenVidu/OpenVidu.ts @@ -92,6 +92,10 @@ export class OpenVidu { * @hidden */ recorder = false; + /** + * @hidden + */ + stt = false; /** * @hidden */ @@ -932,6 +936,13 @@ export class OpenVidu { return this.recorder; } + /** + * @hidden + */ + getStt(): boolean { + return this.stt; + } + /** * @hidden */ diff --git a/openvidu-browser/src/OpenVidu/Session.ts b/openvidu-browser/src/OpenVidu/Session.ts index b397c749..05d4ccf8 100644 --- a/openvidu-browser/src/OpenVidu/Session.ts +++ b/openvidu-browser/src/OpenVidu/Session.ts @@ -1378,7 +1378,8 @@ export class Session extends EventDispatcher { sdkVersion: this.openvidu.libraryVersion, metadata: !!this.options.metadata ? this.options.metadata : '', secret: this.openvidu.getSecret(), - recorder: this.openvidu.getRecorder() + recorder: this.openvidu.getRecorder(), + stt: this.openvidu.getStt() }; return joinParams; } @@ -1538,6 +1539,7 @@ export class Session extends EventDispatcher { sessionId: queryParams['sessionId'], secret: queryParams['secret'], recorder: queryParams['recorder'], + stt: queryParams['stt'], webrtcStatsInterval: queryParams['webrtcStatsInterval'], sendBrowserLogs: queryParams['sendBrowserLogs'], edition: queryParams['edition'], @@ -1689,6 +1691,9 @@ export class Session extends EventDispatcher { if (!!tokenParams.recorder) { this.openvidu.recorder = true; } + if (!!tokenParams.stt) { + this.openvidu.stt = true; + } if (!!tokenParams.webrtcStatsInterval) { this.openvidu.webrtcStatsInterval = tokenParams.webrtcStatsInterval; } diff --git a/openvidu-client/src/main/java/io/openvidu/client/OpenViduException.java b/openvidu-client/src/main/java/io/openvidu/client/OpenViduException.java index 1cd99e3f..3c244e7d 100644 --- a/openvidu-client/src/main/java/io/openvidu/client/OpenViduException.java +++ b/openvidu-client/src/main/java/io/openvidu/client/OpenViduException.java @@ -23,7 +23,7 @@ public class OpenViduException extends JsonRpcErrorException { private static final long serialVersionUID = 1L; public static enum Code { - GENERIC_ERROR_CODE(999), WRONG_PATH_CODE(998), + GENERIC_ERROR_CODE(999), WRONG_PATH_CODE(998), WRONG_OPENVIDU_EDITION(997), TRANSPORT_ERROR_CODE(803), TRANSPORT_RESPONSE_ERROR_CODE(802), TRANSPORT_REQUEST_ERROR_CODE(801), @@ -55,7 +55,7 @@ public class OpenViduException extends JsonRpcErrorException { FORCED_CODEC_NOT_FOUND_IN_SDPOFFER(800), - MEDIA_NODE_NOT_FOUND(900), MEDIA_NODE_STATUS_WRONG(901); + MEDIA_NODE_NOT_FOUND(900), MEDIA_NODE_STATUS_WRONG(901), MEDIA_NODE_CONNECTION_ERROR_CODE(902); private int value; diff --git a/openvidu-client/src/main/java/io/openvidu/client/internal/ProtocolElements.java b/openvidu-client/src/main/java/io/openvidu/client/internal/ProtocolElements.java index fb1f633e..22bb0ed3 100644 --- a/openvidu-client/src/main/java/io/openvidu/client/internal/ProtocolElements.java +++ b/openvidu-client/src/main/java/io/openvidu/client/internal/ProtocolElements.java @@ -40,6 +40,7 @@ public class ProtocolElements { public static final String JOINROOM_PLATFORM_PARAM = "platform"; public static final String JOINROOM_SDKVERSION_PARAM = "sdkVersion"; public static final String JOINROOM_RECORDER_PARAM = "recorder"; + public static final String JOINROOM_STT_PARAM = "stt"; public static final String JOINROOM_PEERID_PARAM = "id"; public static final String JOINROOM_PEERCREATEDAT_PARAM = "createdAt"; @@ -236,4 +237,5 @@ public class ProtocolElements { public static final String CUSTOM_NOTIFICATION = "customNotification"; public static final String RECORDER_PARTICIPANT_PUBLICID = "RECORDER"; + public static final String STT_PARTICIPANT_PUBLICID = "SPEECH_TO_TEXT"; } diff --git a/openvidu-server/src/main/java/io/openvidu/server/core/Participant.java b/openvidu-server/src/main/java/io/openvidu/server/core/Participant.java index 97e17f59..f29bf347 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/core/Participant.java +++ b/openvidu-server/src/main/java/io/openvidu/server/core/Participant.java @@ -22,6 +22,7 @@ import java.util.concurrent.locks.ReentrantLock; import com.google.gson.JsonObject; +import io.openvidu.client.internal.ProtocolElements; import io.openvidu.server.kurento.endpoint.EndpointType; import io.openvidu.server.utils.GeoLocation; @@ -220,6 +221,18 @@ public class Participant { && this.participantPrivateId.startsWith(IdentifierPrefixes.IPCAM_ID); } + public boolean isRecorderParticipant() { + return ProtocolElements.RECORDER_PARTICIPANT_PUBLICID.equals(this.participantPublicId); + } + + public boolean isSttParticipant() { + return ProtocolElements.STT_PARTICIPANT_PUBLICID.equals(this.participantPublicId); + } + + public boolean isRecorderOrSttParticipant() { + return (this.isRecorderParticipant() || this.isSttParticipant()); + } + public String getPublisherStreamId() { return null; } diff --git a/openvidu-server/src/main/java/io/openvidu/server/core/Session.java b/openvidu-server/src/main/java/io/openvidu/server/core/Session.java index 50cbe62e..35120b3d 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/core/Session.java +++ b/openvidu-server/src/main/java/io/openvidu/server/core/Session.java @@ -38,7 +38,6 @@ import com.google.gson.JsonObject; import io.openvidu.client.OpenViduException; import io.openvidu.client.OpenViduException.Code; -import io.openvidu.client.internal.ProtocolElements; import io.openvidu.java.client.SessionProperties; import io.openvidu.server.config.OpenviduConfig; import io.openvidu.server.recording.service.RecordingManager; @@ -140,9 +139,13 @@ public class Session implements SessionInterface { return null; } - public boolean onlyRecorderParticipant() { - return this.participants.size() == 1 && ProtocolElements.RECORDER_PARTICIPANT_PUBLICID - .equals(this.participants.values().iterator().next().getParticipantPublicId()); + public boolean onlyRecorderAndOrSttParticipant() { + if (this.participants.size() == 1) { + return this.participants.values().iterator().next().isRecorderOrSttParticipant(); + } else if (this.participants.size() == 2) { + return this.participants.values().stream().allMatch(p -> p.isRecorderOrSttParticipant()); + } + return false; } public int getActivePublishers() { @@ -216,8 +219,8 @@ public class Session implements SessionInterface { Set snapshotOfActiveConnections = this.getParticipants().stream().collect(Collectors.toSet()); JsonArray jsonArray = new JsonArray(); snapshotOfActiveConnections.forEach(participant -> { - // Filter recorder participant - if (!ProtocolElements.RECORDER_PARTICIPANT_PUBLICID.equals(participant.getParticipantPublicId())) { + // Filter RECORDER and STT participants + if (!participant.isRecorderOrSttParticipant()) { jsonArray.add(withWebrtcStats ? participant.withStatsToJson() : participant.toJson()); } }); diff --git a/openvidu-server/src/main/java/io/openvidu/server/core/SessionEventsHandler.java b/openvidu-server/src/main/java/io/openvidu/server/core/SessionEventsHandler.java index 60bfb45b..112cdbaf 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/core/SessionEventsHandler.java +++ b/openvidu-server/src/main/java/io/openvidu/server/core/SessionEventsHandler.java @@ -130,16 +130,16 @@ public class SessionEventsHandler { participantJson.add(ProtocolElements.JOINROOM_PEERSTREAMS_PARAM, streamsArray); } - // Avoid emitting 'connectionCreated' event of existing RECORDER participant in - // openvidu-browser in newly joined participants - if (!ProtocolElements.RECORDER_PARTICIPANT_PUBLICID.equals(existingParticipant.getParticipantPublicId())) { + // Avoid emitting 'connectionCreated' event of existing RECORDER or STT + // participant in openvidu-browser in newly joined participants + if (!existingParticipant.isRecorderOrSttParticipant()) { resultArray.add(participantJson); } - // If RECORDER participant has joined do NOT send 'participantJoined' + // If RECORDER or STT participant has joined do NOT send 'participantJoined' // notification to existing participants. 'recordingStarted' will be sent to all // existing participants when recorder first subscribe to a stream - if (!ProtocolElements.RECORDER_PARTICIPANT_PUBLICID.equals(participant.getParticipantPublicId())) { + if (!participant.isRecorderOrSttParticipant()) { JsonObject notifParams = new JsonObject(); // Metadata associated to new participant @@ -221,13 +221,14 @@ public class SessionEventsHandler { public void onParticipantLeft(Participant participant, String sessionId, Set remainingParticipants, Integer transactionId, OpenViduException error, EndReason reason, boolean scheduleWebsocketClose) { + if (error != null) { rpcNotificationService.sendErrorResponse(participant.getParticipantPrivateId(), transactionId, null, error); return; } - if (ProtocolElements.RECORDER_PARTICIPANT_PUBLICID.equals(participant.getParticipantPublicId())) { - // RECORDER participant + if (participant.isRecorderOrSttParticipant()) { + this.rpcNotificationService.immediatelyCloseRpcSession(participant.getParticipantPrivateId()); return; } @@ -253,9 +254,7 @@ public class SessionEventsHandler { this.rpcNotificationService.scheduleCloseRpcSession(participant.getParticipantPrivateId(), 10000); } - if (!ProtocolElements.RECORDER_PARTICIPANT_PUBLICID.equals(participant.getParticipantPublicId())) { - CDR.recordParticipantLeft(participant, sessionId, reason); - } + CDR.recordParticipantLeft(participant, sessionId, reason); } public void onPublishMedia(Participant participant, String streamId, Long createdAt, String sessionId, @@ -357,32 +356,27 @@ public class SessionEventsHandler { public void onSubscribeClientInitiatedNegotiation(Participant participant, Session session, String sdpAnswer, Integer transactionId, OpenViduException error) { - if (error != null) { - rpcNotificationService.sendErrorResponse(participant.getParticipantPrivateId(), transactionId, null, error); - return; - } - JsonObject result = new JsonObject(); - result.addProperty(ProtocolElements.RECEIVEVIDEO_SDPANSWER_PARAM, sdpAnswer); - rpcNotificationService.sendResponse(participant.getParticipantPrivateId(), transactionId, result); - - if (ProtocolElements.RECORDER_PARTICIPANT_PUBLICID.equals(participant.getParticipantPublicId())) { - recordingsToSendClientEvents.computeIfPresent(session.getSessionId(), (key, value) -> { - sendRecordingStartedNotification(session, value); - return null; - }); - } + this.onSubscribeAux(participant, session, sdpAnswer, transactionId, error); } public void onSubscribeServerInitiatedNegotiation(Participant participant, Session session, Integer transactionId, OpenViduException error) { + this.onSubscribeAux(participant, session, null, transactionId, error); + } + + private void onSubscribeAux(Participant participant, Session session, String sdpAnswer, Integer transactionId, + OpenViduException error) { if (error != null) { rpcNotificationService.sendErrorResponse(participant.getParticipantPrivateId(), transactionId, null, error); return; } JsonObject result = new JsonObject(); + if (sdpAnswer != null) { + result.addProperty(ProtocolElements.RECEIVEVIDEO_SDPANSWER_PARAM, sdpAnswer); + } rpcNotificationService.sendResponse(participant.getParticipantPrivateId(), transactionId, result); - if (ProtocolElements.RECORDER_PARTICIPANT_PUBLICID.equals(participant.getParticipantPublicId())) { + if (participant.isRecorderParticipant()) { recordingsToSendClientEvents.computeIfPresent(session.getSessionId(), (key, value) -> { sendRecordingStartedNotification(session, value); return null; @@ -464,7 +458,7 @@ public class SessionEventsHandler { } } - if (isRpcCall) { + if (participant != null && isRpcCall) { rpcNotificationService.sendResponse(participant.getParticipantPrivateId(), transactionId, new JsonObject()); } @@ -519,13 +513,13 @@ public class SessionEventsHandler { evictedParticipant.getParticipantPublicId()); params.addProperty(ProtocolElements.PARTICIPANTEVICTED_REASON_PARAM, reason != null ? reason.name() : ""); - if (!ProtocolElements.RECORDER_PARTICIPANT_PUBLICID.equals(evictedParticipant.getParticipantPublicId())) { - // Do not send a message when evicting RECORDER participant + if (evictedParticipant.isRecorderOrSttParticipant()) { + // Do not send a message when evicting RECORDER or STT participant rpcNotificationService.sendNotification(evictedParticipant.getParticipantPrivateId(), ProtocolElements.PARTICIPANTEVICTED_METHOD, params); } for (Participant p : participants) { - if (!ProtocolElements.RECORDER_PARTICIPANT_PUBLICID.equals(evictedParticipant.getParticipantPublicId())) { + if (!evictedParticipant.isRecorderParticipant()) { rpcNotificationService.sendNotification(p.getParticipantPrivateId(), ProtocolElements.PARTICIPANTEVICTED_METHOD, params); } @@ -691,6 +685,24 @@ public class SessionEventsHandler { public void onMediaNodeRecovered(Kms kms, String environmentId, long timeOfConnection) { } + public void onSubscribeToSpeechToText(Participant participant, Integer transactionId, OpenViduException error) { + if (error != null) { + rpcNotificationService.sendErrorResponse(participant.getParticipantPrivateId(), transactionId, null, error); + } else { + JsonObject result = new JsonObject(); + rpcNotificationService.sendResponse(participant.getParticipantPrivateId(), transactionId, result); + } + } + + public void onUnsubscribeToSpeechToText(Participant participant, Integer transactionId, OpenViduException error) { + if (error != null) { + rpcNotificationService.sendErrorResponse(participant.getParticipantPrivateId(), transactionId, null, error); + } else { + JsonObject result = new JsonObject(); + rpcNotificationService.sendResponse(participant.getParticipantPrivateId(), transactionId, result); + } + } + public void onSpeechToTextMessage(String sessionId, String connectionId, long timestamp, String text, Set subscribedParticipants) { } @@ -701,7 +713,7 @@ public class SessionEventsHandler { protected Set filterParticipantsByRole(Set roles, Set participants) { return participants.stream().filter(part -> { - if (ProtocolElements.RECORDER_PARTICIPANT_PUBLICID.equals(part.getParticipantPublicId())) { + if (part.isRecorderOrSttParticipant()) { return false; } return roles.contains(part.getToken().getRole()); diff --git a/openvidu-server/src/main/java/io/openvidu/server/core/SessionManager.java b/openvidu-server/src/main/java/io/openvidu/server/core/SessionManager.java index 376cd1b4..04b1b359 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/core/SessionManager.java +++ b/openvidu-server/src/main/java/io/openvidu/server/core/SessionManager.java @@ -444,6 +444,17 @@ public abstract class SessionManager { } } + public Participant newSttParticipant(Session session, String participantPrivateId, Token token, String clientMetadata) { + String sessionId = session.getSessionId(); + if (this.sessionidParticipantpublicidParticipant.get(sessionId) != null) { + return newParticipantAux(sessionId, session.getUniqueSessionId(), null, participantPrivateId, + ProtocolElements.STT_PARTICIPANT_PUBLICID, token, clientMetadata, null, null, + EndpointType.WEBRTC_ENDPOINT); + } else { + throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE, sessionId); + } + } + public Participant newIpcamParticipant(Session session, String ipcamId, Token token, GeoLocation location, String platform) { String sessionId = session.getSessionId(); diff --git a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoParticipant.java b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoParticipant.java index 6155a09b..a1e7692d 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoParticipant.java +++ b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoParticipant.java @@ -46,7 +46,6 @@ import com.google.gson.JsonObject; import io.openvidu.client.OpenViduException; import io.openvidu.client.OpenViduException.Code; -import io.openvidu.client.internal.ProtocolElements; import io.openvidu.java.client.OpenViduRole; import io.openvidu.server.cdr.WebrtcDebugEvent; import io.openvidu.server.config.OpenviduConfig; @@ -284,8 +283,7 @@ public class KurentoParticipant extends Participant { String sdpAnswer = subscriber.subscribe(sdpString, kSender.getPublisher()); log.info("PARTICIPANT {}: Is now receiving video from {} in room {}", this.getParticipantPublicId(), senderName, this.session.getSessionId()); - if (!silent && !ProtocolElements.RECORDER_PARTICIPANT_PUBLICID - .equals(this.getParticipantPublicId())) { + if (!silent && !this.isRecorderOrSttParticipant()) { endpointConfig.getCdr().recordNewSubscriber(this, sender.getPublisherStreamId(), sender.getParticipantPublicId(), subscriber.createdAt()); } @@ -591,7 +589,7 @@ public class KurentoParticipant extends Participant { } } - if (!ProtocolElements.RECORDER_PARTICIPANT_PUBLICID.equals(this.getParticipantPublicId())) { + if (!this.isRecorderOrSttParticipant()) { endpointConfig.getCdr().stopSubscriber(this.getParticipantPublicId(), senderName, subscriber.getStreamId(), reason); } diff --git a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSession.java b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSession.java index e83cf231..0cf7019b 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSession.java +++ b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSession.java @@ -37,7 +37,6 @@ import com.google.gson.JsonObject; import io.openvidu.client.OpenViduException; import io.openvidu.client.OpenViduException.Code; -import io.openvidu.client.internal.ProtocolElements; import io.openvidu.java.client.OpenViduRole; import io.openvidu.server.core.EndReason; import io.openvidu.server.core.MediaOptions; @@ -87,7 +86,7 @@ public class KurentoSession extends Session { log.info("SESSION {}: Added participant {}", sessionId, participant); - if (!ProtocolElements.RECORDER_PARTICIPANT_PUBLICID.equals(participant.getParticipantPublicId())) { + if (!participant.isRecorderOrSttParticipant()) { kurentoEndpointConfig.getCdr().recordParticipantJoined(participant, sessionId); } } @@ -381,9 +380,9 @@ public class KurentoSession extends Session { } public int getNumberOfWebrtcConnections() { - return this.getActivePublishers() + this.participants.values().stream() - .filter(p -> !ProtocolElements.RECORDER_PARTICIPANT_PUBLICID.equals(p.getParticipantPublicId())) - .mapToInt(p -> ((KurentoParticipant) p).getSubscribers().size()).reduce(0, Integer::sum); + return this.getActivePublishers() + + this.participants.values().stream().filter(p -> !p.isRecorderOrSttParticipant()) + .mapToInt(p -> ((KurentoParticipant) p).getSubscribers().size()).reduce(0, Integer::sum); } } diff --git a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSessionManager.java b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSessionManager.java index 3ad1a0c9..dfe30521 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSessionManager.java +++ b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSessionManager.java @@ -262,6 +262,12 @@ public class KurentoSessionManager extends SessionManager { // If session is closed by a call to "DELETE /api/sessions" do NOT stop the // recording. Will be stopped after in method // "SessionManager.closeSessionAndEmptyCollections" + + boolean recordingParticipantLeft = (remainingParticipants.size() == 1 + && remainingParticipants.iterator().next().isRecorderParticipant()) + || (remainingParticipants.size() == 2 && remainingParticipants.stream() + .allMatch(p -> p.isRecorderOrSttParticipant())); + if (remainingParticipants.isEmpty()) { if (openviduConfig.isRecordingModuleEnabled() && MediaMode.ROUTED.equals(session.getSessionProperties().mediaMode()) @@ -297,23 +303,19 @@ public class KurentoSessionManager extends SessionManager { sessionId); } } - } else if (remainingParticipants.size() == 1 && openviduConfig.isRecordingModuleEnabled() + } else if (recordingParticipantLeft && openviduConfig.isRecordingModuleEnabled() && MediaMode.ROUTED.equals(session.getSessionProperties().mediaMode()) - && this.recordingManager.sessionIsBeingRecorded(sessionId) - && ProtocolElements.RECORDER_PARTICIPANT_PUBLICID - .equals(remainingParticipants.iterator().next().getParticipantPublicId())) { - // RECORDER participant is the last one standing. Start countdown + && this.recordingManager.sessionIsBeingRecorded(sessionId)) { + // RECORDER or STT participant is the last one standing. Start countdown log.info( "Last participant left. Starting {} seconds countdown for stopping recording of session {}", this.openviduConfig.getOpenviduRecordingAutostopTimeout(), sessionId); recordingManager.initAutomaticRecordingStopThread(session); - } else if (remainingParticipants.size() == 1 && openviduConfig.isRecordingModuleEnabled() + } else if (recordingParticipantLeft && openviduConfig.isRecordingModuleEnabled() && MediaMode.ROUTED.equals(session.getSessionProperties().mediaMode()) && session.getSessionProperties().defaultRecordingProperties().outputMode() - .equals(Recording.OutputMode.COMPOSED_QUICK_START) - && ProtocolElements.RECORDER_PARTICIPANT_PUBLICID - .equals(remainingParticipants.iterator().next().getParticipantPublicId())) { + .equals(Recording.OutputMode.COMPOSED_QUICK_START)) { // If no recordings are active in COMPOSED_QUICK_START output mode, stop // container recordingManager.stopComposedQuickStartContainer(session, reason); @@ -1200,10 +1202,14 @@ public class KurentoSessionManager extends SessionManager { @Override public void onSubscribeToSpeechToText(Participant participant, Integer transactionId, JsonArray connectionIds) { + sessionEventsHandler.onUnsubscribeToSpeechToText(participant, transactionId, new OpenViduException( + Code.WRONG_OPENVIDU_EDITION, "Speech To text requires OpenVidu Pro/Enterprise edition")); } @Override public void onUnsubscribeFromSpeechToText(Participant participant, Integer transactionId, JsonArray connectionIds) { + sessionEventsHandler.onUnsubscribeToSpeechToText(participant, transactionId, new OpenViduException( + Code.WRONG_OPENVIDU_EDITION, "Speech To text requires OpenVidu Pro/Enterprise edition")); } private String mungeSdpOffer(Session kSession, Participant participant, String sdpOffer, boolean isPublisher) { diff --git a/openvidu-server/src/main/java/io/openvidu/server/kurento/kms/Kms.java b/openvidu-server/src/main/java/io/openvidu/server/kurento/kms/Kms.java index e251d4f9..dc964a32 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/kurento/kms/Kms.java +++ b/openvidu-server/src/main/java/io/openvidu/server/kurento/kms/Kms.java @@ -59,6 +59,7 @@ public class Kms { private String id; // Dynamic ID private String uri; private String ip; + private String masterNodePrivateIp; private KurentoClient client; private MediaServer mediaServer; private UpdatableTimerTask clientReconnectTimer; @@ -119,6 +120,14 @@ public class Kms { return ip; } + public String getMasterNodePrivateIp() { + return masterNodePrivateIp; + } + + public void setMasterNodePrivateIp(String masterNodePrivateIp) { + this.masterNodePrivateIp = masterNodePrivateIp; + } + public double getLoad() { return loadManager.calculateLoad(this); } diff --git a/openvidu-server/src/main/java/io/openvidu/server/recording/service/RecordingManager.java b/openvidu-server/src/main/java/io/openvidu/server/recording/service/RecordingManager.java index 6568f617..b0232284 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/recording/service/RecordingManager.java +++ b/openvidu-server/src/main/java/io/openvidu/server/recording/service/RecordingManager.java @@ -673,8 +673,9 @@ public class RecordingManager { if (session.isClosed()) { return; } - if (session.getParticipants().size() == 0 || session.onlyRecorderParticipant()) { - // Close session if there are no participants connected (RECORDER does not + if (session.getParticipants().size() == 0 + || session.onlyRecorderAndOrSttParticipant()) { + // Close session if there are no participants connected (RECORDER or STT do not // count) and publishing log.info("Closing session {} after automatic stop of recording {}", session.getSessionId(), recordingId); @@ -726,10 +727,10 @@ public class RecordingManager { if (session.isClosed()) { return false; } - if (session.getParticipants().size() == 0 || session.onlyRecorderParticipant()) { - // Close session if there are no participants connected (except for RECORDER). - // This code will only be executed if recording is manually stopped during the - // automatic stop timeout, so the session must be also closed + if (session.getParticipants().size() == 0 || session.onlyRecorderAndOrSttParticipant()) { + // Close session if there are no participants connected (except for RECORDER or + // STT). This code will only be executed if recording is manually stopped during + // the automatic stop timeout, so the session must be also closed log.info( "Ongoing recording of session {} was explicetly stopped within timeout for automatic recording stop. Closing session", session.getSessionId()); diff --git a/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java b/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java index ffaf6242..fb7fa324 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java +++ b/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java @@ -48,6 +48,8 @@ import io.openvidu.client.OpenViduException; import io.openvidu.client.OpenViduException.Code; import io.openvidu.client.internal.ProtocolElements; import io.openvidu.java.client.ConnectionProperties; +import io.openvidu.java.client.ConnectionType; +import io.openvidu.java.client.OpenViduRole; import io.openvidu.java.client.utils.FormatChecker; import io.openvidu.server.config.OpenviduBuildInfo; import io.openvidu.server.config.OpenviduConfig; @@ -257,28 +259,43 @@ public class RpcHandler extends DefaultJsonRpcHandler { } boolean recorder = false; - try { recorder = getBooleanParam(request, ProtocolElements.JOINROOM_RECORDER_PARAM); } catch (RuntimeException e) { // Nothing happens. 'recorder' param to false } + boolean stt = false; + try { + stt = getBooleanParam(request, ProtocolElements.JOINROOM_STT_PARAM); + } catch (RuntimeException e) { + // Nothing happens. 'stt' param to false + } + boolean generateRecorderParticipant = false; + boolean generateSttParticipant = false; if (openviduConfig.isOpenViduSecret(secret)) { + + if (recorder) { + generateRecorderParticipant = true; + } else if (stt) { + generateSttParticipant = true; + } + sessionManager.newInsecureParticipant(participantPrivateId); + token = IdentifierPrefixes.TOKEN_ID + RandomStringUtils.randomAlphabetic(1).toUpperCase() + RandomStringUtils.randomAlphanumeric(15); + ConnectionProperties connectionProperties = new ConnectionProperties.Builder().type(ConnectionType.WEBRTC) + .role(OpenViduRole.SUBSCRIBER).build(); + try { - sessionManager.newTokenForInsecureUser(session, token, new ConnectionProperties.Builder().build()); + sessionManager.newTokenForInsecureUser(session, token, connectionProperties); } catch (Exception e) { throw new OpenViduException(Code.TOKEN_CANNOT_BE_CREATED_ERROR_CODE, "Unable to create token for session " + sessionId + ": " + e.getMessage()); } - if (recorder) { - generateRecorderParticipant = true; - } } Token tokenObj = session.consumeToken(token); @@ -298,12 +315,16 @@ public class RpcHandler extends DefaultJsonRpcHandler { if (generateRecorderParticipant) { participant = sessionManager.newRecorderParticipant(session, participantPrivateId, tokenObj, clientMetadata); + } else if (generateSttParticipant) { + participant = sessionManager.newSttParticipant(session, participantPrivateId, tokenObj, + clientMetadata); } else { participant = sessionManager.newParticipant(session, participantPrivateId, tokenObj, clientMetadata, location, platform, httpSession.getId().substring(0, Math.min(16, httpSession.getId().length()))); log.info("New Connection {} in Session {} with IP {} and platform {}", - participant.getParticipantPublicId(), sessionId, remoteAddress.getHostAddress(), + participant.getParticipantPublicId(), sessionId, + remoteAddress != null ? remoteAddress.getHostAddress() : "UNKNOWN", participant.getPlatform()); } @@ -919,7 +940,7 @@ public class RpcHandler extends DefaultJsonRpcHandler { } catch (VersionMismatchException e) { if (e.isIncompatible()) { - if (ProtocolElements.RECORDER_PARTICIPANT_PUBLICID.equals(participant.getParticipantPublicId())) { + if (participant.isRecorderParticipant()) { log.error( "The COMPOSED recording layout is using an incompatible version of openvidu-browser SDK ({}) for this OpenVidu deployment ({}). This may cause the system to malfunction", clientVersion, serverVersion); @@ -936,7 +957,7 @@ public class RpcHandler extends DefaultJsonRpcHandler { } else { DefaultArtifactVersion v = new DefaultArtifactVersion(serverVersion); - if (ProtocolElements.RECORDER_PARTICIPANT_PUBLICID.equals(participant.getParticipantPublicId())) { + if (participant.isRecorderParticipant()) { log.warn( "The COMPOSED recording layout has an older version of openvidu-browser SDK ({}) for this OpenVidu deployment ({}). These versions are still compatible with each other, " + "but client SDK must be updated as soon as possible to {}.x. This recording layout using openvidu-browser {} will become incompatible with the next release of openvidu-server",