From 718c7f9e634a5b3df64817e29f5f519c0b0f078e Mon Sep 17 00:00:00 2001 From: pabloFuente Date: Thu, 24 Jan 2019 14:44:48 +0100 Subject: [PATCH] openvidu-server: recording small fixes (duplicate recording start notification, do not init automatic stop on session closed by API REST, loggin improved) --- .../kurento/core/KurentoSessionManager.java | 75 ++++++++++--------- .../service/ComposedRecordingService.java | 33 ++++++-- .../recording/service/RecordingService.java | 9 ++- .../service/SingleStreamRecordingService.java | 13 +++- 4 files changed, 87 insertions(+), 43 deletions(-) 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 dfe690d4..79e0de49 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 @@ -169,41 +169,48 @@ public class KurentoSessionManager extends SessionManager { sessionEventsHandler.onParticipantLeft(participant, sessionId, remainingParticipants, transactionId, null, reason); - if (remainingParticipants.isEmpty()) { - if (openviduConfig.isRecordingModuleEnabled() + if (!"sessionClosedByServer".equals(reason)) { + // If session is closed by a call to "DELETE /api/sessions" do NOT stop the + // recording. Will be stopped after in method + // "SessionManager.closeSessionAndEmptyCollections" + if (remainingParticipants.isEmpty()) { + if (openviduConfig.isRecordingModuleEnabled() + && MediaMode.ROUTED.equals(session.getSessionProperties().mediaMode()) + && (this.recordingManager.sessionIsBeingRecordedIndividual(sessionId) + || (this.recordingManager.sessionIsBeingRecordedComposed(sessionId) + && this.recordingManager.sessionIsBeingRecordedOnlyAudio(sessionId)))) { + // Start countdown to stop recording if INDIVIDUAL mode or COMPOSED audio-only + // (will be aborted if a Publisher starts before timeout) + log.info( + "Last participant left. Starting {} seconds countdown for stopping recording of session {}", + this.openviduConfig.getOpenviduRecordingAutostopTimeout(), sessionId); + recordingManager.initAutomaticRecordingStopThread(session); + } else { + log.info("No more participants in session '{}', removing it and closing it", sessionId); + this.closeSessionAndEmptyCollections(session, reason); + showTokens(); + } + } else if (remainingParticipants.size() == 1 && openviduConfig.isRecordingModuleEnabled() && MediaMode.ROUTED.equals(session.getSessionProperties().mediaMode()) - && (this.recordingManager.sessionIsBeingRecordedIndividual(sessionId) - || (this.recordingManager.sessionIsBeingRecordedComposed(sessionId) - && this.recordingManager.sessionIsBeingRecordedOnlyAudio(sessionId)))) { - // Start countdown to stop recording if INDIVIDUAL mode or COMPOSED audio-only - // (will be aborted if a Publisher starts before timeout) - log.info("Last participant left. Starting {} seconds countdown for stopping recording of session {}", - this.openviduConfig.getOpenviduRecordingAutostopTimeout(), sessionId); - recordingManager.initAutomaticRecordingStopThread(session); - } else { - log.info("No more participants in session '{}', removing it and closing it", sessionId); - this.closeSessionAndEmptyCollections(session, reason); - showTokens(); - } - } else if (remainingParticipants.size() == 1 && openviduConfig.isRecordingModuleEnabled() - && MediaMode.ROUTED.equals(session.getSessionProperties().mediaMode()) - && this.recordingManager.sessionIsBeingRecordedComposed(sessionId) - && !this.recordingManager.sessionIsBeingRecordedOnlyAudio(sessionId) - && ProtocolElements.RECORDER_PARTICIPANT_PUBLICID - .equals(remainingParticipants.iterator().next().getParticipantPublicId())) { - if (RecordingMode.ALWAYS.equals(session.getSessionProperties().recordingMode())) { - // Immediately stop recording when last real participant left if - // RecordingMode.ALWAYS - log.info("Last participant left. Stopping recording for session {}", sessionId); - recordingManager.stopRecording(session, null, reason); - evictParticipant(session.getParticipantByPublicId(ProtocolElements.RECORDER_PARTICIPANT_PUBLICID), null, - null, "EVICT_RECORDER"); - } else if (RecordingMode.MANUAL.equals(session.getSessionProperties().recordingMode())) { - // Start countdown to stop recording if RecordingMode.MANUAL (will be aborted if - // a Publisher starts before timeout) - log.info("Last participant left. Starting {} seconds countdown for stopping recording of session {}", - this.openviduConfig.getOpenviduRecordingAutostopTimeout(), sessionId); - recordingManager.initAutomaticRecordingStopThread(session); + && this.recordingManager.sessionIsBeingRecordedComposed(sessionId) + && !this.recordingManager.sessionIsBeingRecordedOnlyAudio(sessionId) + && ProtocolElements.RECORDER_PARTICIPANT_PUBLICID + .equals(remainingParticipants.iterator().next().getParticipantPublicId())) { + if (RecordingMode.ALWAYS.equals(session.getSessionProperties().recordingMode())) { + // Immediately stop recording when last real participant left if + // RecordingMode.ALWAYS + log.info("Last participant left. Stopping recording for session {}", sessionId); + recordingManager.stopRecording(session, null, reason); + evictParticipant(session.getParticipantByPublicId(ProtocolElements.RECORDER_PARTICIPANT_PUBLICID), + null, null, "EVICT_RECORDER"); + } else if (RecordingMode.MANUAL.equals(session.getSessionProperties().recordingMode())) { + // Start countdown to stop recording if RecordingMode.MANUAL (will be aborted if + // a Publisher starts before timeout) + log.info( + "Last participant left. Starting {} seconds countdown for stopping recording of session {}", + this.openviduConfig.getOpenviduRecordingAutostopTimeout(), sessionId); + recordingManager.initAutomaticRecordingStopThread(session); + } } } diff --git a/openvidu-server/src/main/java/io/openvidu/server/recording/service/ComposedRecordingService.java b/openvidu-server/src/main/java/io/openvidu/server/recording/service/ComposedRecordingService.java index b6a10b06..47460524 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/recording/service/ComposedRecordingService.java +++ b/openvidu-server/src/main/java/io/openvidu/server/recording/service/ComposedRecordingService.java @@ -93,8 +93,8 @@ public class ComposedRecordingService extends RecordingService { recording = this.startRecordingAudioOnly(session, recording, properties); } - // Update collections and return recording - this.updateCollectionsAndSendNotifCauseRecordingStarted(session, recording); + this.updateRecordingManagerCollections(session, recording); + return recording; } @@ -111,7 +111,7 @@ public class ComposedRecordingService extends RecordingService { throws OpenViduException { log.info("Joining single stream {} to Composite in session {}", participant.getPublisherStreamId(), session.getSessionId()); - + KurentoParticipant kurentoParticipant = (KurentoParticipant) participant; CompositeWrapper compositeWrapper = this.composites.get(session.getSessionId()); @@ -132,6 +132,10 @@ public class ComposedRecordingService extends RecordingService { private Recording startRecordingWithVideo(Session session, Recording recording, RecordingProperties properties) throws OpenViduException { + + log.info("Starting composed ({}) recording {} of session {}", + properties.hasAudio() ? "video + audio" : "audio-only", recording.getId(), recording.getSessionId()); + List envs = new ArrayList<>(); String layoutUrl = this.getLayoutUrl(recording, this.getShortSessionId(session)); @@ -173,6 +177,9 @@ public class ComposedRecordingService extends RecordingService { private Recording startRecordingAudioOnly(Session session, Recording recording, RecordingProperties properties) throws OpenViduException { + log.info("Starting composed (audio-only) recording {} of session {}", recording.getId(), + recording.getSessionId()); + CompositeWrapper compositeWrapper = new CompositeWrapper((KurentoSession) session, "file://" + this.openviduConfig.getOpenViduRecordingPath() + recording.getId() + "/" + properties.name() + ".webm"); @@ -191,12 +198,17 @@ public class ComposedRecordingService extends RecordingService { } this.generateRecordingMetadataFile(recording); + this.sendRecordingStartedNotification(session, recording); return recording; } private Recording stopRecordingWithVideo(Session session, Recording recording, String reason) { + log.info("Stopping composed ({}) recording {} of session {}. Reason: {}", + recording.hasAudio() ? "video + audio" : "audio-only", recording.getId(), recording.getSessionId(), + RecordingManager.finalReason(reason)); + String containerId = this.sessionsContainers.remove(recording.getSessionId()); this.cleanRecordingMaps(recording); @@ -218,13 +230,14 @@ public class ComposedRecordingService extends RecordingService { log.warn("Session closed while starting recording container"); boolean containerClosed = false; String containerIdAux; - int timeOut = 0; - while (!containerClosed && (timeOut < 30)) { + int i = 0; + final int timeout = 30; + while (!containerClosed && (i < timeout)) { containerIdAux = this.sessionsContainers.remove(session.getSessionId()); if (containerIdAux == null) { try { log.warn("Waiting for container to be launched..."); - timeOut++; + i++; Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); @@ -244,6 +257,10 @@ public class ComposedRecordingService extends RecordingService { } } } + if (i == timeout) { + log.error("Container did not launched in {} seconds", timeout / 2); + return; + } }).start(); } else { @@ -309,6 +326,10 @@ public class ComposedRecordingService extends RecordingService { } private Recording stopRecordingAudioOnly(Session session, Recording recording, String reason) { + + log.info("Stopping composed (audio-only) recording {} of session {}. Reason: {}", recording.getId(), + recording.getSessionId(), reason); + String sessionId; if (session == null) { log.warn( diff --git a/openvidu-server/src/main/java/io/openvidu/server/recording/service/RecordingService.java b/openvidu-server/src/main/java/io/openvidu/server/recording/service/RecordingService.java index 725455a2..780ab1a3 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/recording/service/RecordingService.java +++ b/openvidu-server/src/main/java/io/openvidu/server/recording/service/RecordingService.java @@ -83,11 +83,17 @@ public abstract class RecordingService { * Changes recording from starting to started, updates global recording * collections and sends RPC response to clients */ - protected void updateCollectionsAndSendNotifCauseRecordingStarted(Session session, Recording recording) { + protected void updateRecordingManagerCollections(Session session, Recording recording) { this.recordingManager.sessionHandler.setRecordingStarted(session.getSessionId(), recording); this.recordingManager.sessionsRecordings.put(session.getSessionId(), recording); this.recordingManager.startingRecordings.remove(recording.getId()); this.recordingManager.startedRecordings.put(recording.getId(), recording); + } + + /** + * Sends RPC response for recording started event + */ + protected void sendRecordingStartedNotification(Session session, Recording recording) { this.recordingManager.getSessionEventsHandler().sendRecordingStartedNotification(session, recording); } @@ -126,6 +132,7 @@ public abstract class RecordingService { } protected OpenViduException failStartRecording(Session session, Recording recording, String errorMessage) { + log.error("Recording start failed for session {}: {}", session.getSessionId(), errorMessage); recording.setStatus(io.openvidu.java.client.Recording.Status.failed); this.recordingManager.startingRecordings.remove(recording.getId()); this.stopRecording(session, recording, null); diff --git a/openvidu-server/src/main/java/io/openvidu/server/recording/service/SingleStreamRecordingService.java b/openvidu-server/src/main/java/io/openvidu/server/recording/service/SingleStreamRecordingService.java index dcfa2e82..0b544f15 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/recording/service/SingleStreamRecordingService.java +++ b/openvidu-server/src/main/java/io/openvidu/server/recording/service/SingleStreamRecordingService.java @@ -78,7 +78,11 @@ public class SingleStreamRecordingService extends RecordingService { properties); properties = updatePropertiesAndRecordingId.properties; String recordingId = updatePropertiesAndRecordingId.recordingId; - + + log.info("Starting individual ({}) recording {} of session {}", + properties.hasVideo() ? (properties.hasAudio() ? "video+audio" : "video-only") : "audioOnly", + recordingId, session.getSessionId()); + Recording recording = new Recording(session.getSessionId(), recordingId, properties); this.recordingManager.startingRecordings.put(recording.getId(), recording); @@ -120,7 +124,8 @@ public class SingleStreamRecordingService extends RecordingService { } this.generateRecordingMetadataFile(recording); - this.updateCollectionsAndSendNotifCauseRecordingStarted(session, recording); + this.updateRecordingManagerCollections(session, recording); + this.sendRecordingStartedNotification(session, recording); return recording; } @@ -128,6 +133,10 @@ public class SingleStreamRecordingService extends RecordingService { @Override public Recording stopRecording(Session session, Recording recording, String reason) { + log.info("Stopping individual ({}) recording {} of session {}. Reason: {}", + recording.hasVideo() ? (recording.hasAudio() ? "video+audio" : "video-only") : "audioOnly", + recording.getId(), recording.getSessionId(), reason); + final int numberOfActiveRecorders = recorders.get(recording.getSessionId()).size(); final CountDownLatch stoppedCountDown = new CountDownLatch(numberOfActiveRecorders);