mirror of https://github.com/OpenVidu/openvidu.git
Move ConnectionProperties#fromJson from openvidu-server to openvidu-java-client
parent
a49e1818c0
commit
b102a44d50
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
package io.openvidu.java.client;
|
package io.openvidu.java.client;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -25,9 +26,7 @@ import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See {@link io.openvidu.java.client.Session#getConnections()}
|
* See {@link io.openvidu.java.client.Session#getConnections()}
|
||||||
|
@ -328,9 +327,12 @@ public class Connection {
|
||||||
builder.record(this.connectionProperties.record());
|
builder.record(this.connectionProperties.record());
|
||||||
}
|
}
|
||||||
// Keep old configuration in the rest of properties
|
// Keep old configuration in the rest of properties
|
||||||
builder.type(this.connectionProperties.getType()).data(this.connectionProperties.getData())
|
try {
|
||||||
.kurentoOptions(this.connectionProperties.getKurentoOptions())
|
builder.type(this.connectionProperties.getType()).data(this.connectionProperties.getData())
|
||||||
.rtspUri(this.connectionProperties.getRtspUri());
|
.kurentoOptions(this.connectionProperties.getKurentoOptions())
|
||||||
|
.rtspUri(this.connectionProperties.getRtspUri());
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
}
|
||||||
if (this.connectionProperties.adaptativeBitrate() != null) {
|
if (this.connectionProperties.adaptativeBitrate() != null) {
|
||||||
builder.adaptativeBitrate(this.connectionProperties.adaptativeBitrate());
|
builder.adaptativeBitrate(this.connectionProperties.adaptativeBitrate());
|
||||||
}
|
}
|
||||||
|
@ -340,8 +342,9 @@ public class Connection {
|
||||||
if (this.connectionProperties.getNetworkCache() != null) {
|
if (this.connectionProperties.getNetworkCache() != null) {
|
||||||
builder.networkCache(this.connectionProperties.getNetworkCache());
|
builder.networkCache(this.connectionProperties.getNetworkCache());
|
||||||
}
|
}
|
||||||
if (this.connectionProperties.getCustomIceServers() != null && !this.connectionProperties.getCustomIceServers().isEmpty()) {
|
if (this.connectionProperties.getCustomIceServers() != null
|
||||||
for (IceServerProperties iceServerProperties: this.connectionProperties.getCustomIceServers()) {
|
&& !this.connectionProperties.getCustomIceServers().isEmpty()) {
|
||||||
|
for (IceServerProperties iceServerProperties : this.connectionProperties.getCustomIceServers()) {
|
||||||
builder.addCustomIceServer(iceServerProperties);
|
builder.addCustomIceServer(iceServerProperties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -452,7 +455,8 @@ public class Connection {
|
||||||
String credential = (iceJsonObj.has("credential") && !iceJsonObj.get("credential").isJsonNull())
|
String credential = (iceJsonObj.has("credential") && !iceJsonObj.get("credential").isJsonNull())
|
||||||
? iceJsonObj.get("credential").getAsString()
|
? iceJsonObj.get("credential").getAsString()
|
||||||
: null;
|
: null;
|
||||||
customIceServers.add(new IceServerProperties.Builder().url(url).username(username).credential(credential).build());
|
customIceServers.add(
|
||||||
|
new IceServerProperties.Builder().url(url).username(username).credential(credential).build());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,19 @@
|
||||||
package io.openvidu.java.client;
|
package io.openvidu.java.client;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonNull;
|
import com.google.gson.JsonNull;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See
|
* See
|
||||||
* {@link io.openvidu.java.client.Session#createConnection(ConnectionProperties)}
|
* {@link io.openvidu.java.client.Session#createConnection(ConnectionProperties)}
|
||||||
|
@ -172,8 +179,11 @@ public class ConnectionProperties {
|
||||||
* <br>
|
* <br>
|
||||||
* <strong>Only for
|
* <strong>Only for
|
||||||
* {@link io.openvidu.java.client.ConnectionType#IPCAM}</strong>
|
* {@link io.openvidu.java.client.ConnectionType#IPCAM}</strong>
|
||||||
|
*
|
||||||
|
* @throws MalformedURLException
|
||||||
*/
|
*/
|
||||||
public Builder rtspUri(String rtspUri) {
|
public Builder rtspUri(String rtspUri) throws MalformedURLException {
|
||||||
|
checkRtspUri(rtspUri);
|
||||||
this.rtspUri = rtspUri;
|
this.rtspUri = rtspUri;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -463,4 +473,203 @@ public class ConnectionProperties {
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain a {@link ConnectionProperties.Builder} directly from a JSON object in
|
||||||
|
* the form of a Map
|
||||||
|
*
|
||||||
|
* @return A {@link ConnectionProperties.Builder}
|
||||||
|
* @throws IllegalArgumentException If some parameter has a wrong type or an
|
||||||
|
* invalid value
|
||||||
|
*/
|
||||||
|
public static ConnectionProperties.Builder fromJson(Map<String, ?> params) throws IllegalArgumentException {
|
||||||
|
|
||||||
|
ConnectionProperties.Builder builder = new ConnectionProperties.Builder();
|
||||||
|
|
||||||
|
String typeString;
|
||||||
|
String data;
|
||||||
|
try {
|
||||||
|
typeString = (String) params.get("type");
|
||||||
|
data = (String) params.get("data");
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
throw new IllegalArgumentException("Type error in some parameter: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
ConnectionType type;
|
||||||
|
try {
|
||||||
|
if (typeString != null) {
|
||||||
|
type = ConnectionType.valueOf(typeString);
|
||||||
|
} else {
|
||||||
|
type = ConnectionType.WEBRTC;
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
throw new IllegalArgumentException("Parameter 'type' " + typeString + " is not defined");
|
||||||
|
}
|
||||||
|
data = data != null ? data : "";
|
||||||
|
|
||||||
|
// Build COMMON options
|
||||||
|
builder.type(type).data(data).record(true);
|
||||||
|
|
||||||
|
OpenViduRole role = null;
|
||||||
|
KurentoOptions kurentoOptions = null;
|
||||||
|
|
||||||
|
if (ConnectionType.WEBRTC.equals(type)) {
|
||||||
|
String roleString;
|
||||||
|
try {
|
||||||
|
roleString = (String) params.get("role");
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
throw new IllegalArgumentException("Type error in parameter 'role': " + e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (roleString != null) {
|
||||||
|
role = OpenViduRole.valueOf(roleString);
|
||||||
|
} else {
|
||||||
|
role = OpenViduRole.PUBLISHER;
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
throw new IllegalArgumentException("Parameter role " + params.get("role") + " is not defined");
|
||||||
|
}
|
||||||
|
JsonObject kurentoOptionsJson = null;
|
||||||
|
if (params.get("kurentoOptions") != null) {
|
||||||
|
try {
|
||||||
|
kurentoOptionsJson = new Gson().toJsonTree(params.get("kurentoOptions"), Map.class)
|
||||||
|
.getAsJsonObject();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Error in parameter 'kurentoOptions'. It is not a valid JSON object");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (kurentoOptionsJson != null) {
|
||||||
|
try {
|
||||||
|
KurentoOptions.Builder builder2 = new KurentoOptions.Builder();
|
||||||
|
if (kurentoOptionsJson.has("videoMaxRecvBandwidth")) {
|
||||||
|
builder2.videoMaxRecvBandwidth(kurentoOptionsJson.get("videoMaxRecvBandwidth").getAsInt());
|
||||||
|
}
|
||||||
|
if (kurentoOptionsJson.has("videoMinRecvBandwidth")) {
|
||||||
|
builder2.videoMinRecvBandwidth(kurentoOptionsJson.get("videoMinRecvBandwidth").getAsInt());
|
||||||
|
}
|
||||||
|
if (kurentoOptionsJson.has("videoMaxSendBandwidth")) {
|
||||||
|
builder2.videoMaxSendBandwidth(kurentoOptionsJson.get("videoMaxSendBandwidth").getAsInt());
|
||||||
|
}
|
||||||
|
if (kurentoOptionsJson.has("videoMinSendBandwidth")) {
|
||||||
|
builder2.videoMinSendBandwidth(kurentoOptionsJson.get("videoMinSendBandwidth").getAsInt());
|
||||||
|
}
|
||||||
|
if (kurentoOptionsJson.has("allowedFilters")) {
|
||||||
|
JsonArray filters = kurentoOptionsJson.get("allowedFilters").getAsJsonArray();
|
||||||
|
String[] arrayOfFilters = new String[filters.size()];
|
||||||
|
Iterator<JsonElement> it = filters.iterator();
|
||||||
|
int index = 0;
|
||||||
|
while (it.hasNext()) {
|
||||||
|
arrayOfFilters[index] = it.next().getAsString();
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
builder2.allowedFilters(arrayOfFilters);
|
||||||
|
}
|
||||||
|
kurentoOptions = builder2.build();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Type error in some parameter of 'kurentoOptions': " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom Ice Servers
|
||||||
|
JsonArray customIceServersJsonArray = null;
|
||||||
|
if (params.get("customIceServers") != null) {
|
||||||
|
try {
|
||||||
|
customIceServersJsonArray = new Gson().toJsonTree(params.get("customIceServers"), List.class)
|
||||||
|
.getAsJsonArray();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Error in parameter 'customIceServersJson'. It is not a valid JSON object");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (customIceServersJsonArray != null) {
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < customIceServersJsonArray.size(); i++) {
|
||||||
|
JsonObject customIceServerJson = customIceServersJsonArray.get(i).getAsJsonObject();
|
||||||
|
IceServerProperties.Builder iceServerPropertiesBuilder = new IceServerProperties.Builder();
|
||||||
|
iceServerPropertiesBuilder.url(customIceServerJson.get("url").getAsString());
|
||||||
|
if (customIceServerJson.has("staticAuthSecret")) {
|
||||||
|
iceServerPropertiesBuilder
|
||||||
|
.staticAuthSecret(customIceServerJson.get("staticAuthSecret").getAsString());
|
||||||
|
}
|
||||||
|
if (customIceServerJson.has("username")) {
|
||||||
|
iceServerPropertiesBuilder.username(customIceServerJson.get("username").getAsString());
|
||||||
|
}
|
||||||
|
if (customIceServerJson.has("credential")) {
|
||||||
|
iceServerPropertiesBuilder.credential(customIceServerJson.get("credential").getAsString());
|
||||||
|
}
|
||||||
|
IceServerProperties iceServerProperties = iceServerPropertiesBuilder.build();
|
||||||
|
builder.addCustomIceServer(iceServerProperties);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Type error in some parameter of 'customIceServers': " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build WEBRTC options
|
||||||
|
builder.role(role).kurentoOptions(kurentoOptions);
|
||||||
|
|
||||||
|
} else if (ConnectionType.IPCAM.equals(type)) {
|
||||||
|
String rtspUri;
|
||||||
|
Boolean adaptativeBitrate;
|
||||||
|
Boolean onlyPlayWithSubscribers;
|
||||||
|
Number networkCache;
|
||||||
|
try {
|
||||||
|
rtspUri = (String) params.get("rtspUri");
|
||||||
|
adaptativeBitrate = (Boolean) params.get("adaptativeBitrate");
|
||||||
|
onlyPlayWithSubscribers = (Boolean) params.get("onlyPlayWithSubscribers");
|
||||||
|
networkCache = (Number) params.get("networkCache");
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
throw new IllegalArgumentException("Type error in some parameter: " + e.getMessage());
|
||||||
|
}
|
||||||
|
adaptativeBitrate = adaptativeBitrate != null ? adaptativeBitrate : true;
|
||||||
|
onlyPlayWithSubscribers = onlyPlayWithSubscribers != null ? onlyPlayWithSubscribers : true;
|
||||||
|
networkCache = networkCache != null ? networkCache : 2000;
|
||||||
|
if (rtspUri != null) {
|
||||||
|
try {
|
||||||
|
checkRtspUri(rtspUri);
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
throw new IllegalArgumentException("Error in parameter 'rtspUri': " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build IPCAM options
|
||||||
|
try {
|
||||||
|
builder.rtspUri(rtspUri).adaptativeBitrate(adaptativeBitrate)
|
||||||
|
.onlyPlayWithSubscribers(onlyPlayWithSubscribers).networkCache(networkCache.intValue()).build();
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
throw new IllegalArgumentException("Type error in some parameter: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Boolean record;
|
||||||
|
try {
|
||||||
|
record = (Boolean) params.get("record");
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
throw new IllegalArgumentException("Type error in parameter 'record': " + e.getMessage());
|
||||||
|
}
|
||||||
|
record = record != null ? record : true;
|
||||||
|
builder.record(record);
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hidden
|
||||||
|
*/
|
||||||
|
public static URI checkRtspUri(String rtspUri) throws MalformedURLException {
|
||||||
|
try {
|
||||||
|
URI uri = new URI(rtspUri);
|
||||||
|
List<String> allowedSchemes = Arrays.asList("file", "rtsp", "rtsps");
|
||||||
|
if (!allowedSchemes.contains(uri.getScheme())) {
|
||||||
|
throw new MalformedURLException(
|
||||||
|
"RTSP URI does not contain a valid protocol " + allowedSchemes.toString());
|
||||||
|
}
|
||||||
|
return uri;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new MalformedURLException(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
package io.openvidu.java.client.test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertThrows;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
import io.openvidu.java.client.ConnectionProperties;
|
||||||
|
import junit.framework.Test;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
|
public class ConnectionPropertiesTest extends TestCase {
|
||||||
|
|
||||||
|
public ConnectionPropertiesTest(String testName) {
|
||||||
|
super(testName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Test suite() {
|
||||||
|
return new TestSuite(ConnectionPropertiesTest.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testWebrtcFromJsonSuccess() {
|
||||||
|
String jsonString = "{'type':'WEBRTC','data':'MY_CUSTOM_STRING','record':false,'role':'SUBSCRIBER','kurentoOptions':{'videoMaxRecvBandwidth':333,'videoMinRecvBandwidth':333,'videoMaxSendBandwidth':333,'videoMinSendBandwidth':333,'allowedFilters':['CustomFilter']},'customIceServers':[{'url':'turn:turn-domain.com:443','username':'MY_CUSTOM_STRING','credential':'MY_CUSTOM_STRING'}]}";
|
||||||
|
JsonObject originalJson = new Gson().fromJson(jsonString, JsonObject.class);
|
||||||
|
Map<String, ?> map = mapFromJsonString(jsonString);
|
||||||
|
ConnectionProperties.Builder builder = ConnectionProperties.fromJson(map);
|
||||||
|
ConnectionProperties props = builder.build();
|
||||||
|
JsonObject finalJson = props.toJson("MY_CUSTOM_STRING");
|
||||||
|
finalJson = removeIpcamProps(finalJson);
|
||||||
|
assertEquals(originalJson, finalJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testIpcamFromJsonSuccess() {
|
||||||
|
String jsonString = "{'type':'IPCAM','data':'MY_CUSTOM_STRING','record':false,'rtspUri':'rtsp://your.camera.ip.sdp','adaptativeBitrate':false,'onlyPlayWithSubscribers':false,'networkCache':333}";
|
||||||
|
JsonObject originalJson = new Gson().fromJson(jsonString, JsonObject.class);
|
||||||
|
Map<String, ?> map = mapFromJsonString(jsonString);
|
||||||
|
ConnectionProperties.Builder builder = ConnectionProperties.fromJson(map);
|
||||||
|
ConnectionProperties props = builder.build();
|
||||||
|
JsonObject finalJson = props.toJson("MY_CUSTOM_STRING");
|
||||||
|
finalJson = removeWebrtcProps(finalJson);
|
||||||
|
assertEquals(originalJson, finalJson);
|
||||||
|
|
||||||
|
jsonString = "{'type':'IPCAM','rtspUri':'rtsp://your.camera.ip.sdp'}";
|
||||||
|
ConnectionProperties.fromJson(mapFromJsonString(jsonString)).build();
|
||||||
|
|
||||||
|
jsonString = "{'type':'IPCAM','rtspUri':'rtsps://your.camera.ip.sdp'}";
|
||||||
|
ConnectionProperties.fromJson(mapFromJsonString(jsonString)).build();
|
||||||
|
|
||||||
|
jsonString = "{'type':'IPCAM','rtspUri':'file://your.camera.ip.sdp'}";
|
||||||
|
ConnectionProperties.fromJson(mapFromJsonString(jsonString)).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testFromJsonError() {
|
||||||
|
Map<String, ?> map = mapFromJsonString("{'type':'NOT_EXISTS'}");
|
||||||
|
assertException(map, "type");
|
||||||
|
|
||||||
|
map = mapFromJsonString("{'data':4000}");
|
||||||
|
assertException(map, "");
|
||||||
|
|
||||||
|
map = mapFromJsonString("{'record':4000}");
|
||||||
|
assertException(map, "record");
|
||||||
|
|
||||||
|
map = mapFromJsonString("{'role':'NOT_EXISTS'}");
|
||||||
|
assertException(map, "role");
|
||||||
|
|
||||||
|
map = mapFromJsonString("{'kurentoOptions':{'allowedFilters':[{'OBJECT_NOT_EXPECTED':true}]}}");
|
||||||
|
assertException(map, "kurentoOptions");
|
||||||
|
|
||||||
|
map = mapFromJsonString("{'customIceServers':[{'url':'NOT_A_VALID_URI'}]}");
|
||||||
|
assertException(map, "customIceServers");
|
||||||
|
|
||||||
|
map = mapFromJsonString("{'type':'IPCAM','rtspUri':'NOT_A_VALID_RTSP_URI'}");
|
||||||
|
assertException(map, "rtspUri");
|
||||||
|
|
||||||
|
map = mapFromJsonString("{'type':'IPCAM','rtspUri':'https://domain.com'}");
|
||||||
|
assertException(map, "rtspUri");
|
||||||
|
|
||||||
|
map = mapFromJsonString("{'type':'IPCAM','rtspUri':'filse://your.camera.ip.sdp'}");
|
||||||
|
assertException(map, "rtspUri");
|
||||||
|
}
|
||||||
|
|
||||||
|
private JsonObject removeIpcamProps(JsonObject json) {
|
||||||
|
json.remove("session");
|
||||||
|
json.remove("adaptativeBitrate");
|
||||||
|
json.remove("networkCache");
|
||||||
|
json.remove("onlyPlayWithSubscribers");
|
||||||
|
json.remove("rtspUri");
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JsonObject removeWebrtcProps(JsonObject json) {
|
||||||
|
json.remove("session");
|
||||||
|
json.remove("kurentoOptions");
|
||||||
|
json.remove("role");
|
||||||
|
json.remove("customIceServers");
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, ?> mapFromJsonString(String json) {
|
||||||
|
return new Gson().fromJson(json, Map.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertException(Map<String, ?> params, String containsError) {
|
||||||
|
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class,
|
||||||
|
() -> ConnectionProperties.fromJson(params));
|
||||||
|
assertTrue(exception.getMessage().contains(containsError));
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,8 +19,7 @@ package io.openvidu.server.kurento.core;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.MalformedURLException;
|
import java.net.URI;
|
||||||
import java.net.URL;
|
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -28,8 +27,6 @@ import java.util.HashSet;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import javax.annotation.PreDestroy;
|
import javax.annotation.PreDestroy;
|
||||||
|
|
||||||
|
@ -1134,25 +1131,12 @@ public class KurentoSessionManager extends SessionManager {
|
||||||
|
|
||||||
// Generate the location for the IpCam
|
// Generate the location for the IpCam
|
||||||
GeoLocation location = null;
|
GeoLocation location = null;
|
||||||
URL url = null;
|
URI uri = ConnectionProperties.checkRtspUri(kMediaOptions.rtspUri);
|
||||||
|
String protocol = uri.getScheme();
|
||||||
InetAddress ipAddress = null;
|
InetAddress ipAddress = null;
|
||||||
String protocol = null;
|
|
||||||
try {
|
|
||||||
Pattern pattern = Pattern.compile("^(file|rtsp|rtsps)://");
|
|
||||||
Matcher matcher = pattern.matcher(kMediaOptions.rtspUri);
|
|
||||||
if (matcher.find()) {
|
|
||||||
protocol = matcher.group(0).replaceAll("://$", "");
|
|
||||||
} else {
|
|
||||||
throw new MalformedURLException();
|
|
||||||
}
|
|
||||||
String parsedUrl = kMediaOptions.rtspUri.replaceAll("^.*?://", "http://");
|
|
||||||
url = new URL(parsedUrl);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new MalformedURLException();
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ipAddress = InetAddress.getByName(url.getHost());
|
ipAddress = InetAddress.getByName(uri.getHost());
|
||||||
location = this.geoLocationByIp.getLocationByIp(ipAddress);
|
location = this.geoLocationByIp.getLocationByIp(ipAddress);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -1163,8 +1147,8 @@ public class KurentoSessionManager extends SessionManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
String rtspConnectionId = kMediaOptions.getTypeOfVideo() + "_" + protocol + "_"
|
String rtspConnectionId = kMediaOptions.getTypeOfVideo() + "_" + protocol + "_"
|
||||||
+ RandomStringUtils.randomAlphanumeric(4).toUpperCase() + "_" + url.getHost()
|
+ RandomStringUtils.randomAlphanumeric(4).toUpperCase() + "_" + uri.getHost()
|
||||||
+ (url.getPort() != -1 ? (":" + url.getPort()) : "") + url.getPath();
|
+ (uri.getPort() != -1 ? (":" + uri.getPort()) : "") + uri.getPath();
|
||||||
rtspConnectionId = rtspConnectionId.replace("/", "_").replace("-", "").replace(".", "_").replace(":", "_");
|
rtspConnectionId = rtspConnectionId.replace("/", "_").replace("-", "").replace(".", "_").replace(":", "_");
|
||||||
rtspConnectionId = IdentifierPrefixes.IPCAM_ID + rtspConnectionId;
|
rtspConnectionId = IdentifierPrefixes.IPCAM_ID + rtspConnectionId;
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@ import java.net.MalformedURLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
@ -46,7 +45,6 @@ import org.springframework.web.bind.annotation.RestController;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
|
|
||||||
|
@ -56,9 +54,7 @@ import io.openvidu.client.internal.ProtocolElements;
|
||||||
import io.openvidu.java.client.ConnectionProperties;
|
import io.openvidu.java.client.ConnectionProperties;
|
||||||
import io.openvidu.java.client.ConnectionType;
|
import io.openvidu.java.client.ConnectionType;
|
||||||
import io.openvidu.java.client.IceServerProperties;
|
import io.openvidu.java.client.IceServerProperties;
|
||||||
import io.openvidu.java.client.KurentoOptions;
|
|
||||||
import io.openvidu.java.client.MediaMode;
|
import io.openvidu.java.client.MediaMode;
|
||||||
import io.openvidu.java.client.OpenViduRole;
|
|
||||||
import io.openvidu.java.client.Recording.OutputMode;
|
import io.openvidu.java.client.Recording.OutputMode;
|
||||||
import io.openvidu.java.client.RecordingLayout;
|
import io.openvidu.java.client.RecordingLayout;
|
||||||
import io.openvidu.java.client.RecordingProperties;
|
import io.openvidu.java.client.RecordingProperties;
|
||||||
|
@ -99,13 +95,13 @@ public class SessionRestController {
|
||||||
protected OpenviduConfig openviduConfig;
|
protected OpenviduConfig openviduConfig;
|
||||||
|
|
||||||
@RequestMapping(value = "/sessions", method = RequestMethod.POST)
|
@RequestMapping(value = "/sessions", method = RequestMethod.POST)
|
||||||
public ResponseEntity<?> initializeSession(@RequestBody(required = false) Map<?, ?> params) {
|
public ResponseEntity<?> initializeSession(@RequestBody(required = false) Map<String, ?> params) {
|
||||||
|
|
||||||
log.info("REST API: POST {}/sessions {}", RequestMappings.API, params != null ? params.toString() : "{}");
|
log.info("REST API: POST {}/sessions {}", RequestMappings.API, params != null ? params.toString() : "{}");
|
||||||
|
|
||||||
SessionProperties sessionProperties;
|
SessionProperties sessionProperties;
|
||||||
try {
|
try {
|
||||||
sessionProperties = getSessionPropertiesFromParams((Map<String, ?>) params).build();
|
sessionProperties = getSessionPropertiesFromParams(params).build();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return this.generateErrorResponse(e.getMessage(), "/sessions", HttpStatus.BAD_REQUEST);
|
return this.generateErrorResponse(e.getMessage(), "/sessions", HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
@ -275,7 +271,7 @@ public class SessionRestController {
|
||||||
|
|
||||||
@RequestMapping(value = "/sessions/{sessionId}/connection", method = RequestMethod.POST)
|
@RequestMapping(value = "/sessions/{sessionId}/connection", method = RequestMethod.POST)
|
||||||
public ResponseEntity<?> initializeConnection(@PathVariable("sessionId") String sessionId,
|
public ResponseEntity<?> initializeConnection(@PathVariable("sessionId") String sessionId,
|
||||||
@RequestBody Map<?, ?> params) {
|
@RequestBody Map<String, ?> params) {
|
||||||
|
|
||||||
log.info("REST API: POST {} {}", RequestMappings.API + "/sessions/" + sessionId + "/connection",
|
log.info("REST API: POST {} {}", RequestMappings.API + "/sessions/" + sessionId + "/connection",
|
||||||
params.toString());
|
params.toString());
|
||||||
|
@ -374,7 +370,7 @@ public class SessionRestController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/recordings/start", method = RequestMethod.POST)
|
@RequestMapping(value = "/recordings/start", method = RequestMethod.POST)
|
||||||
public ResponseEntity<?> startRecording(@RequestBody Map<?, ?> params) {
|
public ResponseEntity<?> startRecording(@RequestBody Map<String, ?> params) {
|
||||||
|
|
||||||
if (params == null) {
|
if (params == null) {
|
||||||
return this.generateErrorResponse("Error in body parameters. Cannot be empty", "/recordings/start",
|
return this.generateErrorResponse("Error in body parameters. Cannot be empty", "/recordings/start",
|
||||||
|
@ -559,7 +555,7 @@ public class SessionRestController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/tokens", method = RequestMethod.POST)
|
@RequestMapping(value = "/tokens", method = RequestMethod.POST)
|
||||||
public ResponseEntity<String> newToken(@RequestBody Map<?, ?> params) {
|
public ResponseEntity<String> newToken(@RequestBody Map<String, ?> params) {
|
||||||
|
|
||||||
if (params == null) {
|
if (params == null) {
|
||||||
return this.generateErrorResponse("Error in body parameters. Cannot be empty", "/tokens",
|
return this.generateErrorResponse("Error in body parameters. Cannot be empty", "/tokens",
|
||||||
|
@ -642,7 +638,7 @@ public class SessionRestController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/signal", method = RequestMethod.POST)
|
@RequestMapping(value = "/signal", method = RequestMethod.POST)
|
||||||
public ResponseEntity<?> signal(@RequestBody Map<?, ?> params) {
|
public ResponseEntity<?> signal(@RequestBody Map<String, ?> params) {
|
||||||
|
|
||||||
if (params == null) {
|
if (params == null) {
|
||||||
return this.generateErrorResponse("Error in body parameters. Cannot be empty", "/signal",
|
return this.generateErrorResponse("Error in body parameters. Cannot be empty", "/signal",
|
||||||
|
@ -837,158 +833,21 @@ public class SessionRestController {
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ConnectionProperties.Builder getConnectionPropertiesFromParams(Map<?, ?> params) throws Exception {
|
protected ConnectionProperties.Builder getConnectionPropertiesFromParams(Map<String, ?> params) throws Exception {
|
||||||
|
|
||||||
ConnectionProperties.Builder builder = new ConnectionProperties.Builder();
|
ConnectionProperties.Builder builder = ConnectionProperties.fromJson(params);
|
||||||
|
|
||||||
String typeString;
|
ConnectionType type = ConnectionProperties.fromJson(params).build().getType();
|
||||||
String data;
|
|
||||||
try {
|
|
||||||
typeString = (String) params.get("type");
|
|
||||||
data = (String) params.get("data");
|
|
||||||
} catch (ClassCastException e) {
|
|
||||||
throw new Exception("Type error in some parameter: " + e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
ConnectionType type;
|
|
||||||
try {
|
|
||||||
if (typeString != null) {
|
|
||||||
type = ConnectionType.valueOf(typeString);
|
|
||||||
} else {
|
|
||||||
type = ConnectionType.WEBRTC;
|
|
||||||
}
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
throw new Exception("Parameter 'type' " + typeString + " is not defined");
|
|
||||||
}
|
|
||||||
data = data != null ? data : "";
|
|
||||||
|
|
||||||
// Build COMMON options
|
|
||||||
builder.type(type).data(data).record(true);
|
|
||||||
|
|
||||||
OpenViduRole role = null;
|
|
||||||
KurentoOptions kurentoOptions = null;
|
|
||||||
|
|
||||||
if (ConnectionType.WEBRTC.equals(type)) {
|
if (ConnectionType.WEBRTC.equals(type)) {
|
||||||
String roleString;
|
if (params.get("customIceServers") == null && !openviduConfig.getWebrtcIceServersBuilders().isEmpty()) {
|
||||||
try {
|
// If not defined in Connection, check if defined in OpenVidu global config
|
||||||
roleString = (String) params.get("role");
|
|
||||||
} catch (ClassCastException e) {
|
|
||||||
throw new Exception("Type error in parameter 'role': " + e.getMessage());
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
if (roleString != null) {
|
|
||||||
role = OpenViduRole.valueOf(roleString);
|
|
||||||
} else {
|
|
||||||
role = OpenViduRole.PUBLISHER;
|
|
||||||
}
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
throw new Exception("Parameter role " + params.get("role") + " is not defined");
|
|
||||||
}
|
|
||||||
JsonObject kurentoOptionsJson = null;
|
|
||||||
if (params.get("kurentoOptions") != null) {
|
|
||||||
try {
|
|
||||||
kurentoOptionsJson = new Gson().toJsonTree(params.get("kurentoOptions"), Map.class)
|
|
||||||
.getAsJsonObject();
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new Exception("Error in parameter 'kurentoOptions'. It is not a valid JSON object");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (kurentoOptionsJson != null) {
|
|
||||||
try {
|
|
||||||
KurentoOptions.Builder builder2 = new KurentoOptions.Builder();
|
|
||||||
if (kurentoOptionsJson.has("videoMaxRecvBandwidth")) {
|
|
||||||
builder2.videoMaxRecvBandwidth(kurentoOptionsJson.get("videoMaxRecvBandwidth").getAsInt());
|
|
||||||
}
|
|
||||||
if (kurentoOptionsJson.has("videoMinRecvBandwidth")) {
|
|
||||||
builder2.videoMinRecvBandwidth(kurentoOptionsJson.get("videoMinRecvBandwidth").getAsInt());
|
|
||||||
}
|
|
||||||
if (kurentoOptionsJson.has("videoMaxSendBandwidth")) {
|
|
||||||
builder2.videoMaxSendBandwidth(kurentoOptionsJson.get("videoMaxSendBandwidth").getAsInt());
|
|
||||||
}
|
|
||||||
if (kurentoOptionsJson.has("videoMinSendBandwidth")) {
|
|
||||||
builder2.videoMinSendBandwidth(kurentoOptionsJson.get("videoMinSendBandwidth").getAsInt());
|
|
||||||
}
|
|
||||||
if (kurentoOptionsJson.has("allowedFilters")) {
|
|
||||||
JsonArray filters = kurentoOptionsJson.get("allowedFilters").getAsJsonArray();
|
|
||||||
String[] arrayOfFilters = new String[filters.size()];
|
|
||||||
Iterator<JsonElement> it = filters.iterator();
|
|
||||||
int index = 0;
|
|
||||||
while (it.hasNext()) {
|
|
||||||
arrayOfFilters[index] = it.next().getAsString();
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
builder2.allowedFilters(arrayOfFilters);
|
|
||||||
}
|
|
||||||
kurentoOptions = builder2.build();
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new Exception("Type error in some parameter of 'kurentoOptions': " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Custom Ice Servers
|
|
||||||
JsonArray customIceServersJsonArray = null;
|
|
||||||
if (params.get("customIceServers") != null) {
|
|
||||||
try {
|
|
||||||
customIceServersJsonArray = new Gson().toJsonTree(params.get("customIceServers"), List.class)
|
|
||||||
.getAsJsonArray();
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new Exception("Error in parameter 'customIceServersJson'. It is not a valid JSON object");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (customIceServersJsonArray != null) {
|
|
||||||
try {
|
|
||||||
for (int i = 0; i < customIceServersJsonArray.size(); i++) {
|
|
||||||
JsonObject customIceServerJson = customIceServersJsonArray.get(i).getAsJsonObject();
|
|
||||||
IceServerProperties.Builder iceServerPropertiesBuilder = new IceServerProperties.Builder();
|
|
||||||
iceServerPropertiesBuilder.url(customIceServerJson.get("url").getAsString());
|
|
||||||
if (customIceServerJson.has("staticAuthSecret")) {
|
|
||||||
iceServerPropertiesBuilder
|
|
||||||
.staticAuthSecret(customIceServerJson.get("staticAuthSecret").getAsString());
|
|
||||||
}
|
|
||||||
if (customIceServerJson.has("username")) {
|
|
||||||
iceServerPropertiesBuilder.username(customIceServerJson.get("username").getAsString());
|
|
||||||
}
|
|
||||||
if (customIceServerJson.has("credential")) {
|
|
||||||
iceServerPropertiesBuilder.credential(customIceServerJson.get("credential").getAsString());
|
|
||||||
}
|
|
||||||
IceServerProperties iceServerProperties = iceServerPropertiesBuilder.build();
|
|
||||||
builder.addCustomIceServer(iceServerProperties);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new Exception("Type error in some parameter of 'customIceServers': " + e.getMessage());
|
|
||||||
}
|
|
||||||
} else if (!openviduConfig.getWebrtcIceServersBuilders().isEmpty()) {
|
|
||||||
// If not defined in connection, check if defined in openvidu config
|
|
||||||
for (IceServerProperties.Builder iceServerPropertiesBuilder : openviduConfig
|
for (IceServerProperties.Builder iceServerPropertiesBuilder : openviduConfig
|
||||||
.getWebrtcIceServersBuilders()) {
|
.getWebrtcIceServersBuilders()) {
|
||||||
IceServerProperties.Builder configIceBuilder = iceServerPropertiesBuilder.clone();
|
IceServerProperties.Builder configIceBuilder = iceServerPropertiesBuilder.clone();
|
||||||
builder.addCustomIceServer(configIceBuilder.build());
|
builder.addCustomIceServer(configIceBuilder.build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build WEBRTC options
|
|
||||||
builder.role(role).kurentoOptions(kurentoOptions);
|
|
||||||
|
|
||||||
} else if (ConnectionType.IPCAM.equals(type)) {
|
|
||||||
String rtspUri;
|
|
||||||
Boolean adaptativeBitrate;
|
|
||||||
Boolean onlyPlayWithSubscribers;
|
|
||||||
Integer networkCache;
|
|
||||||
try {
|
|
||||||
rtspUri = (String) params.get("rtspUri");
|
|
||||||
adaptativeBitrate = (Boolean) params.get("adaptativeBitrate");
|
|
||||||
onlyPlayWithSubscribers = (Boolean) params.get("onlyPlayWithSubscribers");
|
|
||||||
networkCache = (Integer) params.get("networkCache");
|
|
||||||
} catch (ClassCastException e) {
|
|
||||||
throw new Exception("Type error in some parameter: " + e.getMessage());
|
|
||||||
}
|
|
||||||
adaptativeBitrate = adaptativeBitrate != null ? adaptativeBitrate : true;
|
|
||||||
onlyPlayWithSubscribers = onlyPlayWithSubscribers != null ? onlyPlayWithSubscribers : true;
|
|
||||||
networkCache = networkCache != null ? networkCache : 2000;
|
|
||||||
|
|
||||||
// Build IPCAM options
|
|
||||||
builder.rtspUri(rtspUri).adaptativeBitrate(adaptativeBitrate)
|
|
||||||
.onlyPlayWithSubscribers(onlyPlayWithSubscribers).networkCache(networkCache).build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
|
|
Loading…
Reference in New Issue