mirror of https://github.com/OpenVidu/openvidu.git
commit
fd6eb2017f
|
@ -25,11 +25,6 @@ import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.JsonArray;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonSyntaxException;
|
|
||||||
|
|
||||||
import org.apache.http.HttpHeaders;
|
import org.apache.http.HttpHeaders;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.client.methods.HttpDelete;
|
import org.apache.http.client.methods.HttpDelete;
|
||||||
|
@ -40,6 +35,12 @@ import org.apache.http.util.EntityUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonNull;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonSyntaxException;
|
||||||
|
|
||||||
public class Session {
|
public class Session {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(Session.class);
|
private static final Logger log = LoggerFactory.getLogger(Session.class);
|
||||||
|
@ -120,8 +121,22 @@ public class Session {
|
||||||
|
|
||||||
JsonObject json = new JsonObject();
|
JsonObject json = new JsonObject();
|
||||||
json.addProperty("session", this.sessionId);
|
json.addProperty("session", this.sessionId);
|
||||||
json.addProperty("role", tokenOptions.getRole().name());
|
|
||||||
json.addProperty("data", tokenOptions.getData());
|
if (tokenOptions.getData() != null) {
|
||||||
|
json.addProperty("data", tokenOptions.getData());
|
||||||
|
} else {
|
||||||
|
json.add("data", JsonNull.INSTANCE);
|
||||||
|
}
|
||||||
|
if (tokenOptions.getRole() != null) {
|
||||||
|
json.addProperty("role", tokenOptions.getRole().name());
|
||||||
|
} else {
|
||||||
|
json.add("role", JsonNull.INSTANCE);
|
||||||
|
}
|
||||||
|
if (tokenOptions.record() != null) {
|
||||||
|
json.addProperty("record", tokenOptions.record());
|
||||||
|
} else {
|
||||||
|
json.add("record", JsonNull.INSTANCE);
|
||||||
|
}
|
||||||
if (tokenOptions.getKurentoOptions() != null) {
|
if (tokenOptions.getKurentoOptions() != null) {
|
||||||
JsonObject kurentoOptions = new JsonObject();
|
JsonObject kurentoOptions = new JsonObject();
|
||||||
if (tokenOptions.getKurentoOptions().getVideoMaxRecvBandwidth() != null) {
|
if (tokenOptions.getKurentoOptions().getVideoMaxRecvBandwidth() != null) {
|
||||||
|
|
|
@ -24,6 +24,7 @@ public class TokenOptions {
|
||||||
|
|
||||||
private String data;
|
private String data;
|
||||||
private OpenViduRole role;
|
private OpenViduRole role;
|
||||||
|
private Boolean record;
|
||||||
private KurentoOptions kurentoOptions;
|
private KurentoOptions kurentoOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,15 +34,16 @@ public class TokenOptions {
|
||||||
*/
|
*/
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
|
||||||
private String data = "";
|
private String data;
|
||||||
private OpenViduRole role = OpenViduRole.PUBLISHER;
|
private OpenViduRole role;
|
||||||
|
private Boolean record;
|
||||||
private KurentoOptions kurentoOptions;
|
private KurentoOptions kurentoOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builder for {@link io.openvidu.java.client.TokenOptions}
|
* Builder for {@link io.openvidu.java.client.TokenOptions}
|
||||||
*/
|
*/
|
||||||
public TokenOptions build() {
|
public TokenOptions build() {
|
||||||
return new TokenOptions(this.data, this.role, this.kurentoOptions);
|
return new TokenOptions(this.data, this.role, this.record, this.kurentoOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -79,6 +81,17 @@ public class TokenOptions {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call this method to flag the streams published by the participant
|
||||||
|
* owning this token to be recorded or not. This only affects <a href=
|
||||||
|
* "https://docs.openvidu.io/en/stable/advanced-features/recording#selecting-streams-to-be-recorded"
|
||||||
|
* target="_blank">INDIVIDUAL recording</a>. If not set by default will be true
|
||||||
|
*/
|
||||||
|
public Builder record(boolean record) {
|
||||||
|
this.record = record;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call this method to set a {@link io.openvidu.java.client.KurentoOptions}
|
* Call this method to set a {@link io.openvidu.java.client.KurentoOptions}
|
||||||
* object for this token
|
* object for this token
|
||||||
|
@ -90,9 +103,10 @@ public class TokenOptions {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private TokenOptions(String data, OpenViduRole role, KurentoOptions kurentoOptions) {
|
private TokenOptions(String data, OpenViduRole role, Boolean record, KurentoOptions kurentoOptions) {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
this.role = role;
|
this.role = role;
|
||||||
|
this.record = record;
|
||||||
this.kurentoOptions = kurentoOptions;
|
this.kurentoOptions = kurentoOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,6 +124,16 @@ public class TokenOptions {
|
||||||
return this.role;
|
return this.role;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the streams published by the participant owning this token will be
|
||||||
|
* recorded or not. This only affects <a href=
|
||||||
|
* "https://docs.openvidu.io/en/stable/advanced-features/recording#selecting-streams-to-be-recorded"
|
||||||
|
* target="_blank">INDIVIDUAL recording</a>
|
||||||
|
*/
|
||||||
|
public Boolean record() {
|
||||||
|
return this.record;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the Kurento options assigned to this token
|
* Returns the Kurento options assigned to this token
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -105,9 +105,10 @@ export class Session {
|
||||||
|
|
||||||
const data = JSON.stringify({
|
const data = JSON.stringify({
|
||||||
session: this.sessionId,
|
session: this.sessionId,
|
||||||
role: (!!tokenOptions && !!tokenOptions.role) ? tokenOptions.role : OpenViduRole.PUBLISHER,
|
data: (!!tokenOptions && !!tokenOptions.data) ? tokenOptions.data : null,
|
||||||
data: (!!tokenOptions && !!tokenOptions.data) ? tokenOptions.data : '',
|
role: (!!tokenOptions && !!tokenOptions.role) ? tokenOptions.role : null,
|
||||||
kurentoOptions: (!!tokenOptions && !!tokenOptions.kurentoOptions) ? tokenOptions.kurentoOptions : {},
|
record: !!tokenOptions ? tokenOptions.record : null,
|
||||||
|
kurentoOptions: (!!tokenOptions && !!tokenOptions.kurentoOptions) ? tokenOptions.kurentoOptions : null
|
||||||
});
|
});
|
||||||
|
|
||||||
axios.post(
|
axios.post(
|
||||||
|
|
|
@ -32,9 +32,18 @@ export interface TokenOptions {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The role assigned to this token
|
* The role assigned to this token
|
||||||
|
*
|
||||||
|
* @default PUBLISHER
|
||||||
*/
|
*/
|
||||||
role?: OpenViduRole;
|
role?: OpenViduRole;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to record the streams published by the participant owning this token or not. This only affects [INDIVIDUAL recording](/en/stable/advanced-features/recording#selecting-streams-to-be-recorded)
|
||||||
|
*
|
||||||
|
* @default true
|
||||||
|
*/
|
||||||
|
record?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* **WARNING**: experimental option. This interface may change in the near future
|
* **WARNING**: experimental option. This interface may change in the near future
|
||||||
*
|
*
|
||||||
|
|
|
@ -47,7 +47,7 @@ fi
|
||||||
|
|
||||||
touch xvfb.log
|
touch xvfb.log
|
||||||
chmod 777 xvfb.log
|
chmod 777 xvfb.log
|
||||||
xvfb-run --auto-servernum --server-args="-ac -screen 0 ${RESOLUTION}x24 -noreset" google-chrome --kiosk --start-maximized --test-type --no-sandbox --disable-infobars --disable-gpu --disable-popup-blocking --window-size=$WIDTH,$HEIGHT --window-position=0,0 --no-first-run --ignore-certificate-errors --autoplay-policy=no-user-gesture-required $DEBUG_CHROME_FLAGS $URL &> xvfb.log &
|
xvfb-run --auto-servernum --server-args="-ac -screen 0 ${RESOLUTION}x24 -noreset" google-chrome --kiosk --start-maximized --test-type --no-sandbox --disable-infobars --disable-gpu --disable-popup-blocking --window-size=$WIDTH,$HEIGHT --window-position=0,0 --no-first-run --ignore-certificate-errors --disable-dev-shm-usage --autoplay-policy=no-user-gesture-required $DEBUG_CHROME_FLAGS $URL &> xvfb.log &
|
||||||
touch stop
|
touch stop
|
||||||
chmod 777 /recordings
|
chmod 777 /recordings
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ if [[ -z "${COMPOSED_QUICK_START_ACTION}" ]]; then
|
||||||
|
|
||||||
touch xvfb.log
|
touch xvfb.log
|
||||||
chmod 777 xvfb.log
|
chmod 777 xvfb.log
|
||||||
xvfb-run --auto-servernum --server-args="-ac -screen 0 ${RESOLUTION}x24 -noreset" google-chrome --kiosk --start-maximized --test-type --no-sandbox --disable-infobars --disable-gpu --disable-popup-blocking --window-size=$WIDTH,$HEIGHT --window-position=0,0 --no-first-run --ignore-certificate-errors --autoplay-policy=no-user-gesture-required --enable-logging --v=1 $DEBUG_CHROME_FLAGS $URL &> xvfb.log &
|
xvfb-run --auto-servernum --server-args="-ac -screen 0 ${RESOLUTION}x24 -noreset" google-chrome --kiosk --start-maximized --test-type --no-sandbox --disable-infobars --disable-gpu --disable-popup-blocking --window-size=$WIDTH,$HEIGHT --window-position=0,0 --no-first-run --ignore-certificate-errors --disable-dev-shm-usage --autoplay-policy=no-user-gesture-required --enable-logging --v=1 $DEBUG_CHROME_FLAGS $URL &> xvfb.log &
|
||||||
chmod 777 /recordings
|
chmod 777 /recordings
|
||||||
|
|
||||||
until pids=$(pidof Xvfb)
|
until pids=$(pidof Xvfb)
|
||||||
|
|
|
@ -50,7 +50,6 @@ import io.openvidu.server.config.OpenviduConfig.Error;
|
||||||
import io.openvidu.server.core.SessionEventsHandler;
|
import io.openvidu.server.core.SessionEventsHandler;
|
||||||
import io.openvidu.server.core.SessionManager;
|
import io.openvidu.server.core.SessionManager;
|
||||||
import io.openvidu.server.core.TokenGenerator;
|
import io.openvidu.server.core.TokenGenerator;
|
||||||
import io.openvidu.server.core.TokenGeneratorDefault;
|
|
||||||
import io.openvidu.server.coturn.CoturnCredentialsService;
|
import io.openvidu.server.coturn.CoturnCredentialsService;
|
||||||
import io.openvidu.server.coturn.CoturnCredentialsServiceFactory;
|
import io.openvidu.server.coturn.CoturnCredentialsServiceFactory;
|
||||||
import io.openvidu.server.kurento.core.KurentoParticipantEndpointConfig;
|
import io.openvidu.server.kurento.core.KurentoParticipantEndpointConfig;
|
||||||
|
@ -157,7 +156,7 @@ public class OpenViduServer implements JsonRpcConfigurer {
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
@DependsOn("openviduConfig")
|
@DependsOn("openviduConfig")
|
||||||
public TokenGenerator tokenGenerator() {
|
public TokenGenerator tokenGenerator() {
|
||||||
return new TokenGeneratorDefault();
|
return new TokenGenerator();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|
|
@ -60,6 +60,7 @@ public class Session implements SessionInterface {
|
||||||
|
|
||||||
protected volatile boolean closed = false;
|
protected volatile boolean closed = false;
|
||||||
protected AtomicInteger activePublishers = new AtomicInteger(0);
|
protected AtomicInteger activePublishers = new AtomicInteger(0);
|
||||||
|
protected AtomicInteger activeIndividualRecordedPublishers = new AtomicInteger(0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This lock protects the following operations with read lock: [REST API](POST
|
* This lock protects the following operations with read lock: [REST API](POST
|
||||||
|
@ -145,12 +146,22 @@ public class Session implements SessionInterface {
|
||||||
return activePublishers.get();
|
return activePublishers.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerPublisher() {
|
public int getActiveIndividualRecordedPublishers() {
|
||||||
this.activePublishers.incrementAndGet();
|
return activeIndividualRecordedPublishers.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deregisterPublisher() {
|
public void registerPublisher(Participant participant) {
|
||||||
|
this.activePublishers.incrementAndGet();
|
||||||
|
if (participant.getToken().record()) {
|
||||||
|
activeIndividualRecordedPublishers.incrementAndGet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deregisterPublisher(Participant participant) {
|
||||||
this.activePublishers.decrementAndGet();
|
this.activePublishers.decrementAndGet();
|
||||||
|
if (participant.getToken().record()) {
|
||||||
|
activeIndividualRecordedPublishers.decrementAndGet();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void storeToken(Token token) {
|
public void storeToken(Token token) {
|
||||||
|
|
|
@ -297,13 +297,13 @@ public abstract class SessionManager {
|
||||||
return sessionNotActive;
|
return sessionNotActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String newToken(Session session, OpenViduRole role, String serverMetadata,
|
public String newToken(Session session, OpenViduRole role, String serverMetadata, boolean record,
|
||||||
KurentoTokenOptions kurentoTokenOptions) throws Exception {
|
KurentoTokenOptions kurentoTokenOptions) throws Exception {
|
||||||
if (!formatChecker.isServerMetadataFormatCorrect(serverMetadata)) {
|
if (!formatChecker.isServerMetadataFormatCorrect(serverMetadata)) {
|
||||||
log.error("Data invalid format");
|
log.error("Data invalid format");
|
||||||
throw new OpenViduException(Code.GENERIC_ERROR_CODE, "Data invalid format");
|
throw new OpenViduException(Code.GENERIC_ERROR_CODE, "Data invalid format");
|
||||||
}
|
}
|
||||||
Token tokenObj = tokenGenerator.generateToken(session.getSessionId(), role, serverMetadata,
|
Token tokenObj = tokenGenerator.generateToken(session.getSessionId(), role, serverMetadata, record,
|
||||||
kurentoTokenOptions);
|
kurentoTokenOptions);
|
||||||
session.storeToken(tokenObj);
|
session.storeToken(tokenObj);
|
||||||
session.showTokens("Token created");
|
session.showTokens("Token created");
|
||||||
|
@ -312,7 +312,8 @@ public abstract class SessionManager {
|
||||||
|
|
||||||
public Token newTokenForInsecureUser(Session session, String token, String serverMetadata) throws Exception {
|
public Token newTokenForInsecureUser(Session session, String token, String serverMetadata) throws Exception {
|
||||||
Token tokenObj = new Token(token, OpenViduRole.PUBLISHER, serverMetadata != null ? serverMetadata : "",
|
Token tokenObj = new Token(token, OpenViduRole.PUBLISHER, serverMetadata != null ? serverMetadata : "",
|
||||||
this.openviduConfig.isTurnadminAvailable() ? this.coturnCredentialsService.createUser() : null, null);
|
this.openviduConfig.isTurnadminAvailable() ? this.coturnCredentialsService.createUser() : null, true,
|
||||||
|
null);
|
||||||
session.storeToken(tokenObj);
|
session.storeToken(tokenObj);
|
||||||
session.showTokens("Token created for insecure user");
|
session.showTokens("Token created for insecure user");
|
||||||
return tokenObj;
|
return tokenObj;
|
||||||
|
|
|
@ -27,6 +27,7 @@ public class Token {
|
||||||
private OpenViduRole role;
|
private OpenViduRole role;
|
||||||
private String serverMetadata = "";
|
private String serverMetadata = "";
|
||||||
private TurnCredentials turnCredentials;
|
private TurnCredentials turnCredentials;
|
||||||
|
private boolean record = true;
|
||||||
|
|
||||||
private KurentoTokenOptions kurentoTokenOptions;
|
private KurentoTokenOptions kurentoTokenOptions;
|
||||||
|
|
||||||
|
@ -35,11 +36,12 @@ public class Token {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Token(String token, OpenViduRole role, String serverMetadata, TurnCredentials turnCredentials,
|
public Token(String token, OpenViduRole role, String serverMetadata, TurnCredentials turnCredentials,
|
||||||
KurentoTokenOptions kurentoTokenOptions) {
|
boolean record, KurentoTokenOptions kurentoTokenOptions) {
|
||||||
this.token = token;
|
this.token = token;
|
||||||
this.role = role;
|
this.role = role;
|
||||||
this.serverMetadata = serverMetadata;
|
this.serverMetadata = serverMetadata;
|
||||||
this.turnCredentials = turnCredentials;
|
this.turnCredentials = turnCredentials;
|
||||||
|
this.record = record;
|
||||||
this.kurentoTokenOptions = kurentoTokenOptions;
|
this.kurentoTokenOptions = kurentoTokenOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +65,10 @@ public class Token {
|
||||||
return turnCredentials;
|
return turnCredentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean record() {
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
public KurentoTokenOptions getKurentoTokenOptions() {
|
public KurentoTokenOptions getKurentoTokenOptions() {
|
||||||
return kurentoTokenOptions;
|
return kurentoTokenOptions;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,45 @@
|
||||||
|
|
||||||
package io.openvidu.server.core;
|
package io.openvidu.server.core;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
import io.openvidu.java.client.OpenViduRole;
|
import io.openvidu.java.client.OpenViduRole;
|
||||||
|
import io.openvidu.server.OpenViduServer;
|
||||||
|
import io.openvidu.server.config.OpenviduBuildInfo;
|
||||||
|
import io.openvidu.server.config.OpenviduConfig;
|
||||||
|
import io.openvidu.server.coturn.CoturnCredentialsService;
|
||||||
|
import io.openvidu.server.coturn.TurnCredentials;
|
||||||
import io.openvidu.server.kurento.core.KurentoTokenOptions;
|
import io.openvidu.server.kurento.core.KurentoTokenOptions;
|
||||||
|
|
||||||
public interface TokenGenerator {
|
public class TokenGenerator {
|
||||||
|
|
||||||
public Token generateToken(String sessionId, OpenViduRole role, String serverMetadata,
|
@Autowired
|
||||||
KurentoTokenOptions kurentoTokenOptions) throws Exception;
|
private CoturnCredentialsService coturnCredentialsService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected OpenviduConfig openviduConfig;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected OpenviduBuildInfo openviduBuildConfig;
|
||||||
|
|
||||||
|
public Token generateToken(String sessionId, OpenViduRole role, String serverMetadata, boolean record,
|
||||||
|
KurentoTokenOptions kurentoTokenOptions) throws Exception {
|
||||||
|
String token = OpenViduServer.wsUrl;
|
||||||
|
token += "?sessionId=" + sessionId;
|
||||||
|
token += "&token=" + IdentifierPrefixes.TOKEN_ID + RandomStringUtils.randomAlphabetic(1).toUpperCase()
|
||||||
|
+ RandomStringUtils.randomAlphanumeric(15);
|
||||||
|
token += "&role=" + role.name();
|
||||||
|
token += "&version=" + openviduBuildConfig.getOpenViduServerVersion();
|
||||||
|
TurnCredentials turnCredentials = null;
|
||||||
|
if (this.openviduConfig.isTurnadminAvailable()) {
|
||||||
|
turnCredentials = coturnCredentialsService.createUser();
|
||||||
|
if (turnCredentials != null) {
|
||||||
|
token += "&coturnIp=" + openviduConfig.getCoturnIp();
|
||||||
|
token += "&turnUsername=" + turnCredentials.getUsername();
|
||||||
|
token += "&turnCredential=" + turnCredentials.getCredential();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Token(token, role, serverMetadata, turnCredentials, record, kurentoTokenOptions);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
/*
|
|
||||||
* (C) Copyright 2017-2020 OpenVidu (https://openvidu.io)
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.openvidu.server.core;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
|
|
||||||
import io.openvidu.java.client.OpenViduRole;
|
|
||||||
import io.openvidu.server.OpenViduServer;
|
|
||||||
import io.openvidu.server.config.OpenviduBuildInfo;
|
|
||||||
import io.openvidu.server.config.OpenviduConfig;
|
|
||||||
import io.openvidu.server.coturn.CoturnCredentialsService;
|
|
||||||
import io.openvidu.server.coturn.TurnCredentials;
|
|
||||||
import io.openvidu.server.kurento.core.KurentoTokenOptions;
|
|
||||||
|
|
||||||
public class TokenGeneratorDefault implements TokenGenerator {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private CoturnCredentialsService coturnCredentialsService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
protected OpenviduConfig openviduConfig;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
protected OpenviduBuildInfo openviduBuildConfig;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Token generateToken(String sessionId, OpenViduRole role, String serverMetadata,
|
|
||||||
KurentoTokenOptions kurentoTokenOptions) throws Exception {
|
|
||||||
String token = OpenViduServer.wsUrl;
|
|
||||||
token += "?sessionId=" + sessionId;
|
|
||||||
token += "&token=" + IdentifierPrefixes.TOKEN_ID + RandomStringUtils.randomAlphabetic(1).toUpperCase()
|
|
||||||
+ RandomStringUtils.randomAlphanumeric(15);
|
|
||||||
token += "&role=" + role.name();
|
|
||||||
token += "&version=" + openviduBuildConfig.getOpenViduServerVersion();
|
|
||||||
TurnCredentials turnCredentials = null;
|
|
||||||
if (this.openviduConfig.isTurnadminAvailable()) {
|
|
||||||
turnCredentials = coturnCredentialsService.createUser();
|
|
||||||
if (turnCredentials != null) {
|
|
||||||
token += "&coturnIp=" + openviduConfig.getCoturnIp();
|
|
||||||
token += "&turnUsername=" + turnCredentials.getUsername();
|
|
||||||
token += "&turnCredential=" + turnCredentials.getCredential();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new Token(token, role, serverMetadata, turnCredentials, kurentoTokenOptions);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -181,7 +181,7 @@ public class KurentoParticipant extends Participant {
|
||||||
this.session.getSessionId());
|
this.session.getSessionId());
|
||||||
|
|
||||||
if (this.openviduConfig.isRecordingModuleEnabled()
|
if (this.openviduConfig.isRecordingModuleEnabled()
|
||||||
&& this.recordingManager.sessionIsBeingRecorded(session.getSessionId())) {
|
&& this.recordingManager.sessionIsBeingRecorded(session.getSessionId()) && this.token.record()) {
|
||||||
this.recordingManager.startOneIndividualStreamRecording(session, null, null, this);
|
this.recordingManager.startOneIndividualStreamRecording(session, null, null, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,7 +504,7 @@ public class KurentoParticipant extends Participant {
|
||||||
}
|
}
|
||||||
releaseElement(getParticipantPublicId(), publisher.getEndpoint());
|
releaseElement(getParticipantPublicId(), publisher.getEndpoint());
|
||||||
this.streaming = false;
|
this.streaming = false;
|
||||||
this.session.deregisterPublisher();
|
this.session.deregisterPublisher(this);
|
||||||
|
|
||||||
endpointConfig.getCdr().stopPublisher(this.getParticipantPublicId(), publisher.getStreamId(), reason);
|
endpointConfig.getCdr().stopPublisher(this.getParticipantPublicId(), publisher.getStreamId(), reason);
|
||||||
publisher = null;
|
publisher = null;
|
||||||
|
|
|
@ -88,7 +88,7 @@ public class KurentoSession extends Session {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void newPublisher(Participant participant) {
|
public void newPublisher(Participant participant) {
|
||||||
registerPublisher();
|
registerPublisher(participant);
|
||||||
log.debug("SESSION {}: Virtually subscribed other participants {} to new publisher {}", sessionId,
|
log.debug("SESSION {}: Virtually subscribed other participants {} to new publisher {}", sessionId,
|
||||||
participants.values(), participant.getParticipantPublicId());
|
participants.values(), participant.getParticipantPublicId());
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,7 +97,7 @@ public class ComposedQuickStartRecordingService extends ComposedRecordingService
|
||||||
log.info("Stopping COMPOSED_QUICK_START ({}) recording {} of session {}. Reason: {}",
|
log.info("Stopping COMPOSED_QUICK_START ({}) recording {} of session {}. Reason: {}",
|
||||||
recording.hasAudio() ? "video + audio" : "audio-only", recording.getId(), recording.getSessionId(),
|
recording.hasAudio() ? "video + audio" : "audio-only", recording.getId(), recording.getSessionId(),
|
||||||
RecordingManager.finalReason(reason));
|
RecordingManager.finalReason(reason));
|
||||||
log.info("Container for session {} still being ready for new recordings", session.getSessionId());
|
log.info("Container for session {} still being ready for new recordings", recording.getSessionId());
|
||||||
|
|
||||||
String containerId = this.sessionsContainers.get(recording.getSessionId());
|
String containerId = this.sessionsContainers.get(recording.getSessionId());
|
||||||
|
|
||||||
|
@ -119,10 +119,7 @@ public class ComposedQuickStartRecordingService extends ComposedRecordingService
|
||||||
|
|
||||||
recording = updateRecordingAttributes(recording);
|
recording = updateRecordingAttributes(recording);
|
||||||
|
|
||||||
final String folderPath = this.openviduConfig.getOpenViduRecordingPath() + recording.getId() + "/";
|
this.sealRecordingMetadataFileAsReady(recording, recording.getSize(), recording.getDuration(), getMetadataFilePath(recording));
|
||||||
final String metadataFilePath = folderPath + RecordingManager.RECORDING_ENTITY_FILE + recording.getId();
|
|
||||||
this.sealRecordingMetadataFileAsReady(recording, recording.getSize(), recording.getDuration(),
|
|
||||||
metadataFilePath);
|
|
||||||
cleanRecordingMaps(recording);
|
cleanRecordingMaps(recording);
|
||||||
|
|
||||||
final long timestamp = System.currentTimeMillis();
|
final long timestamp = System.currentTimeMillis();
|
||||||
|
|
|
@ -103,7 +103,6 @@ public class ComposedRecordingService extends RecordingService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Recording stopRecording(Session session, Recording recording, EndReason reason) {
|
public Recording stopRecording(Session session, Recording recording, EndReason reason) {
|
||||||
recording = this.sealRecordingMetadataFileAsStopped(recording);
|
|
||||||
if (recording.hasVideo()) {
|
if (recording.hasVideo()) {
|
||||||
return this.stopRecordingWithVideo(session, recording, reason);
|
return this.stopRecordingWithVideo(session, recording, reason);
|
||||||
} else {
|
} else {
|
||||||
|
@ -297,10 +296,8 @@ public class ComposedRecordingService extends RecordingService {
|
||||||
stopAndRemoveRecordingContainer(recording, containerId, 30);
|
stopAndRemoveRecordingContainer(recording, containerId, 30);
|
||||||
recording = updateRecordingAttributes(recording);
|
recording = updateRecordingAttributes(recording);
|
||||||
|
|
||||||
final String folderPath = this.openviduConfig.getOpenViduRecordingPath() + recording.getId() + "/";
|
|
||||||
final String metadataFilePath = folderPath + RecordingManager.RECORDING_ENTITY_FILE + recording.getId();
|
|
||||||
this.sealRecordingMetadataFileAsReady(recording, recording.getSize(), recording.getDuration(),
|
this.sealRecordingMetadataFileAsReady(recording, recording.getSize(), recording.getDuration(),
|
||||||
metadataFilePath);
|
getMetadataFilePath(recording));
|
||||||
cleanRecordingMaps(recording);
|
cleanRecordingMaps(recording);
|
||||||
|
|
||||||
final long timestamp = System.currentTimeMillis();
|
final long timestamp = System.currentTimeMillis();
|
||||||
|
|
|
@ -279,8 +279,7 @@ public class RecordingManager {
|
||||||
this.sessionHandler.sendRecordingStartedNotification(session, recording);
|
this.sessionHandler.sendRecordingStartedNotification(session, recording);
|
||||||
}
|
}
|
||||||
if (session.getActivePublishers() == 0) {
|
if (session.getActivePublishers() == 0) {
|
||||||
// Init automatic recording stop if there are now publishers when starting
|
// Init automatic recording stop if no publishers when starting the recording
|
||||||
// recording
|
|
||||||
log.info("No publisher in session {}. Starting {} seconds countdown for stopping recording",
|
log.info("No publisher in session {}. Starting {} seconds countdown for stopping recording",
|
||||||
session.getSessionId(), this.openviduConfig.getOpenviduRecordingAutostopTimeout());
|
session.getSessionId(), this.openviduConfig.getOpenviduRecordingAutostopTimeout());
|
||||||
this.initAutomaticRecordingStopThread(session);
|
this.initAutomaticRecordingStopThread(session);
|
||||||
|
@ -310,6 +309,8 @@ public class RecordingManager {
|
||||||
recording = this.sessionsRecordings.get(session.getSessionId());
|
recording = this.sessionsRecordings.get(session.getSessionId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recording = ((RecordingService) singleStreamRecordingService).sealRecordingMetadataFileAsStopped(recording);
|
||||||
|
|
||||||
final long timestamp = System.currentTimeMillis();
|
final long timestamp = System.currentTimeMillis();
|
||||||
this.cdr.recordRecordingStatusChanged(recording, reason, timestamp, Status.stopped);
|
this.cdr.recordRecordingStatusChanged(recording, reason, timestamp, Status.stopped);
|
||||||
cdr.recordRecordingStopped(recording, reason, timestamp);
|
cdr.recordRecordingStopped(recording, reason, timestamp);
|
||||||
|
|
|
@ -175,6 +175,10 @@ public abstract class RecordingService {
|
||||||
protected OpenViduException failStartRecording(Session session, Recording recording, String errorMessage) {
|
protected OpenViduException failStartRecording(Session session, Recording recording, String errorMessage) {
|
||||||
log.error("Recording start failed for session {}: {}", session.getSessionId(), errorMessage);
|
log.error("Recording start failed for session {}: {}", session.getSessionId(), errorMessage);
|
||||||
recording.setStatus(io.openvidu.java.client.Recording.Status.failed);
|
recording.setStatus(io.openvidu.java.client.Recording.Status.failed);
|
||||||
|
|
||||||
|
sealRecordingMetadataFileAsReady(recording, recording.getSize(), recording.getDuration(),
|
||||||
|
getMetadataFilePath(recording));
|
||||||
|
|
||||||
this.recordingManager.startingRecordings.remove(recording.getId());
|
this.recordingManager.startingRecordings.remove(recording.getId());
|
||||||
this.recordingManager.sessionsRecordingsStarting.remove(session.getSessionId());
|
this.recordingManager.sessionsRecordingsStarting.remove(session.getSessionId());
|
||||||
this.stopRecording(session, recording, null);
|
this.stopRecording(session, recording, null);
|
||||||
|
@ -186,6 +190,11 @@ public abstract class RecordingService {
|
||||||
this.recordingManager.startedRecordings.remove(recording.getId());
|
this.recordingManager.startedRecordings.remove(recording.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String getMetadataFilePath(Recording recording) {
|
||||||
|
final String folderPath = this.openviduConfig.getOpenViduRecordingPath() + recording.getId() + "/";
|
||||||
|
return folderPath + RecordingManager.RECORDING_ENTITY_FILE + recording.getId();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple wrapper for returning update RecordingProperties and a free
|
* Simple wrapper for returning update RecordingProperties and a free
|
||||||
* recordingId when starting a new recording
|
* recordingId when starting a new recording
|
||||||
|
|
|
@ -98,11 +98,11 @@ public class SingleStreamRecordingService extends RecordingService {
|
||||||
activeRecorders.put(session.getSessionId(), new ConcurrentHashMap<String, RecorderEndpointWrapper>());
|
activeRecorders.put(session.getSessionId(), new ConcurrentHashMap<String, RecorderEndpointWrapper>());
|
||||||
storedRecorders.put(session.getSessionId(), new ConcurrentHashMap<String, RecorderEndpointWrapper>());
|
storedRecorders.put(session.getSessionId(), new ConcurrentHashMap<String, RecorderEndpointWrapper>());
|
||||||
|
|
||||||
final int activePublishers = session.getActivePublishers();
|
int activePublishersToRecord = session.getActiveIndividualRecordedPublishers();
|
||||||
final CountDownLatch recordingStartedCountdown = new CountDownLatch(activePublishers);
|
final CountDownLatch recordingStartedCountdown = new CountDownLatch(activePublishersToRecord);
|
||||||
|
|
||||||
for (Participant p : session.getParticipants()) {
|
for (Participant p : session.getParticipants()) {
|
||||||
if (p.isStreaming()) {
|
if (p.isStreaming() && p.getToken().record()) {
|
||||||
|
|
||||||
MediaProfileSpecType profile = null;
|
MediaProfileSpecType profile = null;
|
||||||
try {
|
try {
|
||||||
|
@ -139,7 +139,6 @@ public class SingleStreamRecordingService extends RecordingService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Recording stopRecording(Session session, Recording recording, EndReason reason) {
|
public Recording stopRecording(Session session, Recording recording, EndReason reason) {
|
||||||
recording = this.sealRecordingMetadataFileAsStopped(recording);
|
|
||||||
return this.stopRecording(session, recording, reason, 0);
|
return this.stopRecording(session, recording, reason, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,7 @@ public class SessionRestController {
|
||||||
if (customSessionId != null && !customSessionId.isEmpty()) {
|
if (customSessionId != null && !customSessionId.isEmpty()) {
|
||||||
if (!sessionManager.formatChecker.isValidCustomSessionId(customSessionId)) {
|
if (!sessionManager.formatChecker.isValidCustomSessionId(customSessionId)) {
|
||||||
return this.generateErrorResponse(
|
return this.generateErrorResponse(
|
||||||
"Parameter \"customSessionId\" is wrong. Must be an alphanumeric string",
|
"Parameter 'customSessionId' is wrong. Must be an alphanumeric string [a-zA-Z0-9_-]",
|
||||||
"/api/sessions", HttpStatus.BAD_REQUEST);
|
"/api/sessions", HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
builder = builder.customSessionId(customSessionId);
|
builder = builder.customSessionId(customSessionId);
|
||||||
|
@ -345,10 +345,12 @@ public class SessionRestController {
|
||||||
String sessionId;
|
String sessionId;
|
||||||
String roleString;
|
String roleString;
|
||||||
String metadata;
|
String metadata;
|
||||||
|
Boolean record;
|
||||||
try {
|
try {
|
||||||
sessionId = (String) params.get("session");
|
sessionId = (String) params.get("session");
|
||||||
roleString = (String) params.get("role");
|
roleString = (String) params.get("role");
|
||||||
metadata = (String) params.get("data");
|
metadata = (String) params.get("data");
|
||||||
|
record = (Boolean) params.get("record");
|
||||||
} catch (ClassCastException e) {
|
} catch (ClassCastException e) {
|
||||||
return this.generateErrorResponse("Type error in some parameter", "/api/tokens", HttpStatus.BAD_REQUEST);
|
return this.generateErrorResponse("Type error in some parameter", "/api/tokens", HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
@ -398,17 +400,19 @@ public class SessionRestController {
|
||||||
}
|
}
|
||||||
|
|
||||||
metadata = (metadata != null) ? metadata : "";
|
metadata = (metadata != null) ? metadata : "";
|
||||||
|
record = (record != null) ? record : true;
|
||||||
|
|
||||||
// While closing a session tokens can't be generated
|
// While closing a session tokens can't be generated
|
||||||
if (session.closingLock.readLock().tryLock()) {
|
if (session.closingLock.readLock().tryLock()) {
|
||||||
try {
|
try {
|
||||||
String token = sessionManager.newToken(session, role, metadata, kurentoTokenOptions);
|
String token = sessionManager.newToken(session, role, metadata, record, kurentoTokenOptions);
|
||||||
|
|
||||||
JsonObject responseJson = new JsonObject();
|
JsonObject responseJson = new JsonObject();
|
||||||
responseJson.addProperty("id", token);
|
responseJson.addProperty("id", token);
|
||||||
responseJson.addProperty("session", sessionId);
|
responseJson.addProperty("session", sessionId);
|
||||||
responseJson.addProperty("role", role.toString());
|
responseJson.addProperty("role", role.toString());
|
||||||
responseJson.addProperty("data", metadata);
|
responseJson.addProperty("data", metadata);
|
||||||
|
responseJson.addProperty("record", record);
|
||||||
responseJson.addProperty("token", token);
|
responseJson.addProperty("token", token);
|
||||||
|
|
||||||
if (kurentoOptions != null) {
|
if (kurentoOptions != null) {
|
||||||
|
@ -500,28 +504,36 @@ public class SessionRestController {
|
||||||
HttpStatus.BAD_REQUEST);
|
HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (name != null && !name.isEmpty()) {
|
||||||
|
if (!sessionManager.formatChecker.isValidRecordingName(name)) {
|
||||||
|
return this.generateErrorResponse(
|
||||||
|
"Parameter 'name' is wrong. Must be an alphanumeric string [a-zA-Z0-9_-]", "/api/sessions",
|
||||||
|
HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
OutputMode finalOutputMode = OutputMode.COMPOSED;
|
OutputMode finalOutputMode = OutputMode.COMPOSED;
|
||||||
RecordingLayout recordingLayout = null;
|
RecordingLayout recordingLayout = null;
|
||||||
if (outputModeString != null && !outputModeString.isEmpty()) {
|
if (outputModeString != null && !outputModeString.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
finalOutputMode = OutputMode.valueOf(outputModeString);
|
finalOutputMode = OutputMode.valueOf(outputModeString);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return this.generateErrorResponse("Type error in some parameter", "/api/recordings/start",
|
return this.generateErrorResponse("Type error in parameter 'outputMode'", "/api/recordings/start",
|
||||||
HttpStatus.BAD_REQUEST);
|
HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (RecordingUtils.IS_COMPOSED(finalOutputMode)) {
|
if (RecordingUtils.IS_COMPOSED(finalOutputMode)) {
|
||||||
if (resolution != null && !sessionManager.formatChecker.isAcceptableRecordingResolution(resolution)) {
|
if (resolution != null && !sessionManager.formatChecker.isAcceptableRecordingResolution(resolution)) {
|
||||||
return this.generateErrorResponse(
|
return this.generateErrorResponse(
|
||||||
"Wrong \"resolution\" parameter. Acceptable values from 100 to 1999 for both width and height",
|
"Wrong 'resolution' parameter. Acceptable values from 100 to 1999 for both width and height",
|
||||||
"/api/recordings/start", HttpStatus.UNPROCESSABLE_ENTITY);
|
"/api/recordings/start", HttpStatus.UNPROCESSABLE_ENTITY);
|
||||||
}
|
}
|
||||||
if (recordingLayoutString != null && !recordingLayoutString.isEmpty()) {
|
if (recordingLayoutString != null && !recordingLayoutString.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
recordingLayout = RecordingLayout.valueOf(recordingLayoutString);
|
recordingLayout = RecordingLayout.valueOf(recordingLayoutString);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return this.generateErrorResponse("Type error in some parameter", "/api/recordings/start",
|
return this.generateErrorResponse("Type error in parameter 'recordingLayout'",
|
||||||
HttpStatus.BAD_REQUEST);
|
"/api/recordings/start", HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,15 @@ public class FormatChecker {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isValidCustomSessionId(String customSessionId) {
|
public boolean isValidCustomSessionId(String customSessionId) {
|
||||||
// Alphanumeric string
|
return isValidAlphanumeric(customSessionId);
|
||||||
return customSessionId.matches("[a-zA-Z0-9_-]+");
|
}
|
||||||
|
|
||||||
|
public boolean isValidRecordingName(String recodingName) {
|
||||||
|
return isValidAlphanumeric(recodingName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isValidAlphanumeric(String str) {
|
||||||
|
return str.matches("[a-zA-Z0-9_-]+");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,7 @@ public class SessionGarbageCollectorIntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void joinParticipant(String sessionId, String token) {
|
private void joinParticipant(String sessionId, String token) {
|
||||||
Token t = new Token(token, OpenViduRole.PUBLISHER, "SERVER_METADATA", null, null);
|
Token t = new Token(token, OpenViduRole.PUBLISHER, "SERVER_METADATA", null, true, null);
|
||||||
String uuid = UUID.randomUUID().toString();
|
String uuid = UUID.randomUUID().toString();
|
||||||
String participantPrivateId = "PARTICIPANT_PRIVATE_ID_" + uuid;
|
String participantPrivateId = "PARTICIPANT_PRIVATE_ID_" + uuid;
|
||||||
String finalUserId = "FINAL_USER_ID_" + uuid;
|
String finalUserId = "FINAL_USER_ID_" + uuid;
|
||||||
|
|
|
@ -934,9 +934,13 @@ public class OpenViduTestAppE2eTest {
|
||||||
user.getEventManager().waitUntilEventReaches("streamCreated", 2);
|
user.getEventManager().waitUntilEventReaches("streamCreated", 2);
|
||||||
user.getEventManager().waitUntilEventReaches("streamPlaying", 2);
|
user.getEventManager().waitUntilEventReaches("streamPlaying", 2);
|
||||||
|
|
||||||
|
// Give some time for the screen sharing warning to stop resizing the viewport
|
||||||
|
Thread.sleep(3000);
|
||||||
|
|
||||||
// Unpublish video
|
// Unpublish video
|
||||||
final CountDownLatch latch1 = new CountDownLatch(2);
|
final CountDownLatch latch1 = new CountDownLatch(2);
|
||||||
user.getEventManager().on("streamPropertyChanged", (event) -> {
|
user.getEventManager().on("streamPropertyChanged", (event) -> {
|
||||||
|
System.out.println(event.toString());
|
||||||
threadAssertions.add("videoActive".equals(event.get("changedProperty").getAsString()));
|
threadAssertions.add("videoActive".equals(event.get("changedProperty").getAsString()));
|
||||||
threadAssertions.add(!event.get("newValue").getAsBoolean());
|
threadAssertions.add(!event.get("newValue").getAsBoolean());
|
||||||
latch1.countDown();
|
latch1.countDown();
|
||||||
|
@ -960,6 +964,7 @@ public class OpenViduTestAppE2eTest {
|
||||||
// Unpublish audio
|
// Unpublish audio
|
||||||
final CountDownLatch latch2 = new CountDownLatch(2);
|
final CountDownLatch latch2 = new CountDownLatch(2);
|
||||||
user.getEventManager().on("streamPropertyChanged", (event) -> {
|
user.getEventManager().on("streamPropertyChanged", (event) -> {
|
||||||
|
System.out.println(event.toString());
|
||||||
threadAssertions.add("audioActive".equals(event.get("changedProperty").getAsString()));
|
threadAssertions.add("audioActive".equals(event.get("changedProperty").getAsString()));
|
||||||
threadAssertions.add(!event.get("newValue").getAsBoolean());
|
threadAssertions.add(!event.get("newValue").getAsBoolean());
|
||||||
latch2.countDown();
|
latch2.countDown();
|
||||||
|
@ -992,9 +997,11 @@ public class OpenViduTestAppE2eTest {
|
||||||
+ "}";
|
+ "}";
|
||||||
System.out.println("Publisher dimensions: " + event.get("newValue").getAsJsonObject().toString());
|
System.out.println("Publisher dimensions: " + event.get("newValue").getAsJsonObject().toString());
|
||||||
System.out.println("Real dimensions of viewport: " + expectedDimensions);
|
System.out.println("Real dimensions of viewport: " + expectedDimensions);
|
||||||
threadAssertions.add("videoDimensions".equals(event.get("changedProperty").getAsString()));
|
if ("videoDimensions".equals(event.get("changedProperty").getAsString())) {
|
||||||
threadAssertions.add(expectedDimensions.equals(event.get("newValue").getAsJsonObject().toString()));
|
if (expectedDimensions.equals(event.get("newValue").getAsJsonObject().toString())) {
|
||||||
latch3.countDown();
|
latch3.countDown();
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
user.getDriver().manage().window().setSize(new Dimension(newWidth, newHeight));
|
user.getDriver().manage().window().setSize(new Dimension(newWidth, newHeight));
|
||||||
|
@ -1009,7 +1016,7 @@ public class OpenViduTestAppE2eTest {
|
||||||
|
|
||||||
user.getEventManager().waitUntilEventReaches("streamPropertyChanged", 6);
|
user.getEventManager().waitUntilEventReaches("streamPropertyChanged", 6);
|
||||||
|
|
||||||
if (!latch3.await(5000, TimeUnit.MILLISECONDS)) {
|
if (!latch3.await(6000, TimeUnit.MILLISECONDS)) {
|
||||||
gracefullyLeaveParticipants(2);
|
gracefullyLeaveParticipants(2);
|
||||||
fail();
|
fail();
|
||||||
return;
|
return;
|
||||||
|
@ -1018,11 +1025,6 @@ public class OpenViduTestAppE2eTest {
|
||||||
System.out.println(getBase64Screenshot(user));
|
System.out.println(getBase64Screenshot(user));
|
||||||
|
|
||||||
user.getEventManager().off("streamPropertyChanged");
|
user.getEventManager().off("streamPropertyChanged");
|
||||||
log.info("Thread assertions: {}", threadAssertions.toString());
|
|
||||||
for (Iterator<Boolean> iter = threadAssertions.iterator(); iter.hasNext();) {
|
|
||||||
Assert.assertTrue("Some Event property was wrong", iter.next());
|
|
||||||
iter.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
gracefullyLeaveParticipants(2);
|
gracefullyLeaveParticipants(2);
|
||||||
}
|
}
|
||||||
|
@ -1347,8 +1349,15 @@ public class OpenViduTestAppE2eTest {
|
||||||
final String sessionName = "TestSession";
|
final String sessionName = "TestSession";
|
||||||
final String recordingName = "CUSTOM_NAME";
|
final String recordingName = "CUSTOM_NAME";
|
||||||
|
|
||||||
user.getDriver().findElement(By.id("auto-join-checkbox")).click();
|
// Connect 2 users. One of them not recorded
|
||||||
user.getDriver().findElement(By.id("one2one-btn")).click();
|
user.getDriver().findElement(By.id("one2one-btn")).click();
|
||||||
|
user.getDriver().findElement(By.id("session-settings-btn-0")).click();
|
||||||
|
Thread.sleep(1000);
|
||||||
|
user.getDriver().findElement(By.id("record-checkbox")).click();
|
||||||
|
user.getDriver().findElement(By.id("save-btn")).click();
|
||||||
|
Thread.sleep(1000);
|
||||||
|
|
||||||
|
user.getDriver().findElements(By.className("join-btn")).forEach(el -> el.sendKeys(Keys.ENTER));
|
||||||
|
|
||||||
user.getEventManager().waitUntilEventReaches("connectionCreated", 4);
|
user.getEventManager().waitUntilEventReaches("connectionCreated", 4);
|
||||||
user.getEventManager().waitUntilEventReaches("accessAllowed", 2);
|
user.getEventManager().waitUntilEventReaches("accessAllowed", 2);
|
||||||
|
@ -1416,7 +1425,7 @@ public class OpenViduTestAppE2eTest {
|
||||||
String recPath = recordingsPath + sessionName + "/";
|
String recPath = recordingsPath + sessionName + "/";
|
||||||
|
|
||||||
Recording recording = new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET).getRecording(sessionName);
|
Recording recording = new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET).getRecording(sessionName);
|
||||||
this.checkIndividualRecording(recPath, recording, 2, "opus", "vp8", true);
|
this.checkIndividualRecording(recPath, recording, 1, "opus", "vp8", true);
|
||||||
|
|
||||||
// Try to get the stopped recording
|
// Try to get the stopped recording
|
||||||
user.getDriver().findElement(By.id("get-recording-btn")).click();
|
user.getDriver().findElement(By.id("get-recording-btn")).click();
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
"core-js": "3.4.7",
|
"core-js": "3.4.7",
|
||||||
"hammerjs": "2.0.8",
|
"hammerjs": "2.0.8",
|
||||||
"openvidu-browser": "2.15.0",
|
"openvidu-browser": "2.15.0",
|
||||||
"openvidu-node-client": "2.11.0",
|
"openvidu-node-client": "2.15.0",
|
||||||
"rxjs": "6.5.3",
|
"rxjs": "6.5.3",
|
||||||
"zone.js": "0.10.2"
|
"zone.js": "0.10.2"
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue