diff --git a/openvidu-client/src/main/java/io/openvidu/client/internal/ProtocolElements.java b/openvidu-client/src/main/java/io/openvidu/client/internal/ProtocolElements.java
index 2f819127..7a218a48 100644
--- a/openvidu-client/src/main/java/io/openvidu/client/internal/ProtocolElements.java
+++ b/openvidu-client/src/main/java/io/openvidu/client/internal/ProtocolElements.java
@@ -17,113 +17,130 @@
package io.openvidu.client.internal;
/**
- * This class defines constant values of client-server messages and their parameters.
+ * This class defines constant values of client-server messages and their
+ * parameters.
*
* @author Radu Tom Vlad
*/
public class ProtocolElements {
- // ---------------------------- CLIENT REQUESTS -----------------------
+ // ---------------------------- CLIENT REQUESTS -----------------------
- public static final String SENDMESSAGE_ROOM_METHOD = "sendMessage";
- public static final String SENDMESSAGE_MESSAGE_PARAM = "message";
+ public static final String SENDMESSAGE_ROOM_METHOD = "sendMessage";
+ public static final String SENDMESSAGE_MESSAGE_PARAM = "message";
- public static final String LEAVEROOM_METHOD = "leaveRoom";
+ public static final String LEAVEROOM_METHOD = "leaveRoom";
- public static final String JOINROOM_METHOD = "joinRoom";
- public static final String JOINROOM_USER_PARAM = "user";
- public static final String JOINROOM_TOKEN_PARAM = "token";
- public static final String JOINROOM_ROOM_PARAM = "session";
- public static final String JOINROOM_METADATA_PARAM = "metadata";
- public static final String JOINROOM_SECRET_PARAM = "secret";
- public static final String JOINROOM_RECORDER_PARAM = "recorder";
-
- public static final String JOINROOM_PEERID_PARAM = "id";
- public static final String JOINROOM_PEERSTREAMS_PARAM = "streams";
- public static final String JOINROOM_PEERSTREAMID_PARAM = "id";
- public static final String JOINROOM_PEERSTREAMAUDIOACTIVE_PARAM = "audioActive";
- public static final String JOINROOM_PEERSTREAMVIDEOACTIVE_PARAM = "videoActive";
- public static final String JOINROOM_PEERSTREAMTYPEOFVIDEO_PARAM = "typeOfVideo";
- public static final String JOINROOM_PEERSTREAMFRAMERATE_PARAM = "frameRate";
+ public static final String JOINROOM_METHOD = "joinRoom";
+ public static final String JOINROOM_USER_PARAM = "user";
+ public static final String JOINROOM_TOKEN_PARAM = "token";
+ public static final String JOINROOM_ROOM_PARAM = "session";
+ public static final String JOINROOM_METADATA_PARAM = "metadata";
+ public static final String JOINROOM_SECRET_PARAM = "secret";
+ public static final String JOINROOM_RECORDER_PARAM = "recorder";
- public static final String PUBLISHVIDEO_METHOD = "publishVideo";
- public static final String PUBLISHVIDEO_SDPOFFER_PARAM = "sdpOffer";
- public static final String PUBLISHVIDEO_DOLOOPBACK_PARAM = "doLoopback";
- public static final String PUBLISHVIDEO_SDPANSWER_PARAM = "sdpAnswer";
- public static final String PUBLISHVIDEO_STREAMID_PARAM = "id";
- public static final String PUBLISHVIDEO_AUDIOACTIVE_PARAM = "audioActive";
- public static final String PUBLISHVIDEO_VIDEOACTIVE_PARAM = "videoActive";
- public static final String PUBLISHVIDEO_TYPEOFVIDEO_PARAM = "typeOfVideo";
- public static final String PUBLISHVIDEO_FRAMERATE_PARAM = "frameRate";
+ public static final String JOINROOM_PEERID_PARAM = "id";
+ public static final String JOINROOM_PEERSTREAMS_PARAM = "streams";
+ public static final String JOINROOM_PEERSTREAMID_PARAM = "id";
+ public static final String JOINROOM_PEERSTREAMHASAUDIO_PARAM = "hasAudio";
+ public static final String JOINROOM_PEERSTREAMHASVIDEO_PARAM = "hasVideo";
+ public static final String JOINROOM_PEERSTREAMAUDIOACTIVE_PARAM = "audioActive";
+ public static final String JOINROOM_PEERSTREAMVIDEOACTIVE_PARAM = "videoActive";
+ public static final String JOINROOM_PEERSTREAMTYPEOFVIDEO_PARAM = "typeOfVideo";
+ public static final String JOINROOM_PEERSTREAMFRAMERATE_PARAM = "frameRate";
+ public static final String JOINROOM_PEERSTREAMVIDEODIMENSIONS_PARAM = "videoDimensions";
- public static final String UNPUBLISHVIDEO_METHOD = "unpublishVideo";
+ public static final String PUBLISHVIDEO_METHOD = "publishVideo";
+ public static final String PUBLISHVIDEO_SDPOFFER_PARAM = "sdpOffer";
+ public static final String PUBLISHVIDEO_DOLOOPBACK_PARAM = "doLoopback";
+ public static final String PUBLISHVIDEO_SDPANSWER_PARAM = "sdpAnswer";
+ public static final String PUBLISHVIDEO_STREAMID_PARAM = "id";
+ public static final String PUBLISHVIDEO_HASAUDIO_PARAM = "hasAudio";
+ public static final String PUBLISHVIDEO_HASVIDEO_PARAM = "hasVideo";
+ public static final String PUBLISHVIDEO_AUDIOACTIVE_PARAM = "audioActive";
+ public static final String PUBLISHVIDEO_VIDEOACTIVE_PARAM = "videoActive";
+ public static final String PUBLISHVIDEO_TYPEOFVIDEO_PARAM = "typeOfVideo";
+ public static final String PUBLISHVIDEO_FRAMERATE_PARAM = "frameRate";
+ public static final String PUBLISHVIDEO_VIDEODIMENSIONS_PARAM = "videoDimensions";
- public static final String RECEIVEVIDEO_METHOD = "receiveVideoFrom";
- public static final String RECEIVEVIDEO_SDPOFFER_PARAM = "sdpOffer";
- public static final String RECEIVEVIDEO_SENDER_PARAM = "sender";
- public static final String RECEIVEVIDEO_SDPANSWER_PARAM = "sdpAnswer";
+ public static final String UNPUBLISHVIDEO_METHOD = "unpublishVideo";
- public static final String UNSUBSCRIBEFROMVIDEO_METHOD = "unsubscribeFromVideo";
- public static final String UNSUBSCRIBEFROMVIDEO_SENDER_PARAM = "sender";
+ public static final String RECEIVEVIDEO_METHOD = "receiveVideoFrom";
+ public static final String RECEIVEVIDEO_SDPOFFER_PARAM = "sdpOffer";
+ public static final String RECEIVEVIDEO_SENDER_PARAM = "sender";
+ public static final String RECEIVEVIDEO_SDPANSWER_PARAM = "sdpAnswer";
- public static final String ONICECANDIDATE_METHOD = "onIceCandidate";
- public static final String ONICECANDIDATE_EPNAME_PARAM = "endpointName";
- public static final String ONICECANDIDATE_CANDIDATE_PARAM = "candidate";
- public static final String ONICECANDIDATE_SDPMIDPARAM = "sdpMid";
- public static final String ONICECANDIDATE_SDPMLINEINDEX_PARAM = "sdpMLineIndex";
+ public static final String UNSUBSCRIBEFROMVIDEO_METHOD = "unsubscribeFromVideo";
+ public static final String UNSUBSCRIBEFROMVIDEO_SENDER_PARAM = "sender";
- public static final String CUSTOMREQUEST_METHOD = "customRequest";
+ public static final String ONICECANDIDATE_METHOD = "onIceCandidate";
+ public static final String ONICECANDIDATE_EPNAME_PARAM = "endpointName";
+ public static final String ONICECANDIDATE_CANDIDATE_PARAM = "candidate";
+ public static final String ONICECANDIDATE_SDPMIDPARAM = "sdpMid";
+ public static final String ONICECANDIDATE_SDPMLINEINDEX_PARAM = "sdpMLineIndex";
- // ---------------------------- SERVER RESPONSES & EVENTS -----------------
+ public static final String CUSTOMREQUEST_METHOD = "customRequest";
- public static final String PARTICIPANTJOINED_METHOD = "participantJoined";
- public static final String PARTICIPANTJOINED_USER_PARAM = "id";
- public static final String PARTICIPANTJOINED_METADATA_PARAM = "metadata";
+ public static final String STREAMPROPERTYCHANGED_METHOD = "streamPropertyChanged";
+ public static final String STREAMPROPERTYCHANGED_CONNECTIONID_PARAM = "connectionId";
+ public static final String STREAMPROPERTYCHANGED_STREAMID_PARAM = "streamId";
+ public static final String STREAMPROPERTYCHANGED_PROPERTY_PARAM = "property";
+ public static final String STREAMPROPERTYCHANGED_NEWVALUE_PARAM = "newValue";
+ public static final String STREAMPROPERTYCHANGED_REASON_PARAM = "reason";
- public static final String PARTICIPANTLEFT_METHOD = "participantLeft";
- public static final String PARTICIPANTLEFT_NAME_PARAM = "name";
- public static final String PARTICIPANTLEFT_REASON_PARAM = "reason";
+ // ---------------------------- SERVER RESPONSES & EVENTS -----------------
- public static final String PARTICIPANTEVICTED_METHOD = "participantEvicted";
+ public static final String PARTICIPANTJOINED_METHOD = "participantJoined";
+ public static final String PARTICIPANTJOINED_USER_PARAM = "id";
+ public static final String PARTICIPANTJOINED_METADATA_PARAM = "metadata";
- public static final String PARTICIPANTPUBLISHED_METHOD = "participantPublished";
- public static final String PARTICIPANTPUBLISHED_USER_PARAM = "id";
- public static final String PARTICIPANTPUBLISHED_STREAMS_PARAM = "streams";
- public static final String PARTICIPANTPUBLISHED_STREAMID_PARAM = "id";
- public static final String PARTICIPANTPUBLISHED_AUDIOACTIVE_PARAM = "audioActive";
- public static final String PARTICIPANTPUBLISHED_VIDEOACTIVE_PARAM = "videoActive";
- public static final String PARTICIPANTPUBLISHED_TYPEOFVIDEO_PARAM = "typeOfVideo";
- public static final String PARTICIPANTPUBLISHED_FRAMERATE_PARAM = "frameRate";
-
- public static final String PARTICIPANTUNPUBLISHED_METHOD = "participantUnpublished";
- public static final String PARTICIPANTUNPUBLISHED_NAME_PARAM = "name";
- public static final String PARTICIPANTUNPUBLISHED_REASON_PARAM = "reason";
+ public static final String PARTICIPANTLEFT_METHOD = "participantLeft";
+ public static final String PARTICIPANTLEFT_NAME_PARAM = "name";
+ public static final String PARTICIPANTLEFT_REASON_PARAM = "reason";
- public static final String PARTICIPANTSENDMESSAGE_METHOD = "sendMessage";
- public static final String PARTICIPANTSENDMESSAGE_DATA_PARAM = "data";
- public static final String PARTICIPANTSENDMESSAGE_FROM_PARAM = "from";
- public static final String PARTICIPANTSENDMESSAGE_TYPE_PARAM = "type";
+ public static final String PARTICIPANTEVICTED_METHOD = "participantEvicted";
- public static final String ROOMCLOSED_METHOD = "roomClosed";
- public static final String ROOMCLOSED_ROOM_PARAM = "room";
+ public static final String PARTICIPANTPUBLISHED_METHOD = "participantPublished";
+ public static final String PARTICIPANTPUBLISHED_USER_PARAM = "id";
+ public static final String PARTICIPANTPUBLISHED_STREAMS_PARAM = "streams";
+ public static final String PARTICIPANTPUBLISHED_STREAMID_PARAM = "id";
+ public static final String PARTICIPANTPUBLISHED_HASAUDIO_PARAM = "hasAudio";
+ public static final String PARTICIPANTPUBLISHED_HASVIDEO_PARAM = "hasVideo";
+ public static final String PARTICIPANTPUBLISHED_AUDIOACTIVE_PARAM = "audioActive";
+ public static final String PARTICIPANTPUBLISHED_VIDEOACTIVE_PARAM = "videoActive";
+ public static final String PARTICIPANTPUBLISHED_TYPEOFVIDEO_PARAM = "typeOfVideo";
+ public static final String PARTICIPANTPUBLISHED_FRAMERATE_PARAM = "frameRate";
+ public static final String PARTICIPANTPUBLISHED_VIDEODIMENSIONS_PARAM = "videoDimensions";
- public static final String MEDIAERROR_METHOD = "mediaError";
- public static final String MEDIAERROR_ERROR_PARAM = "error";
+ public static final String PARTICIPANTUNPUBLISHED_METHOD = "participantUnpublished";
+ public static final String PARTICIPANTUNPUBLISHED_NAME_PARAM = "name";
+ public static final String PARTICIPANTUNPUBLISHED_REASON_PARAM = "reason";
- public static final String ICECANDIDATE_METHOD = "iceCandidate";
- public static final String ICECANDIDATE_EPNAME_PARAM = "endpointName";
- public static final String ICECANDIDATE_CANDIDATE_PARAM = "candidate";
- public static final String ICECANDIDATE_SDPMID_PARAM = "sdpMid";
- public static final String ICECANDIDATE_SDPMLINEINDEX_PARAM = "sdpMLineIndex";
-
- public static final String RECORDINGSTARTED_METHOD = "recordingStarted";
- public static final String RECORDINGSTARTED_ID_PARAM = "id";
- public static final String RECORDINGSTARTED_NAME_PARAM = "name";
-
- public static final String RECORDINGSTOPPED_METHOD = "recordingStopped";
- public static final String RECORDINGSTOPPED_ID_PARAM = "id";
+ public static final String PARTICIPANTSENDMESSAGE_METHOD = "sendMessage";
+ public static final String PARTICIPANTSENDMESSAGE_DATA_PARAM = "data";
+ public static final String PARTICIPANTSENDMESSAGE_FROM_PARAM = "from";
+ public static final String PARTICIPANTSENDMESSAGE_TYPE_PARAM = "type";
- public static final String CUSTOM_NOTIFICATION = "custonNotification";
-
- public static final String RECORDER_PARTICIPANT_PUBLICID = "RECORDER";
+ public static final String ROOMCLOSED_METHOD = "roomClosed";
+ public static final String ROOMCLOSED_ROOM_PARAM = "room";
+
+ public static final String MEDIAERROR_METHOD = "mediaError";
+ public static final String MEDIAERROR_ERROR_PARAM = "error";
+
+ public static final String ICECANDIDATE_METHOD = "iceCandidate";
+ public static final String ICECANDIDATE_EPNAME_PARAM = "endpointName";
+ public static final String ICECANDIDATE_CANDIDATE_PARAM = "candidate";
+ public static final String ICECANDIDATE_SDPMID_PARAM = "sdpMid";
+ public static final String ICECANDIDATE_SDPMLINEINDEX_PARAM = "sdpMLineIndex";
+
+ public static final String RECORDINGSTARTED_METHOD = "recordingStarted";
+ public static final String RECORDINGSTARTED_ID_PARAM = "id";
+ public static final String RECORDINGSTARTED_NAME_PARAM = "name";
+
+ public static final String RECORDINGSTOPPED_METHOD = "recordingStopped";
+ public static final String RECORDINGSTOPPED_ID_PARAM = "id";
+
+ public static final String CUSTOM_NOTIFICATION = "custonNotification";
+
+ public static final String RECORDER_PARTICIPANT_PUBLICID = "RECORDER";
}
diff --git a/openvidu-server/src/main/java/io/openvidu/server/cdr/CDREvent.java b/openvidu-server/src/main/java/io/openvidu/server/cdr/CDREvent.java
index 348edde5..430c9f7d 100644
--- a/openvidu-server/src/main/java/io/openvidu/server/cdr/CDREvent.java
+++ b/openvidu-server/src/main/java/io/openvidu/server/cdr/CDREvent.java
@@ -122,11 +122,11 @@ public class CDREvent implements Comparable {
}
if (this.mediaOptions != null) {
json.put("connection", this.receivingFrom != null ? "INBOUND" : "OUTBOUND");
- json.put("audioEnabled", this.mediaOptions.audioActive);
- json.put("videoEnabled", this.mediaOptions.videoActive);
- if (this.mediaOptions.videoActive) {
- json.put("videoSource", this.mediaOptions.typeOfVideo);
- json.put("videoFramerate", this.mediaOptions.frameRate);
+ json.put("audioEnabled", this.mediaOptions.hasAudio());
+ json.put("videoEnabled", this.mediaOptions.hasVideo());
+ if (this.mediaOptions.hasVideo()) {
+ json.put("videoSource", this.mediaOptions.getTypeOfVideo());
+ json.put("videoFramerate", this.mediaOptions.getFrameRate());
}
if (this.receivingFrom != null) {
json.put("receivingFrom", this.receivingFrom);
diff --git a/openvidu-server/src/main/java/io/openvidu/server/core/MediaOptions.java b/openvidu-server/src/main/java/io/openvidu/server/core/MediaOptions.java
index 066775c8..2376e938 100644
--- a/openvidu-server/src/main/java/io/openvidu/server/core/MediaOptions.java
+++ b/openvidu-server/src/main/java/io/openvidu/server/core/MediaOptions.java
@@ -17,18 +17,72 @@
package io.openvidu.server.core;
+import org.json.simple.JSONObject;
+
public class MediaOptions {
-
- public boolean audioActive;
- public boolean videoActive;
- public String typeOfVideo;
- public int frameRate;
-
- public MediaOptions(boolean audioActive, boolean videoActive, String typeOfVideo, int frameRate) {
+
+ protected Boolean hasAudio;
+ protected Boolean hasVideo;
+ protected Boolean audioActive;
+ protected Boolean videoActive;
+ protected String typeOfVideo;
+ protected Integer frameRate;
+ protected String videoDimensions;
+
+ public MediaOptions(Boolean hasAudio, Boolean hasVideo, Boolean audioActive, Boolean videoActive,
+ String typeOfVideo, Integer frameRate, String videoDimensions) {
+ this.hasAudio = hasAudio;
+ this.hasVideo = hasVideo;
this.audioActive = audioActive;
this.videoActive = videoActive;
this.typeOfVideo = typeOfVideo;
this.frameRate = frameRate;
+ this.videoDimensions = videoDimensions;
+ }
+
+ @SuppressWarnings("unchecked")
+ public JSONObject toJson() {
+ JSONObject json = new JSONObject();
+ json.put("hasAudio", this.hasAudio);
+ if (hasAudio)
+ json.put("audioActive", this.audioActive);
+ json.put("hasVideo", this.hasVideo);
+ if (hasVideo)
+ json.put("videoActive", this.videoActive);
+ if (this.hasVideo && this.videoActive) {
+ json.put("typeOfVideo", this.typeOfVideo);
+ json.put("frameRate", this.frameRate);
+ json.put("videoDimensions", this.videoDimensions);
+ }
+ return json;
+ }
+
+ public boolean hasAudio() {
+ return this.hasAudio;
+ }
+
+ public boolean hasVideo() {
+ return this.hasVideo;
+ }
+
+ public boolean isAudioActive() {
+ return this.hasAudio && this.audioActive;
+ }
+
+ public boolean isVideoActive() {
+ return this.hasVideo && this.videoActive;
+ }
+
+ public String getTypeOfVideo() {
+ return this.typeOfVideo;
+ }
+
+ public Integer getFrameRate() {
+ return this.frameRate;
+ }
+
+ public String getVideoDimensions() {
+ return this.videoDimensions;
}
}
diff --git a/openvidu-server/src/main/java/io/openvidu/server/core/SessionEventsHandler.java b/openvidu-server/src/main/java/io/openvidu/server/core/SessionEventsHandler.java
index 8a58b844..c60859f7 100644
--- a/openvidu-server/src/main/java/io/openvidu/server/core/SessionEventsHandler.java
+++ b/openvidu-server/src/main/java/io/openvidu/server/core/SessionEventsHandler.java
@@ -91,12 +91,18 @@ public class SessionEventsHandler {
existingParticipant.getFullMetadata());
if (existingParticipant.isStreaming()) {
-
+
KurentoParticipant kParticipant = (KurentoParticipant) existingParticipant;
-
+
JsonObject stream = new JsonObject();
stream.addProperty(ProtocolElements.JOINROOM_PEERSTREAMID_PARAM,
existingParticipant.getPublisherStremId());
+ stream.addProperty(ProtocolElements.JOINROOM_PEERSTREAMHASAUDIO_PARAM,
+ kParticipant.getPublisherMediaOptions().hasAudio);
+ stream.addProperty(ProtocolElements.JOINROOM_PEERSTREAMHASVIDEO_PARAM,
+ kParticipant.getPublisherMediaOptions().hasVideo);
+ stream.addProperty(ProtocolElements.JOINROOM_PEERSTREAMVIDEOACTIVE_PARAM,
+ kParticipant.getPublisherMediaOptions().videoActive);
stream.addProperty(ProtocolElements.JOINROOM_PEERSTREAMAUDIOACTIVE_PARAM,
kParticipant.getPublisherMediaOptions().audioActive);
stream.addProperty(ProtocolElements.JOINROOM_PEERSTREAMVIDEOACTIVE_PARAM,
@@ -105,6 +111,8 @@ public class SessionEventsHandler {
kParticipant.getPublisherMediaOptions().typeOfVideo);
stream.addProperty(ProtocolElements.JOINROOM_PEERSTREAMFRAMERATE_PARAM,
kParticipant.getPublisherMediaOptions().frameRate);
+ stream.addProperty(ProtocolElements.JOINROOM_PEERSTREAMVIDEODIMENSIONS_PARAM,
+ kParticipant.getPublisherMediaOptions().videoDimensions);
JsonArray streamsArray = new JsonArray();
streamsArray.add(stream);
@@ -168,8 +176,8 @@ public class SessionEventsHandler {
}
}
- public void onPublishMedia(Participant participant, String streamId, String sessionId, MediaOptions mediaOptions, String sdpAnswer,
- Set participants, Integer transactionId, OpenViduException error) {
+ public void onPublishMedia(Participant participant, String streamId, String sessionId, MediaOptions mediaOptions,
+ String sdpAnswer, Set participants, Integer transactionId, OpenViduException error) {
if (error != null) {
rpcNotificationService.sendErrorResponse(participant.getParticipantPrivateId(), transactionId, null, error);
return;
@@ -184,10 +192,13 @@ public class SessionEventsHandler {
JsonObject stream = new JsonObject();
stream.addProperty(ProtocolElements.PARTICIPANTPUBLISHED_STREAMID_PARAM, streamId);
+ stream.addProperty(ProtocolElements.PARTICIPANTPUBLISHED_HASAUDIO_PARAM, mediaOptions.hasAudio);
+ stream.addProperty(ProtocolElements.PARTICIPANTPUBLISHED_HASVIDEO_PARAM, mediaOptions.hasVideo);
stream.addProperty(ProtocolElements.PARTICIPANTPUBLISHED_AUDIOACTIVE_PARAM, mediaOptions.audioActive);
stream.addProperty(ProtocolElements.PARTICIPANTPUBLISHED_VIDEOACTIVE_PARAM, mediaOptions.videoActive);
stream.addProperty(ProtocolElements.PARTICIPANTPUBLISHED_TYPEOFVIDEO_PARAM, mediaOptions.typeOfVideo);
stream.addProperty(ProtocolElements.PARTICIPANTPUBLISHED_FRAMERATE_PARAM, mediaOptions.frameRate);
+ stream.addProperty(ProtocolElements.PARTICIPANTPUBLISHED_VIDEODIMENSIONS_PARAM, mediaOptions.videoDimensions);
JsonArray streamsArray = new JsonArray();
streamsArray.add(stream);
@@ -308,6 +319,28 @@ public class SessionEventsHandler {
rpcNotificationService.sendResponse(participant.getParticipantPrivateId(), transactionId, new JsonObject());
}
+ public void onStreamPropertyChanged(Participant participant, Integer transactionId, Set participants,
+ String streamId, String property, JsonElement newValue, String reason) {
+
+ JsonObject params = new JsonObject();
+ params.addProperty(ProtocolElements.STREAMPROPERTYCHANGED_CONNECTIONID_PARAM,
+ participant.getParticipantPublicId());
+ params.addProperty(ProtocolElements.STREAMPROPERTYCHANGED_STREAMID_PARAM, streamId);
+ params.addProperty(ProtocolElements.STREAMPROPERTYCHANGED_PROPERTY_PARAM, property);
+ params.addProperty(ProtocolElements.STREAMPROPERTYCHANGED_NEWVALUE_PARAM, newValue.toString());
+ params.addProperty(ProtocolElements.STREAMPROPERTYCHANGED_REASON_PARAM, reason);
+
+ for (Participant p : participants) {
+ if (p.getParticipantPrivateId().equals(participant.getParticipantPrivateId())) {
+ rpcNotificationService.sendResponse(participant.getParticipantPrivateId(), transactionId,
+ new JsonObject());
+ } else {
+ rpcNotificationService.sendNotification(p.getParticipantPrivateId(),
+ ProtocolElements.STREAMPROPERTYCHANGED_METHOD, params);
+ }
+ }
+ }
+
public void onRecvIceCandidate(Participant participant, Integer transactionId, OpenViduException error) {
if (error != null) {
rpcNotificationService.sendErrorResponse(participant.getParticipantPrivateId(), transactionId, null, error);
diff --git a/openvidu-server/src/main/java/io/openvidu/server/core/SessionManager.java b/openvidu-server/src/main/java/io/openvidu/server/core/SessionManager.java
index d3996ab2..e5c3ad33 100644
--- a/openvidu-server/src/main/java/io/openvidu/server/core/SessionManager.java
+++ b/openvidu-server/src/main/java/io/openvidu/server/core/SessionManager.java
@@ -32,6 +32,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.openvidu.client.OpenViduException;
@@ -86,6 +87,9 @@ public abstract class SessionManager {
public abstract void sendMessage(Participant participant, String message, Integer transactionId);
+ public abstract void streamPropertyChanged(Participant participant, Integer transactionId, String streamId,
+ String property, JsonElement newValue, String reason);
+
public abstract void onIceCandidate(Participant participant, String endpointName, String candidate,
int sdpMLineIndex, String sdpMid, Integer transactionId);
@@ -203,15 +207,16 @@ public abstract class SessionManager {
public String newToken(String sessionId, ParticipantRole role, String serverMetadata) throws OpenViduException {
- ConcurrentHashMap map = this.sessionidTokenTokenobj.putIfAbsent(sessionId, new ConcurrentHashMap<>());
+ ConcurrentHashMap map = this.sessionidTokenTokenobj.putIfAbsent(sessionId,
+ new ConcurrentHashMap<>());
if (map != null) {
-
+
if (!isMetadataFormatCorrect(serverMetadata)) {
log.error("Data invalid format. Max length allowed is 10000 chars");
throw new OpenViduException(Code.GENERIC_ERROR_CODE,
"Data invalid format. Max length allowed is 10000 chars");
}
-
+
String token = OpenViduServer.publicUrl;
token += "?sessionId=" + sessionId;
token += "&token=" + this.generateRandomChain();
@@ -225,11 +230,11 @@ public abstract class SessionManager {
}
}
Token t = new Token(token, role, serverMetadata, turnCredentials);
-
+
map.putIfAbsent(token, t);
showTokens();
return token;
-
+
} else {
this.sessionidTokenTokenobj.remove(sessionId);
log.error("sessionId [" + sessionId + "] is not valid");
@@ -249,8 +254,10 @@ public abstract class SessionManager {
this.sessionidParticipantpublicidParticipant.putIfAbsent(sessionId, new ConcurrentHashMap<>());
this.sessionidTokenTokenobj.putIfAbsent(sessionId, new ConcurrentHashMap<>());
this.sessionidTokenTokenobj.get(sessionId).putIfAbsent(token,
- new Token(token, ParticipantRole.PUBLISHER, "",
- this.coturnCredentialsService.isCoturnAvailable() ? this.coturnCredentialsService.createUser() : null));
+ new Token(token, ParticipantRole.PUBLISHER, "",
+ this.coturnCredentialsService.isCoturnAvailable()
+ ? this.coturnCredentialsService.createUser()
+ : null));
return true;
}
}
@@ -313,8 +320,10 @@ public abstract class SessionManager {
public Participant newRecorderParticipant(String sessionId, String participantPrivatetId, Token token,
String clientMetadata) {
if (this.sessionidParticipantpublicidParticipant.get(sessionId) != null) {
- Participant p = new Participant(participantPrivatetId, ProtocolElements.RECORDER_PARTICIPANT_PUBLICID, token, clientMetadata);
- this.sessionidParticipantpublicidParticipant.get(sessionId).put(ProtocolElements.RECORDER_PARTICIPANT_PUBLICID, p);
+ Participant p = new Participant(participantPrivatetId, ProtocolElements.RECORDER_PARTICIPANT_PUBLICID,
+ token, clientMetadata);
+ this.sessionidParticipantpublicidParticipant.get(sessionId)
+ .put(ProtocolElements.RECORDER_PARTICIPANT_PUBLICID, p);
return p;
} else {
throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE, sessionId);
diff --git a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoMediaOptions.java b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoMediaOptions.java
index 422d4366..5c2486e0 100644
--- a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoMediaOptions.java
+++ b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoMediaOptions.java
@@ -32,9 +32,10 @@ public class KurentoMediaOptions extends MediaOptions {
public MediaElement[] mediaElements;
public KurentoMediaOptions(boolean isOffer, String sdpOffer, MediaElement loopbackAlternativeSrc,
- MediaType loopbackConnectionType, boolean audioActive, boolean videoActive, String typeOfVideo,
- int frameRate, boolean doLoopback, MediaElement... mediaElements) {
- super(audioActive, videoActive, typeOfVideo, frameRate);
+ MediaType loopbackConnectionType, Boolean hasAudio, Boolean hasVideo, Boolean audioActive,
+ Boolean videoActive, String typeOfVideo, Integer frameRate, String videoDimensions, boolean doLoopback,
+ MediaElement... mediaElements) {
+ super(hasAudio, hasVideo, audioActive, videoActive, typeOfVideo, frameRate, videoDimensions);
this.isOffer = isOffer;
this.sdpOffer = sdpOffer;
this.loopbackAlternativeSrc = loopbackAlternativeSrc;
diff --git a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoParticipant.java b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoParticipant.java
index 2ac2ace5..dfccf2d5 100644
--- a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoParticipant.java
+++ b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoParticipant.java
@@ -58,7 +58,7 @@ import io.openvidu.server.kurento.endpoint.SubscriberEndpoint;
public class KurentoParticipant extends Participant {
private static final Logger log = LoggerFactory.getLogger(KurentoParticipant.class);
-
+
@Autowired
protected OpenviduConfig openviduConfig;
@@ -102,7 +102,7 @@ public class KurentoParticipant extends Participant {
publisher.setMediaOptions(mediaOptions);
String publisherStreamId = this.getParticipantPublicId() + "_"
- + (mediaOptions.videoActive ? mediaOptions.typeOfVideo : "MICRO") + "_"
+ + (mediaOptions.hasVideo() ? mediaOptions.getTypeOfVideo() : "MICRO") + "_"
+ RandomStringUtils.random(5, true, false).toUpperCase();
this.publisher.getEndpoint().addTag("name", publisherStreamId);
addEndpointListeners(this.publisher);
@@ -180,11 +180,15 @@ public class KurentoParticipant extends Participant {
}
return this.publisher;
}
-
+
public MediaOptions getPublisherMediaOptions() {
return this.publisher.getMediaOptions();
}
+ public void setPublisherMediaOptions(MediaOptions mediaOptions) {
+ this.publisher.setMediaOptions(mediaOptions);
+ }
+
public KurentoSession getSession() {
return session;
}
@@ -641,7 +645,7 @@ public class KurentoParticipant extends Participant {
+ " | MEDIATYPE: " + event.getMediaType() + " | TIMESTAMP: " + System.currentTimeMillis();
endpoint.flowInMedia.put(event.getSource().getName(), event.getMediaType());
- if (endpoint.getMediaOptions().audioActive && endpoint.getMediaOptions().videoActive
+ if (endpoint.getMediaOptions().hasAudio() && endpoint.getMediaOptions().hasVideo()
&& endpoint.flowInMedia.values().size() == 2) {
endpoint.kmsEvents.add(new KmsEvent(event));
} else if (endpoint.flowInMedia.values().size() == 1) {
@@ -658,7 +662,7 @@ public class KurentoParticipant extends Participant {
+ " | MEDIATYPE: " + event.getMediaType() + " | TIMESTAMP: " + System.currentTimeMillis();
endpoint.flowOutMedia.put(event.getSource().getName(), event.getMediaType());
- if (endpoint.getMediaOptions().audioActive && endpoint.getMediaOptions().videoActive
+ if (endpoint.getMediaOptions().hasAudio() && endpoint.getMediaOptions().hasVideo()
&& endpoint.flowOutMedia.values().size() == 2) {
endpoint.kmsEvents.add(new KmsEvent(event));
} else if (endpoint.flowOutMedia.values().size() == 1) {
@@ -708,6 +712,24 @@ public class KurentoParticipant extends Participant {
return json;
}
+ @SuppressWarnings("unchecked")
+ public JSONObject withStatsToJSON() {
+ JSONObject json = super.toJSON();
+ JSONArray publisherEnpoints = new JSONArray();
+ if (this.streaming && this.publisher.getEndpoint() != null) {
+ publisherEnpoints.add(this.publisher.withStatsToJSON());
+ }
+ JSONArray subscriberEndpoints = new JSONArray();
+ for (MediaEndpoint sub : this.subscribers.values()) {
+ if (sub.getEndpoint() != null) {
+ subscriberEndpoints.add(sub.withStatsToJSON());
+ }
+ }
+ json.put("publishers", publisherEnpoints);
+ json.put("subscribers", subscriberEndpoints);
+ return json;
+ }
+
@Override
public String getPublisherStremId() {
return this.publisher.getEndpoint().getTag("name");
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 719abbaf..d862f707 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
@@ -28,6 +28,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
@@ -124,7 +125,7 @@ public class KurentoSessionManager extends SessionManager {
if (sessionidParticipantpublicidParticipant.get(sessionId) != null) {
Participant p = sessionidParticipantpublicidParticipant.get(sessionId)
.remove(participant.getParticipantPublicId());
-
+
if (this.coturnCredentialsService.isCoturnAvailable()) {
this.coturnCredentialsService.deleteUser(p.getToken().getTurnCredentials().getUsername());
}
@@ -271,8 +272,8 @@ public class KurentoSessionManager extends SessionManager {
participants = kurentoParticipant.getSession().getParticipants();
if (sdpAnswer != null) {
- sessionEventsHandler.onPublishMedia(participant, participant.getPublisherStremId(), session.getSessionId(), mediaOptions, sdpAnswer,
- participants, transactionId, null);
+ sessionEventsHandler.onPublishMedia(participant, participant.getPublisherStremId(), session.getSessionId(),
+ mediaOptions, sdpAnswer, participants, transactionId, null);
}
}
@@ -379,6 +380,40 @@ public class KurentoSessionManager extends SessionManager {
}
}
+ @Override
+ public void streamPropertyChanged(Participant participant, Integer transactionId, String streamId, String property,
+ JsonElement newValue, String reason) {
+ KurentoParticipant kParticipant = (KurentoParticipant) participant;
+ streamId = kParticipant.getPublisherStremId();
+ MediaOptions streamProperties = kParticipant.getPublisherMediaOptions();
+
+ Boolean hasAudio = streamProperties.hasAudio();
+ Boolean hasVideo = streamProperties.hasVideo();
+ Boolean audioActive = streamProperties.isAudioActive();
+ Boolean videoActive = streamProperties.isVideoActive();
+ String typeOfVideo = streamProperties.getTypeOfVideo();
+ Integer frameRate = streamProperties.getFrameRate();
+ String videoDimensions = streamProperties.getVideoDimensions();
+
+ switch (property) {
+ case "audioActive":
+ audioActive = newValue.getAsBoolean();
+ break;
+ case "videoActive":
+ videoActive = newValue.getAsBoolean();
+ break;
+ case "videoDimensions":
+ videoDimensions = newValue.getAsString();
+ break;
+ }
+
+ kParticipant.setPublisherMediaOptions(new MediaOptions(hasAudio, hasVideo, audioActive, videoActive,
+ typeOfVideo, frameRate, videoDimensions));
+
+ sessionEventsHandler.onStreamPropertyChanged(participant, transactionId,
+ kParticipant.getSession().getParticipants(), streamId, property, newValue, reason);
+ }
+
@Override
public void onIceCandidate(Participant participant, String endpointName, String candidate, int sdpMLineIndex,
String sdpMid, Integer transactionId) {
@@ -450,14 +485,38 @@ public class KurentoSessionManager extends SessionManager {
public MediaOptions generateMediaOptions(Request request) {
String sdpOffer = RpcHandler.getStringParam(request, ProtocolElements.PUBLISHVIDEO_SDPOFFER_PARAM);
- boolean audioActive = RpcHandler.getBooleanParam(request, ProtocolElements.PUBLISHVIDEO_AUDIOACTIVE_PARAM);
- boolean videoActive = RpcHandler.getBooleanParam(request, ProtocolElements.PUBLISHVIDEO_VIDEOACTIVE_PARAM);
- String typeOfVideo = RpcHandler.getStringParam(request, ProtocolElements.PUBLISHVIDEO_TYPEOFVIDEO_PARAM);
- int frameRate = RpcHandler.getIntParam(request, ProtocolElements.PUBLISHVIDEO_FRAMERATE_PARAM);
+ boolean hasAudio = RpcHandler.getBooleanParam(request, ProtocolElements.PUBLISHVIDEO_HASAUDIO_PARAM);
+ boolean hasVideo = RpcHandler.getBooleanParam(request, ProtocolElements.PUBLISHVIDEO_HASVIDEO_PARAM);
+
+ Boolean audioActive = null, videoActive = null;
+ String typeOfVideo = null, videoDimensions = null;
+ Integer frameRate = null;
+
+ try {
+ audioActive = RpcHandler.getBooleanParam(request, ProtocolElements.PUBLISHVIDEO_AUDIOACTIVE_PARAM);
+ } catch (RuntimeException noParameterFound) {
+ }
+ try {
+ videoActive = RpcHandler.getBooleanParam(request, ProtocolElements.PUBLISHVIDEO_VIDEOACTIVE_PARAM);
+ } catch (RuntimeException noParameterFound) {
+ }
+ try {
+ typeOfVideo = RpcHandler.getStringParam(request, ProtocolElements.PUBLISHVIDEO_TYPEOFVIDEO_PARAM);
+ } catch (RuntimeException noParameterFound) {
+ }
+ try {
+ videoDimensions = RpcHandler.getStringParam(request, ProtocolElements.PUBLISHVIDEO_VIDEODIMENSIONS_PARAM);
+ } catch (RuntimeException noParameterFound) {
+ }
+ try {
+ frameRate = RpcHandler.getIntParam(request, ProtocolElements.PUBLISHVIDEO_FRAMERATE_PARAM);
+ } catch (RuntimeException noParameterFound) {
+ }
+
boolean doLoopback = RpcHandler.getBooleanParam(request, ProtocolElements.PUBLISHVIDEO_DOLOOPBACK_PARAM);
- return new KurentoMediaOptions(true, sdpOffer, null, null, audioActive, videoActive, typeOfVideo, frameRate,
- doLoopback);
+ return new KurentoMediaOptions(true, sdpOffer, null, null, hasAudio, hasVideo, audioActive, videoActive,
+ typeOfVideo, frameRate, videoDimensions, doLoopback);
}
}
diff --git a/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java b/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java
index 87eb95f8..59a5bd8f 100644
--- a/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java
+++ b/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java
@@ -30,6 +30,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.openvidu.client.OpenViduException;
@@ -122,6 +123,9 @@ public class RpcHandler extends DefaultJsonRpcHandler {
case ProtocolElements.UNPUBLISHVIDEO_METHOD:
unpublishVideo(rpcConnection, request);
break;
+ case ProtocolElements.STREAMPROPERTYCHANGED_METHOD:
+ streamPropertyChanged(rpcConnection, request);
+ break;
default:
log.error("Unrecognized request {}", request);
break;
@@ -282,6 +286,19 @@ public class RpcHandler extends DefaultJsonRpcHandler {
sessionManager.unpublishVideo(participant, request.getId(), "unpublish");
}
+
+ public void streamPropertyChanged(RpcConnection rpcConnection, Request request) {
+ String participantPrivateId = rpcConnection.getParticipantPrivateId();
+ String sessionId = rpcConnection.getSessionId();
+ Participant participant = sessionManager.getParticipant(sessionId, participantPrivateId);
+
+ String streamId = getStringParam(request, ProtocolElements.STREAMPROPERTYCHANGED_STREAMID_PARAM);
+ String property = getStringParam(request, ProtocolElements.STREAMPROPERTYCHANGED_PROPERTY_PARAM);
+ JsonElement newValue = getParam(request, ProtocolElements.STREAMPROPERTYCHANGED_NEWVALUE_PARAM);
+ String reason = getStringParam(request, ProtocolElements.STREAMPROPERTYCHANGED_REASON_PARAM);
+
+ sessionManager.streamPropertyChanged(participant, request.getId(), streamId, property, newValue, reason);
+ }
public void leaveRoomAfterConnClosed(String participantPrivateId, String reason) {
try {
@@ -385,5 +402,13 @@ public class RpcHandler extends DefaultJsonRpcHandler {
}
return request.getParams().get(key).getAsBoolean();
}
+
+ public static JsonElement getParam(Request request, String key) {
+ if (request.getParams() == null || request.getParams().get(key) == null) {
+ throw new RuntimeException("Request element '" + key + "' is missing in method '" + request.getMethod()
+ + "'. CHECK THAT 'openvidu-server' AND 'openvidu-browser' SHARE THE SAME VERSION NUMBER");
+ }
+ return request.getParams().get(key);
+ }
}