openvidu-server: add MKV recording profile as part of MediaServer enum (#658)

Uses the MediaServer enum to contain information that is specific about
each particular media server. Specifically,

* kurento must record with the WEBM profile and ".webm" file extension
* mediasoup must record with the MKV profile and ".mkv" file extension

Integrating this as part of the global Openvidu config object makes it
trivial to replace the static or hardcoded lines with others that simply
obtain the data from the current media server mode in use.
pull/664/head
Juan Navarro 2021-11-02 11:40:42 +01:00 committed by GitHub
parent 4882bb89a2
commit a7332aac70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 48 additions and 25 deletions

View File

@ -1,7 +1,29 @@
package io.openvidu.server.core;
import org.kurento.client.MediaProfileSpecType;
public enum MediaServer {
kurento(MediaProfileSpecType.WEBM), mediasoup(MediaProfileSpecType.MKV);
kurento, mediasoup
private final MediaProfileSpecType recordingProfile;
MediaServer(MediaProfileSpecType recordingProfile) {
this.recordingProfile = recordingProfile;
}
public MediaProfileSpecType getRecordingProfile() {
return recordingProfile;
}
public MediaProfileSpecType getRecordingProfileAudioOnly() {
return MediaProfileSpecType.valueOf(recordingProfile.name() + "_AUDIO_ONLY");
}
public MediaProfileSpecType getRecordingProfileVideoOnly() {
return MediaProfileSpecType.valueOf(recordingProfile.name() + "_VIDEO_ONLY");
}
public String getRecordingFileExtension() {
return "." + recordingProfile.name().toLowerCase();
}
}

View File

@ -30,6 +30,7 @@ public class RecorderEndpointWrapper {
private RecorderEndpoint recorder;
private KurentoParticipant kParticipant;
private String name;
private String fileExtension;
private String connectionId;
private String recordingId;
private String streamId;
@ -44,8 +45,9 @@ public class RecorderEndpointWrapper {
private long size;
public RecorderEndpointWrapper(RecorderEndpoint recorder, KurentoParticipant kParticipant, String recordingId,
String name) {
String name, String fileExtension) {
this.name = name;
this.fileExtension = fileExtension;
this.recorder = recorder;
this.kParticipant = kParticipant;
this.recordingId = recordingId;
@ -58,10 +60,11 @@ public class RecorderEndpointWrapper {
this.typeOfVideo = kParticipant.getPublisher().getMediaOptions().getTypeOfVideo();
}
public RecorderEndpointWrapper(JsonObject json) {
public RecorderEndpointWrapper(JsonObject json, String fileExtension) {
String nameAux = json.get("name").getAsString();
// If the name includes the extension, remove it
this.name = StringUtils.removeEnd(nameAux, RecordingService.INDIVIDUAL_RECORDING_EXTENSION);
this.name = StringUtils.removeEnd(nameAux, fileExtension);
this.fileExtension = fileExtension;
this.connectionId = json.get("connectionId").getAsString();
this.streamId = json.get("streamId").getAsString();
this.clientData = (json.has("clientData") && !json.get("clientData").isJsonNull())
@ -91,7 +94,7 @@ public class RecorderEndpointWrapper {
}
public String getNameWithExtension() {
return this.name + RecordingService.INDIVIDUAL_RECORDING_EXTENSION;
return this.name + fileExtension;
}
public String getConnectionId() {

View File

@ -764,7 +764,7 @@ public class RecordingManager {
final String testFolderPath = openviduRecordingPath + "/TEST_RECORDING_PATH_" + System.currentTimeMillis();
final String testFilePath = testFolderPath + "/TEST_RECORDING_PATH"
+ RecordingService.INDIVIDUAL_RECORDING_EXTENSION;
+ openviduConfig.getMediaServer().getRecordingFileExtension();
// Check Kurento Media Server write permissions in recording path
if (this.kmsManager.getKmss().isEmpty()) {

View File

@ -54,9 +54,9 @@ public abstract class RecordingService {
public final static String RECORDING_ENTITY_FILE = ".recording.";
public final static String COMPOSED_RECORDING_EXTENSION = ".mp4";
public final static String COMPOSED_RECORDING_AUDIO_ONLY_EXTENSION = ".webm";
public final static String COMPOSED_THUMBNAIL_EXTENSION = ".jpg";
public final static String COMPOSED_INFO_FILE_EXTENSION = ".info";
public final static String INDIVIDUAL_RECORDING_EXTENSION = ".webm";
public final static String INDIVIDUAL_STREAM_METADATA_FILE = ".stream.";
public final static String INDIVIDUAL_RECORDING_COMPRESSED_EXTENSION = ".zip";

View File

@ -240,13 +240,14 @@ public class SingleStreamRecordingService extends RecordingService {
final List<RecorderEndpointWrapper> wrapperList = storedRecorders.get(recordingId).get(streamId);
final int streamCounter = wrapperList != null ? wrapperList.size() : 0;
String fileName = streamCounter == 0 ? streamId : (streamId + "-" + streamCounter);
String fileExtension = openviduConfig.getMediaServer().getRecordingFileExtension();
KurentoParticipant kurentoParticipant = (KurentoParticipant) participant;
MediaPipeline pipeline = kurentoParticipant.getPublisher().getPipeline();
RecorderEndpoint recorder = new RecorderEndpoint.Builder(pipeline,
"file://" + openviduConfig.getOpenViduRemoteRecordingPath() + recordingId + "/" + fileName
+ RecordingService.INDIVIDUAL_RECORDING_EXTENSION).withMediaProfile(profile)
+ fileExtension).withMediaProfile(profile)
.build();
recorder.addRecordingListener(new EventListener<RecordingEvent>() {
@ -271,7 +272,7 @@ public class SingleStreamRecordingService extends RecordingService {
});
RecorderEndpointWrapper wrapper = new RecorderEndpointWrapper(recorder, kurentoParticipant,
recordingId, fileName);
recordingId, fileName, fileExtension);
activeRecorders.get(recordingId).put(streamId, wrapper);
if (wrapperList != null) {
wrapperList.add(wrapper);
@ -406,13 +407,13 @@ public class SingleStreamRecordingService extends RecordingService {
boolean recordAudio = streamHasAudio && propertiesHasAudio;
boolean recordVideo = streamHasVideo && propertiesHasVideo;
if (recordAudio && recordVideo) {
profile = MediaProfileSpecType.WEBM;
profile = openviduConfig.getMediaServer().getRecordingProfile();
}
else if (recordAudio) {
profile = MediaProfileSpecType.WEBM_AUDIO_ONLY;
profile = openviduConfig.getMediaServer().getRecordingProfileAudioOnly();
}
else if (recordVideo) {
profile = MediaProfileSpecType.WEBM_VIDEO_ONLY;
profile = openviduConfig.getMediaServer().getRecordingProfileVideoOnly();
}
return profile;
@ -422,19 +423,15 @@ public class SingleStreamRecordingService extends RecordingService {
MediaProfileSpecType profile) {
// Perform blocking connections, to ensure that elements are
// already connected when `RecorderEndpoint.record()` is called.
switch (profile) {
case WEBM:
if (profile.name().contains("AUDIO_ONLY")) {
publisherEndpoint.connect(recorder, MediaType.AUDIO, true);
}
else if (profile.name().contains("VIDEO_ONLY")) {
publisherEndpoint.connect(recorder, MediaType.VIDEO, true);
}
else {
publisherEndpoint.connect(recorder, MediaType.AUDIO, true);
publisherEndpoint.connect(recorder, MediaType.VIDEO, true);
break;
case WEBM_AUDIO_ONLY:
publisherEndpoint.connect(recorder, MediaType.AUDIO, true);
break;
case WEBM_VIDEO_ONLY:
publisherEndpoint.connect(recorder, MediaType.VIDEO, true);
break;
default:
throw new UnsupportedOperationException("Unsupported profile when single stream recording: " + profile);
}
}
@ -491,7 +488,8 @@ public class SingleStreamRecordingService extends RecordingService {
log.error("Error reading file {}. Error: {}", files[i].getAbsolutePath(), e.getMessage());
}
RecorderEndpointWrapper wr = new RecorderEndpointWrapper(
JsonParser.parseReader(reader).getAsJsonObject());
JsonParser.parseReader(reader).getAsJsonObject(),
openviduConfig.getMediaServer().getRecordingFileExtension());
minStartTime = Math.min(minStartTime, wr.getStartTime());
maxEndTime = Math.max(maxEndTime, wr.getEndTime());
accumulatedSize += wr.getSize();
@ -542,7 +540,7 @@ public class SingleStreamRecordingService extends RecordingService {
String fileExtension = FilenameUtils.getExtension(files[i].getName());
if (files[i].isFile() && (fileExtension.equals("json")
|| RecordingService.INDIVIDUAL_RECORDING_EXTENSION.equals("." + fileExtension))) {
|| openviduConfig.getMediaServer().getRecordingFileExtension().equals("." + fileExtension))) {
// Zip video files and json sync metadata file
FileInputStream fis = new FileInputStream(files[i]);