diff --git a/openvidu-java-client/src/main/java/io/openvidu/java/client/Session.java b/openvidu-java-client/src/main/java/io/openvidu/java/client/Session.java
index 6bd50536..451d3862 100644
--- a/openvidu-java-client/src/main/java/io/openvidu/java/client/Session.java
+++ b/openvidu-java-client/src/main/java/io/openvidu/java/client/Session.java
@@ -662,16 +662,17 @@ public class Session {
this.sessionId = responseJson.get("id").getAsString();
this.createdAt = responseJson.get("createdAt").getAsLong();
- // forcedVideoCodec and allowTranscoding values are configured in OpenVidu
- // Server via configuration or session
+ // Values that get filled by OpenVidu Server from its global or per-session configuration
VideoCodec forcedVideoCodec = VideoCodec.valueOf(responseJson.get("forcedVideoCodec").getAsString());
+ VideoCodec forcedVideoCodecResolved = VideoCodec
+ .valueOf(responseJson.get("forcedVideoCodecResolved").getAsString());
Boolean allowTranscoding = responseJson.get("allowTranscoding").getAsBoolean();
- SessionProperties responseProperties = new SessionProperties.Builder()
- .customSessionId(properties.customSessionId()).mediaMode(properties.mediaMode())
+ SessionProperties responseProperties = new SessionProperties.Builder().mediaMode(properties.mediaMode())
.recordingMode(properties.recordingMode())
.defaultRecordingProperties(properties.defaultRecordingProperties())
- .mediaNode(properties.mediaNode()).forcedVideoCodec(forcedVideoCodec)
+ .customSessionId(properties.customSessionId()).mediaNode(properties.mediaNode())
+ .forcedVideoCodec(forcedVideoCodec).forcedVideoCodecResolved(forcedVideoCodecResolved)
.allowTranscoding(allowTranscoding).build();
this.properties = responseProperties;
@@ -719,6 +720,9 @@ public class Session {
if (json.has("forcedVideoCodec")) {
builder.forcedVideoCodec(VideoCodec.valueOf(json.get("forcedVideoCodec").getAsString()));
}
+ if (json.has("forcedVideoCodecResolved")) {
+ builder.forcedVideoCodecResolved(VideoCodec.valueOf(json.get("forcedVideoCodecResolved").getAsString()));
+ }
if (json.has("allowTranscoding")) {
builder.allowTranscoding(json.get("allowTranscoding").getAsBoolean());
}
diff --git a/openvidu-java-client/src/main/java/io/openvidu/java/client/SessionProperties.java b/openvidu-java-client/src/main/java/io/openvidu/java/client/SessionProperties.java
index 10392c77..4ca54a22 100644
--- a/openvidu-java-client/src/main/java/io/openvidu/java/client/SessionProperties.java
+++ b/openvidu-java-client/src/main/java/io/openvidu/java/client/SessionProperties.java
@@ -30,6 +30,7 @@ public class SessionProperties {
private String customSessionId;
private String mediaNode;
private VideoCodec forcedVideoCodec;
+ private VideoCodec forcedVideoCodecResolved;
private Boolean allowTranscoding;
/**
@@ -43,6 +44,7 @@ public class SessionProperties {
private String customSessionId = "";
private String mediaNode;
private VideoCodec forcedVideoCodec = VideoCodec.MEDIA_SERVER_PREFERRED;
+ private VideoCodec forcedVideoCodecResolved = VideoCodec.NONE;
private Boolean allowTranscoding = false;
/**
@@ -51,7 +53,8 @@ public class SessionProperties {
*/
public SessionProperties build() {
return new SessionProperties(this.mediaMode, this.recordingMode, this.defaultRecordingProperties,
- this.customSessionId, this.mediaNode, this.forcedVideoCodec, this.allowTranscoding);
+ this.customSessionId, this.mediaNode, this.forcedVideoCodec, this.forcedVideoCodecResolved,
+ this.allowTranscoding);
}
/**
@@ -126,14 +129,25 @@ public class SessionProperties {
* If defined here, this parameter has prevalence over
* OPENVIDU_STREAMS_FORCED_VIDEO_CODEC.
*
- * Default is {@link VideoCodec#VP8} for Kurento, and
- * {@link VideoCodec#NONE} for mediasoup.
+ * Default is {@link VideoCodec#MEDIA_SERVER_PREFERRED}.
*/
public SessionProperties.Builder forcedVideoCodec(VideoCodec forcedVideoCodec) {
this.forcedVideoCodec = forcedVideoCodec;
return this;
}
+ /**
+ * Actual video codec that will be forcibly used for this session.
+ * This is the same as forcedVideoCodec
, except when its
+ * value is {@link VideoCodec#MEDIA_SERVER_PREFERRED}: in that case,
+ * OpenVidu Server will fill this property with a resolved value,
+ * depending on what is the configured media server.
+ */
+ public SessionProperties.Builder forcedVideoCodecResolved(VideoCodec forcedVideoCodec) {
+ this.forcedVideoCodecResolved = forcedVideoCodec;
+ return this;
+ }
+
/**
* Call this method to define if you want to allow transcoding in the media
* server or not when {@link #forcedVideoCodec(VideoCodec)} is not compatible
@@ -159,13 +173,14 @@ public class SessionProperties {
private SessionProperties(MediaMode mediaMode, RecordingMode recordingMode,
RecordingProperties defaultRecordingProperties, String customSessionId, String mediaNode,
- VideoCodec forcedVideoCodec, Boolean allowTranscoding) {
+ VideoCodec forcedVideoCodec, VideoCodec forcedVideoCodecResolved, Boolean allowTranscoding) {
this.mediaMode = mediaMode;
this.recordingMode = recordingMode;
this.defaultRecordingProperties = defaultRecordingProperties;
this.customSessionId = customSessionId;
this.mediaNode = mediaNode;
this.forcedVideoCodec = forcedVideoCodec;
+ this.forcedVideoCodecResolved = forcedVideoCodecResolved;
this.allowTranscoding = allowTranscoding;
}
@@ -222,12 +237,24 @@ public class SessionProperties {
}
/**
- * Defines which video codec is being forced to be used in the browser/client
+ * Defines which video codec is being forced to be used in the browser/client.
+ * This is the raw value that was configured. It might get resolved into a
+ * different one for actual usage in the server.
*/
public VideoCodec forcedVideoCodec() {
return this.forcedVideoCodec;
}
+ /**
+ * Defines which video codec is being forced to be used in the browser/client.
+ * This is the resolved value, for actual usage in the server.
+ *
+ * @hidden
+ */
+ public VideoCodec forcedVideoCodecResolved() {
+ return this.forcedVideoCodecResolved;
+ }
+
/**
* Defines if transcoding is allowed or not when {@link #forcedVideoCodec} is
* not a compatible codec with the browser/client.
@@ -238,20 +265,23 @@ public class SessionProperties {
public JsonObject toJson() {
JsonObject json = new JsonObject();
- json.addProperty("mediaMode", mediaMode().name());
- json.addProperty("recordingMode", recordingMode().name());
- json.addProperty("customSessionId", customSessionId());
- json.add("defaultRecordingProperties", defaultRecordingProperties.toJson());
- if (mediaNode() != null && !mediaNode().isEmpty()) {
+ json.addProperty("mediaMode", this.mediaMode.name());
+ json.addProperty("recordingMode", this.recordingMode.name());
+ json.add("defaultRecordingProperties", this.defaultRecordingProperties.toJson());
+ json.addProperty("customSessionId", this.customSessionId);
+ if (this.mediaNode != null && !this.mediaNode.isEmpty()) {
JsonObject mediaNodeJson = new JsonObject();
- mediaNodeJson.addProperty("id", mediaNode());
+ mediaNodeJson.addProperty("id", this.mediaNode);
json.add("mediaNode", mediaNodeJson);
}
- if (forcedVideoCodec() != null) {
- json.addProperty("forcedVideoCodec", forcedVideoCodec().name());
+ if (this.forcedVideoCodec != null) {
+ json.addProperty("forcedVideoCodec", this.forcedVideoCodec.name());
}
- if (isTranscodingAllowed() != null) {
- json.addProperty("allowTranscoding", isTranscodingAllowed());
+ if (this.forcedVideoCodecResolved != null) {
+ json.addProperty("forcedVideoCodecResolved", this.forcedVideoCodecResolved.name());
+ }
+ if (this.allowTranscoding != null) {
+ json.addProperty("allowTranscoding", this.allowTranscoding);
}
return json;
}
diff --git a/openvidu-node-client/src/Session.ts b/openvidu-node-client/src/Session.ts
index 718709b5..9ca089a2 100644
--- a/openvidu-node-client/src/Session.ts
+++ b/openvidu-node-client/src/Session.ts
@@ -490,6 +490,7 @@ export class Session {
this.properties.defaultRecordingProperties = res.data.defaultRecordingProperties;
this.properties.mediaNode = res.data.mediaNode;
this.properties.forcedVideoCodec = res.data.forcedVideoCodec;
+ this.properties.forcedVideoCodecResolved = res.data.forcedVideoCodecResolved;
this.properties.allowTranscoding = res.data.allowTranscoding;
this.sanitizeDefaultSessionProperties(this.properties);
resolve(this.sessionId);
@@ -533,6 +534,7 @@ export class Session {
recordingMode: json.recordingMode,
defaultRecordingProperties: json.defaultRecordingProperties,
forcedVideoCodec: json.forcedVideoCodec,
+ forcedVideoCodecResolved: json.forcedVideoCodecResolved,
allowTranscoding: json.allowTranscoding
};
this.sanitizeDefaultSessionProperties(this.properties);
@@ -548,6 +550,9 @@ export class Session {
if (json.forcedVideoCodec == null) {
delete this.properties.forcedVideoCodec;
}
+ if (json.forcedVideoCodecResolved == null) {
+ delete this.properties.forcedVideoCodecResolved;
+ }
if (json.allowTranscoding == null) {
delete this.properties.allowTranscoding;
}
@@ -655,9 +660,12 @@ export class Session {
props.mediaMode = (props.mediaMode != null) ? props.mediaMode : MediaMode.ROUTED;
props.recordingMode = (props.recordingMode != null) ? props.recordingMode : RecordingMode.MANUAL;
props.customSessionId = (props.customSessionId != null) ? props.customSessionId : '';
- props.mediaNode = (props.mediaNode != null) ? props.mediaNode : undefined;
- props.forcedVideoCodec = props.forcedVideoCodec;
- props.allowTranscoding = props.allowTranscoding;
+
+ // Remove null values: either set, or undefined
+ props.mediaNode = props.mediaNode ?? undefined;
+ props.forcedVideoCodec = props.forcedVideoCodec ?? undefined;
+ props.forcedVideoCodecResolved = props.forcedVideoCodecResolved ?? undefined;
+ props.allowTranscoding = props.allowTranscoding ?? undefined;
if (!props.defaultRecordingProperties) {
props.defaultRecordingProperties = {};
diff --git a/openvidu-node-client/src/SessionProperties.ts b/openvidu-node-client/src/SessionProperties.ts
index adb4b145..9b23203a 100644
--- a/openvidu-node-client/src/SessionProperties.ts
+++ b/openvidu-node-client/src/SessionProperties.ts
@@ -78,11 +78,21 @@ export interface SessionProperties {
* If defined here, this parameter has prevalence over
* OPENVIDU_STREAMS_FORCED_VIDEO_CODEC.
*
- * Default is [[VideoCodec.VP8]] for Kurento, and
- * [[VideoCodec.NONE]] for mediasoup.
+ * Default is [[VideoCodec.MEDIA_SERVER_PREFERRED]].
*/
forcedVideoCodec?: VideoCodec;
+ /**
+ * Actual video codec that will be forcibly used for this session.
+ * This is the same as forcedVideoCodec
, except when its value
+ * is [[VideoCodec.MEDIA_SERVER_PREFERRED]]: in that case, OpenVidu Server
+ * will fill this property with a resolved value, depending on what is the
+ * configured media server.
+ *
+ * @hidden
+ */
+ forcedVideoCodecResolved?: VideoCodec;
+
/**
* It defines if you want to allow transcoding in the media server or not
* when [[forcedVideoCodec]] is not compatible with the browser/client.
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 e2fa865d..da0bd0fa 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
@@ -380,7 +380,7 @@ public class KurentoSessionManager extends SessionManager {
KurentoParticipant kParticipant = (KurentoParticipant) participant;
KurentoSession kSession = kParticipant.getSession();
boolean isTranscodingAllowed = kSession.getSessionProperties().isTranscodingAllowed();
- VideoCodec forcedVideoCodec = kSession.getSessionProperties().forcedVideoCodec();
+ VideoCodec forcedVideoCodec = kSession.getSessionProperties().forcedVideoCodecResolved();
final String streamId = kParticipant.generateStreamId(kurentoOptions);
@@ -392,22 +392,6 @@ public class KurentoSessionManager extends SessionManager {
log.warn("AllowTranscoding has no effect if the Media Server is not Kurento");
}
- // Set appropriate value for the ForcedVideoCodec feature.
- if (forcedVideoCodec == VideoCodec.MEDIA_SERVER_PREFERRED) {
- final MediaServer mediaServer = openviduConfig.getMediaServer();
- switch (mediaServer) {
- case mediasoup:
- forcedVideoCodec = VideoCodec.NONE;
- break;
- case kurento:
- default:
- forcedVideoCodec = VideoCodec.VP8;
- break;
- }
-
- log.info("Media Server: {}, selected ForcedVideoCodec value: {}", mediaServer, forcedVideoCodec);
- }
-
// Modify sdp if forced codec is defined
if (forcedVideoCodec != VideoCodec.NONE && !participant.isIpcam()) {
kurentoOptions.sdpOffer = sdpMunging.forceCodec(kurentoOptions.sdpOffer, participant, true, false,
@@ -613,7 +597,7 @@ public class KurentoSessionManager extends SessionManager {
WebrtcDebugEventType.sdpOffer, sdpOffer));
boolean isTranscodingAllowed = session.getSessionProperties().isTranscodingAllowed();
- VideoCodec forcedVideoCodec = session.getSessionProperties().forcedVideoCodec();
+ VideoCodec forcedVideoCodec = session.getSessionProperties().forcedVideoCodecResolved();
// Modify server's SDPOffer if forced codec is defined
if (forcedVideoCodec != VideoCodec.NONE && !participant.isIpcam()) {
@@ -679,7 +663,7 @@ public class KurentoSessionManager extends SessionManager {
// Client initiated negotiation. sdpString is the SDP Offer of the client
boolean isTranscodingAllowed = session.getSessionProperties().isTranscodingAllowed();
- VideoCodec forcedVideoCodec = session.getSessionProperties().forcedVideoCodec();
+ VideoCodec forcedVideoCodec = session.getSessionProperties().forcedVideoCodecResolved();
String sdpOffer = sdpString;
// Modify sdp if forced codec is defined
@@ -1236,7 +1220,7 @@ public class KurentoSessionManager extends SessionManager {
private String mungeSdpOffer(Session kSession, Participant participant, String sdpOffer, boolean isPublisher) {
boolean isTranscodingAllowed = kSession.getSessionProperties().isTranscodingAllowed();
- VideoCodec forcedVideoCodec = kSession.getSessionProperties().forcedVideoCodec();
+ VideoCodec forcedVideoCodec = kSession.getSessionProperties().forcedVideoCodecResolved();
// Modify sdp if forced codec is defined
if (forcedVideoCodec != VideoCodec.NONE && !participant.isIpcam()) {
return sdpMunging.forceCodec(sdpOffer, participant, isPublisher, true, isTranscodingAllowed,
diff --git a/openvidu-server/src/main/java/io/openvidu/server/rest/SessionRestController.java b/openvidu-server/src/main/java/io/openvidu/server/rest/SessionRestController.java
index 6e9e9889..cc7d40e1 100644
--- a/openvidu-server/src/main/java/io/openvidu/server/rest/SessionRestController.java
+++ b/openvidu-server/src/main/java/io/openvidu/server/rest/SessionRestController.java
@@ -726,20 +726,31 @@ public class SessionRestController {
if (params != null) {
+ // Obtain primitive values from the params map
String mediaModeString;
String recordingModeString;
- String forcedVideoCodec;
+ String forcedVideoCodecStr;
Boolean allowTranscoding;
try {
mediaModeString = (String) params.get("mediaMode");
recordingModeString = (String) params.get("recordingMode");
customSessionId = (String) params.get("customSessionId");
- forcedVideoCodec = (String) params.get("forcedVideoCodec");
+ forcedVideoCodecStr = (String) params.get("forcedVideoCodec");
allowTranscoding = (Boolean) params.get("allowTranscoding");
} catch (ClassCastException e) {
throw new Exception("Type error in some parameter: " + e.getMessage());
}
+ // Parse obtained values into actual types
+ VideoCodec forcedVideoCodec = null;
+ try {
+ forcedVideoCodec = VideoCodec.valueOf(forcedVideoCodecStr);
+ } catch (NullPointerException e) {
+ // Not an error: "forcedVideoCodec" was not provided in params.
+ } catch (IllegalArgumentException e) {
+ throw new Exception("Invalid value for parameter 'forcedVideoCodec': " + e.getMessage());
+ }
+
try {
// Safe parameter retrieval. Default values if not defined
if (recordingModeString != null) {
@@ -761,11 +772,25 @@ public class SessionRestController {
}
builder = builder.customSessionId(customSessionId);
}
- if (forcedVideoCodec != null) {
- builder = builder.forcedVideoCodec(VideoCodec.valueOf(forcedVideoCodec));
- } else {
- builder = builder.forcedVideoCodec(openviduConfig.getOpenviduForcedCodec());
+
+ if (forcedVideoCodec == null) {
+ forcedVideoCodec = openviduConfig.getOpenviduForcedCodec();
}
+ builder = builder.forcedVideoCodec(forcedVideoCodec);
+ if (forcedVideoCodec == VideoCodec.MEDIA_SERVER_PREFERRED) {
+ switch (openviduConfig.getMediaServer()) {
+ case mediasoup:
+ builder = builder.forcedVideoCodecResolved(VideoCodec.NONE);
+ break;
+ case kurento:
+ default:
+ builder = builder.forcedVideoCodecResolved(VideoCodec.VP8);
+ break;
+ }
+ } else {
+ builder = builder.forcedVideoCodecResolved(forcedVideoCodec);
+ }
+
if (allowTranscoding != null) {
builder = builder.allowTranscoding(allowTranscoding);
} else {
diff --git a/openvidu-server/src/main/java/io/openvidu/server/utils/SDPMunging.java b/openvidu-server/src/main/java/io/openvidu/server/utils/SDPMunging.java
index c30febce..b4a4803f 100644
--- a/openvidu-server/src/main/java/io/openvidu/server/utils/SDPMunging.java
+++ b/openvidu-server/src/main/java/io/openvidu/server/utils/SDPMunging.java
@@ -187,7 +187,7 @@ public class SDPMunging {
return mungedSdpOffer;
} else {
throw new OpenViduException(Code.FORCED_CODEC_NOT_FOUND_IN_SDPOFFER,
- "Codec not supported by Media Server");
+ "Codec not supported by Media Server: " + forcedVideoCodec);
}
} catch (OpenViduException e) {