openvidu-server: manage INDIVIDUAL recording start uncaught error

pull/707/head
pabloFuente 2022-03-07 13:51:58 +01:00
parent 2ad640f35b
commit 90a665230c
1 changed files with 43 additions and 38 deletions

View File

@ -104,22 +104,26 @@ public class SingleStreamRecordingService extends RecordingService {
int activePublishersToRecord = session.getActiveIndividualRecordedPublishers(); int activePublishersToRecord = session.getActiveIndividualRecordedPublishers();
final CountDownLatch recordingStartedCountdown = new CountDownLatch(activePublishersToRecord); final CountDownLatch recordingStartedCountdown = new CountDownLatch(activePublishersToRecord);
for (Participant p : session.getParticipants()) { try {
if (p.isStreaming() && p.getToken().record()) { for (Participant p : session.getParticipants()) {
if (p.isStreaming() && p.getToken().record()) {
MediaProfileSpecType profile = null; MediaProfileSpecType profile = null;
try { try {
profile = generateMediaProfile(properties, p); profile = generateMediaProfile(properties, p);
} catch (OpenViduException e) { } catch (OpenViduException e) {
log.error( log.error(
"Cannot start single stream recorder for stream {} in session {}: {}. Skipping to next stream being published", "Cannot start single stream recorder for stream {} in session {}: {}. Skipping to next stream being published",
p.getPublisherStreamId(), session.getSessionId(), e.getMessage()); p.getPublisherStreamId(), session.getSessionId(), e.getMessage());
recordingStartedCountdown.countDown(); recordingStartedCountdown.countDown();
continue; continue;
}
this.startRecorderEndpointForPublisherEndpoint(recording.getId(), profile, p,
recordingStartedCountdown);
} }
this.startRecorderEndpointForPublisherEndpoint(recording.getId(), profile, p,
recordingStartedCountdown);
} }
} catch (RecorderEndpointException e) {
throw this.failStartRecording(session, recording, "Couldn't initialize some RecorderEndpoint");
} }
try { try {
@ -127,7 +131,8 @@ public class SingleStreamRecordingService extends RecordingService {
if (!recordingStartedCountdown.await(10, TimeUnit.SECONDS)) { if (!recordingStartedCountdown.await(10, TimeUnit.SECONDS)) {
log.error("Error waiting for some recorder endpoint to start in session {}", log.error("Error waiting for some recorder endpoint to start in session {}",
session.getSessionId()); session.getSessionId());
throw this.failStartRecording(session, recording, "Couldn't initialize some RecorderEndpoint"); throw this.failStartRecording(session, recording,
"Some RecorderEndpoint did not trigger RecordingEvent in time");
} }
} else { } else {
log.info( log.info(
@ -247,8 +252,7 @@ public class SingleStreamRecordingService extends RecordingService {
RecorderEndpoint recorder = new RecorderEndpoint.Builder(pipeline, RecorderEndpoint recorder = new RecorderEndpoint.Builder(pipeline,
"file://" + openviduConfig.getOpenViduRemoteRecordingPath() + recordingId + "/" + fileName "file://" + openviduConfig.getOpenViduRemoteRecordingPath() + recordingId + "/" + fileName
+ fileExtension).withMediaProfile(profile) + fileExtension).withMediaProfile(profile).build();
.build();
recorder.addRecordingListener(new EventListener<RecordingEvent>() { recorder.addRecordingListener(new EventListener<RecordingEvent>() {
@Override @Override
@ -263,10 +267,9 @@ public class SingleStreamRecordingService extends RecordingService {
recorder.addErrorListener(new EventListener<ErrorEvent>() { recorder.addErrorListener(new EventListener<ErrorEvent>() {
@Override @Override
public void onEvent(ErrorEvent event) { public void onEvent(ErrorEvent event) {
final String msg = "Event [" + event.getType() + "] endpoint: " final String msg = "Event [" + event.getType() + "] endpoint: " + recorder.getName()
+ recorder.getName() + " | errorCode: " + event.getErrorCode() + " | errorCode: " + event.getErrorCode() + " | description: "
+ " | description: " + event.getDescription() + " | timestamp: " + event.getDescription() + " | timestamp: " + event.getTimestampMillis();
+ event.getTimestampMillis();
log.error(msg); log.error(msg);
} }
}); });
@ -282,7 +285,12 @@ public class SingleStreamRecordingService extends RecordingService {
connectAccordingToProfile(kurentoParticipant.getPublisher(), recorder, profile); connectAccordingToProfile(kurentoParticipant.getPublisher(), recorder, profile);
wrapper.getRecorder().record(); try {
wrapper.getRecorder().record();
} catch (Exception e) {
log.error("Error on RecorderEndpoint: " + e.getMessage());
throw new RecorderEndpointException();
}
} finally { } finally {
participant.singleRecordingLock.unlock(); participant.singleRecordingLock.unlock();
@ -376,29 +384,26 @@ public class SingleStreamRecordingService extends RecordingService {
if (!streamHasAudio && !streamHasVideo) { if (!streamHasAudio && !streamHasVideo) {
// ERROR: Stream has no track at all. This branch should never be reachable // ERROR: Stream has no track at all. This branch should never be reachable
throw new OpenViduException( throw new OpenViduException(Code.MEDIA_TYPE_STREAM_INCOMPATIBLE_WITH_RECORDING_PROPERTIES_ERROR_CODE,
Code.MEDIA_TYPE_STREAM_INCOMPATIBLE_WITH_RECORDING_PROPERTIES_ERROR_CODE,
"Stream has no track at all. Cannot be recorded"); "Stream has no track at all. Cannot be recorded");
} }
if (!propertiesHasAudio && !propertiesHasVideo) { if (!propertiesHasAudio && !propertiesHasVideo) {
// ERROR: Properties don't enable any track. This branch should never be reachable // ERROR: Properties don't enable any track. This branch should never be
throw new OpenViduException( // reachable
Code.MEDIA_TYPE_RECORDING_PROPERTIES_ERROR_CODE, throw new OpenViduException(Code.MEDIA_TYPE_RECORDING_PROPERTIES_ERROR_CODE,
"RecordingProperties cannot set both \"hasAudio(false)\" and \"hasVideo(false)\""); "RecordingProperties cannot set both \"hasAudio(false)\" and \"hasVideo(false)\"");
} }
boolean streamOnlyAudio = streamHasAudio && !streamHasVideo; boolean streamOnlyAudio = streamHasAudio && !streamHasVideo;
if (streamOnlyAudio && !propertiesHasAudio) { if (streamOnlyAudio && !propertiesHasAudio) {
throw new OpenViduException( throw new OpenViduException(Code.MEDIA_TYPE_STREAM_INCOMPATIBLE_WITH_RECORDING_PROPERTIES_ERROR_CODE,
Code.MEDIA_TYPE_STREAM_INCOMPATIBLE_WITH_RECORDING_PROPERTIES_ERROR_CODE,
"RecordingProperties set to \"hasAudio(false)\" but stream is audio-only"); "RecordingProperties set to \"hasAudio(false)\" but stream is audio-only");
} }
boolean streamOnlyVideo = !streamHasAudio && streamHasVideo; boolean streamOnlyVideo = !streamHasAudio && streamHasVideo;
if (streamOnlyVideo & !propertiesHasVideo) { if (streamOnlyVideo & !propertiesHasVideo) {
throw new OpenViduException( throw new OpenViduException(Code.MEDIA_TYPE_STREAM_INCOMPATIBLE_WITH_RECORDING_PROPERTIES_ERROR_CODE,
Code.MEDIA_TYPE_STREAM_INCOMPATIBLE_WITH_RECORDING_PROPERTIES_ERROR_CODE,
"RecordingProperties set to \"hasVideo(false)\" but stream is video-only"); "RecordingProperties set to \"hasVideo(false)\" but stream is video-only");
} }
@ -408,11 +413,9 @@ public class SingleStreamRecordingService extends RecordingService {
boolean recordVideo = streamHasVideo && propertiesHasVideo; boolean recordVideo = streamHasVideo && propertiesHasVideo;
if (recordAudio && recordVideo) { if (recordAudio && recordVideo) {
profile = openviduConfig.getMediaServer().getRecordingProfile(); profile = openviduConfig.getMediaServer().getRecordingProfile();
} } else if (recordAudio) {
else if (recordAudio) {
profile = openviduConfig.getMediaServer().getRecordingProfileAudioOnly(); profile = openviduConfig.getMediaServer().getRecordingProfileAudioOnly();
} } else if (recordVideo) {
else if (recordVideo) {
profile = openviduConfig.getMediaServer().getRecordingProfileVideoOnly(); profile = openviduConfig.getMediaServer().getRecordingProfileVideoOnly();
} }
@ -425,11 +428,9 @@ public class SingleStreamRecordingService extends RecordingService {
// already connected when `RecorderEndpoint.record()` is called. // already connected when `RecorderEndpoint.record()` is called.
if (profile.name().contains("AUDIO_ONLY")) { if (profile.name().contains("AUDIO_ONLY")) {
publisherEndpoint.connect(recorder, MediaType.AUDIO, true); publisherEndpoint.connect(recorder, MediaType.AUDIO, true);
} } else if (profile.name().contains("VIDEO_ONLY")) {
else if (profile.name().contains("VIDEO_ONLY")) {
publisherEndpoint.connect(recorder, MediaType.VIDEO, true); publisherEndpoint.connect(recorder, MediaType.VIDEO, true);
} } else {
else {
publisherEndpoint.connect(recorder, MediaType.AUDIO, true); publisherEndpoint.connect(recorder, MediaType.AUDIO, true);
publisherEndpoint.connect(recorder, MediaType.VIDEO, true); publisherEndpoint.connect(recorder, MediaType.VIDEO, true);
} }
@ -578,4 +579,8 @@ public class SingleStreamRecordingService extends RecordingService {
this.activeRecorders.remove(recording.getId()); this.activeRecorders.remove(recording.getId());
} }
class RecorderEndpointException extends RuntimeException {
private static final long serialVersionUID = 1L;
}
} }