Skip to content

Commit

Permalink
Merge pull request #667 from OpenVidu/forcecodec-preferred
Browse files Browse the repository at this point in the history
ForcedVideoCodec default set to MEDIA_SERVER_PREFERRED
  • Loading branch information
j1elo authored Jan 20, 2022
2 parents 31f5206 + bfa2ad8 commit 46c7516
Show file tree
Hide file tree
Showing 18 changed files with 188 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;

Expand Down Expand Up @@ -661,16 +662,17 @@ private void getSessionHttp() throws OpenViduJavaClientException, OpenViduHttpEx
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;
Expand Down Expand Up @@ -718,6 +720,9 @@ protected Session resetWithJson(JsonObject json) {
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());
}
Expand Down Expand Up @@ -756,19 +761,15 @@ protected String toJson() {
JsonObject json = new JsonObject();
json.addProperty("sessionId", this.sessionId);
json.addProperty("createdAt", this.createdAt);
json.addProperty("customSessionId", this.properties.customSessionId());
json.addProperty("recording", this.recording);
json.addProperty("mediaMode", this.properties.mediaMode().name());
json.addProperty("recordingMode", this.properties.recordingMode().name());
if (this.properties.defaultRecordingProperties() != null) {
json.add("defaultRecordingProperties", this.properties.defaultRecordingProperties().toJson());
}
if (this.properties.forcedVideoCodec() != null) {
json.addProperty("forcedVideoCodec", this.properties.forcedVideoCodec().name());
}
if (this.properties.isTranscodingAllowed() != null) {
json.addProperty("allowTranscoding", this.properties.isTranscodingAllowed());

// Add keys from SessionProperties
JsonObject sessionPropertiesJson = this.properties.toJson();
for (Map.Entry<String, JsonElement> entry : sessionPropertiesJson.entrySet()) {
json.add(entry.getKey(), entry.getValue().deepCopy());
}

// Add "connections" object
JsonObject connections = new JsonObject();
connections.addProperty("numberOfElements", this.getConnections().size());
JsonArray jsonArrayConnections = new JsonArray();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class SessionProperties {
private String customSessionId;
private String mediaNode;
private VideoCodec forcedVideoCodec;
private VideoCodec forcedVideoCodecResolved;
private Boolean allowTranscoding;

/**
Expand All @@ -42,7 +43,8 @@ public static class Builder {
private RecordingProperties defaultRecordingProperties = new RecordingProperties.Builder().build();
private String customSessionId = "";
private String mediaNode;
private VideoCodec forcedVideoCodec = VideoCodec.VP8;
private VideoCodec forcedVideoCodec = VideoCodec.MEDIA_SERVER_PREFERRED;
private VideoCodec forcedVideoCodecResolved = VideoCodec.NONE;
private Boolean allowTranscoding = false;

/**
Expand All @@ -51,7 +53,8 @@ public static class Builder {
*/
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);
}

/**
Expand Down Expand Up @@ -114,21 +117,37 @@ public SessionProperties.Builder mediaNode(String mediaNodeId) {
}

/**
* Call this method to define which video codec do you want to be forcibly used
* for this session. This allows browsers/clients to use the same codec avoiding
* transcoding in the media server. If the browser/client is not compatible with
* the specified codec and {@link #allowTranscoding(Boolean)} is
* <code>false</code> and exception will occur. If forcedVideoCodec is set to
* NONE, no codec will be forced.<br>
* Define which video codec will be forcibly used for this session.
* This forces all browsers/clients to use the same codec, which would
* avoid transcoding in the media server (Kurento only). If
* <code>forcedVideoCodec</code> is set to NONE, no codec will be forced.
*
* If the browser/client is not compatible with the specified codec, and
* {@link #allowTranscoding(Boolean)} is <code>false</code>, an
* exception will occur.
*
* If defined here, this parameter has prevalence over
* OPENVIDU_STREAMS_FORCED_VIDEO_CODEC. OPENVIDU_STREAMS_FORCED_VIDEO_CODEC
* default is {@link VideoCodec#VP8}
* OPENVIDU_STREAMS_FORCED_VIDEO_CODEC.
*
* 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 <code>forcedVideoCodec</code>, 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
Expand All @@ -154,13 +173,14 @@ protected 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;
}

Expand Down Expand Up @@ -217,12 +237,24 @@ public String mediaNode() {
}

/**
* 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.
Expand All @@ -231,22 +263,25 @@ public Boolean isTranscodingAllowed() {
return this.allowTranscoding;
}

protected JsonObject toJson() {
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) {
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 (this.forcedVideoCodecResolved != null) {
json.addProperty("forcedVideoCodecResolved", this.forcedVideoCodecResolved.name());
}
if (isTranscodingAllowed() != null) {
json.addProperty("allowTranscoding", isTranscodingAllowed());
if (this.allowTranscoding != null) {
json.addProperty("allowTranscoding", this.allowTranscoding);
}
return json;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@
* {@link io.openvidu.java.client.SessionProperties.Builder#forcedVideoCodec(VideoCodec)}
*/
public enum VideoCodec {
VP8, VP9, H264, NONE
}
MEDIA_SERVER_PREFERRED, NONE, VP8, VP9, H264
}
14 changes: 11 additions & 3 deletions openvidu-node-client/src/Session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}
Expand Down Expand Up @@ -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 = {};
Expand Down
31 changes: 23 additions & 8 deletions openvidu-node-client/src/SessionProperties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export interface SessionProperties {
customSessionId?: string;

/**
* **This feature is part of OpenVidu Pro tier** <a href="https://docs.openvidu.io/en/stable/openvidu-pro/" target="_blank" style="display: inline-block; background-color: rgb(0, 136, 170); color: white; font-weight: bold; padding: 0px 5px; margin-right: 5px; border-radius: 3px; font-size: 13px; line-height:21px; font-family: Montserrat, sans-serif">PRO</a>
* **This feature is part of OpenVidu Pro tier** <a href="https://docs.openvidu.io/en/stable/openvidu-pro/" target="_blank" style="display: inline-block; background-color: rgb(0, 136, 170); color: white; font-weight: bold; padding: 0px 5px; margin-right: 5px; border-radius: 3px; font-size: 13px; line-height:21px; font-family: Montserrat, sans-serif">PRO</a>
*
* The Media Node where to host the session. The default option if this property is not defined is the less loaded
* Media Node at the moment the first user joins the session. This object defines the following properties as Media Node selector:
Expand All @@ -67,16 +67,32 @@ export interface SessionProperties {
}

/**
* It defines which video codec do you want to be forcibly used for this session.
* This allows browsers/clients to use the same codec avoiding transcoding in the media server.
* If the browser/client is not compatible with the specified codec and [[allowTranscoding]] is <code>false</code>
* and exception will occur. If forcedVideoCodec is set to [[VideoCodec.NONE]], no codec will be forced.
* Define which video codec will be forcibly used for this session.
* This forces all browsers/clients to use the same codec, which would
* avoid transcoding in the media server (Kurento only). If
* <code>forcedVideoCodec</code> is set to NONE, no codec will be forced.
*
* If defined here, this parameter has prevalence over OPENVIDU_STREAMS_FORCED_VIDEO_CODEC.
* OPENVIDU_STREAMS_FORCED_VIDEO_CODEC default is [[VideoCodec.VP8]]
* If the browser/client is not compatible with the specified codec, and
* [[allowTranscoding]] is <code>false</code>, an exception will occur.
*
* If defined here, this parameter has prevalence over
* OPENVIDU_STREAMS_FORCED_VIDEO_CODEC.
*
* Default is [[VideoCodec.MEDIA_SERVER_PREFERRED]].
*/
forcedVideoCodec?: VideoCodec;

/**
* Actual video codec that will be forcibly used for this session.
* This is the same as <code>forcedVideoCodec</code>, 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.
Expand All @@ -85,5 +101,4 @@ export interface SessionProperties {
* OPENVIDU_STREAMS_ALLOW_TRANSCODING default is 'false'
*/
allowTranscoding?: boolean;

}
7 changes: 3 additions & 4 deletions openvidu-node-client/src/VideoCodec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
* See [[SessionProperties.forcedVideoCodec]]
*/
export enum VideoCodec {

MEDIA_SERVER_PREFERRED = 'MEDIA_SERVER_PREFERRED',
NONE = 'NONE',
VP8 = 'VP8',
VP9 = 'VP9',
H264 = 'H264',
NONE = 'NONE'

}
}
6 changes: 3 additions & 3 deletions openvidu-server/deployments/ce/docker-compose/.env
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,9 @@ OPENVIDU_STREAMS_VIDEO_MIN_SEND_BANDWIDTH=300

# All sessions of OpenVidu will try to force this codec. If OPENVIDU_STREAMS_ALLOW_TRANSCODING=true
# when a codec can not be forced, transcoding will be allowed
# Values: VP8, VP9, H264, NONE
# Default value is VP8
# OPENVIDU_STREAMS_FORCED_VIDEO_CODEC=VP8
# Values: MEDIA_SERVER_PREFERRED, NONE, VP8, VP9, H264
# Default value is MEDIA_SERVER_PREFERRED
# OPENVIDU_STREAMS_FORCED_VIDEO_CODEC=MEDIA_SERVER_PREFERRED

# Allow transcoding if codec specified in OPENVIDU_STREAMS_FORCED_VIDEO_CODEC can not be applied
# Values: true | false
Expand Down
6 changes: 3 additions & 3 deletions openvidu-server/deployments/enterprise/master-node/.env
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,9 @@ OPENVIDU_STREAMS_VIDEO_MIN_SEND_BANDWIDTH=300

# All sessions of OpenVidu will try to force this codec. If OPENVIDU_STREAMS_ALLOW_TRANSCODING=true
# when a codec can not be forced, transcoding will be allowed
# Values: VP8, VP9, H264, NONE
# Default value is VP8
# OPENVIDU_STREAMS_FORCED_VIDEO_CODEC=VP8
# Values: MEDIA_SERVER_PREFERRED, NONE, VP8, VP9, H264
# Default value is MEDIA_SERVER_PREFERRED
# OPENVIDU_STREAMS_FORCED_VIDEO_CODEC=MEDIA_SERVER_PREFERRED

# Allow transcoding if codec specified in OPENVIDU_STREAMS_FORCED_VIDEO_CODEC can not be applied
# Values: true | false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,9 @@ OPENVIDU_STREAMS_VIDEO_MIN_SEND_BANDWIDTH=300

# All sessions of OpenVidu will try to force this codec. If OPENVIDU_STREAMS_ALLOW_TRANSCODING=true
# when a codec can not be forced, transcoding will be allowed
# Values: VP8, VP9, H264, NONE
# Default value is VP8
# OPENVIDU_STREAMS_FORCED_VIDEO_CODEC=VP8
# Values: MEDIA_SERVER_PREFERRED, NONE, VP8, VP9, H264
# Default value is MEDIA_SERVER_PREFERRED
# OPENVIDU_STREAMS_FORCED_VIDEO_CODEC=MEDIA_SERVER_PREFERRED

# Allow transcoding if codec specified in OPENVIDU_STREAMS_FORCED_VIDEO_CODEC can not be applied
# Values: true | false
Expand Down
Loading

0 comments on commit 46c7516

Please sign in to comment.