mirror of https://github.com/OpenVidu/openvidu.git
Trigger recordingStarted event for new connected participants
parent
df7bd5f202
commit
8d3fe2b681
|
@ -1436,6 +1436,10 @@ export class Session extends EventDispatcher {
|
|||
this.ee.emitEvent('streamCreated', [new StreamEvent(false, this, 'streamCreated', stream, '')]);
|
||||
});
|
||||
|
||||
if (!!response.recordingId && !!response.recordingName) {
|
||||
this.ee.emitEvent('recordingStarted', [new RecordingEvent(this, 'recordingStarted', response.recordingId, response.recordingName)]);
|
||||
}
|
||||
|
||||
return resolve();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -36,5 +36,7 @@ export interface LocalConnectionOptions {
|
|||
mediaServer: string;
|
||||
videoSimulcast: boolean;
|
||||
life: number;
|
||||
customIceServers?: IceServerProperties[]
|
||||
customIceServers?: IceServerProperties[];
|
||||
recordingId?: string; // Defined if the session is being recorded and the client must be notified
|
||||
recordingName?: string; // Defined if the session is being recorded and the client must be notified
|
||||
}
|
||||
|
|
|
@ -166,6 +166,8 @@ public class ProtocolElements {
|
|||
public static final String PARTICIPANTJOINED_CUSTOM_ICE_SERVERS = "customIceServers";
|
||||
public static final String PARTICIPANTJOINED_TURNUSERNAME_PARAM = "turnUsername";
|
||||
public static final String PARTICIPANTJOINED_TURNCREDENTIAL_PARAM = "turnCredential";
|
||||
public static final String PARTICIPANTJOINED_RECORDINGID_PARAM = "recordingId";
|
||||
public static final String PARTICIPANTJOINED_RECORDINGNAME_PARAM = "recordingName";
|
||||
|
||||
public static final String PARTICIPANTLEFT_METHOD = "participantLeft";
|
||||
public static final String PARTICIPANTLEFT_NAME_PARAM = "connectionId";
|
||||
|
|
|
@ -32,10 +32,11 @@ import java.nio.file.Paths;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
|
@ -413,23 +414,26 @@ public class OpenviduConfig {
|
|||
return this.mediaNodesPublicIps;
|
||||
}
|
||||
|
||||
public OpenViduRole[] getRolesFromRecordingNotification() {
|
||||
OpenViduRole[] roles;
|
||||
public Set<OpenViduRole> getRolesFromRecordingNotification() {
|
||||
Set<OpenViduRole> roles = new HashSet<>();
|
||||
switch (this.openviduRecordingNotification) {
|
||||
case none:
|
||||
roles = new OpenViduRole[0];
|
||||
break;
|
||||
case moderator:
|
||||
roles = new OpenViduRole[] { OpenViduRole.MODERATOR };
|
||||
roles.add(OpenViduRole.MODERATOR);
|
||||
break;
|
||||
case publisher_moderator:
|
||||
roles = new OpenViduRole[] { OpenViduRole.PUBLISHER, OpenViduRole.MODERATOR };
|
||||
roles.add(OpenViduRole.PUBLISHER);
|
||||
roles.add(OpenViduRole.MODERATOR);
|
||||
break;
|
||||
case all:
|
||||
roles = new OpenViduRole[] { OpenViduRole.SUBSCRIBER, OpenViduRole.PUBLISHER, OpenViduRole.MODERATOR };
|
||||
roles.add(OpenViduRole.SUBSCRIBER);
|
||||
roles.add(OpenViduRole.PUBLISHER);
|
||||
roles.add(OpenViduRole.MODERATOR);
|
||||
break;
|
||||
default:
|
||||
roles = new OpenViduRole[] { OpenViduRole.PUBLISHER, OpenViduRole.MODERATOR };
|
||||
roles.add(OpenViduRole.PUBLISHER);
|
||||
roles.add(OpenViduRole.MODERATOR);
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
|
@ -547,7 +551,8 @@ public class OpenviduConfig {
|
|||
|
||||
protected List<String> getNonUserProperties() {
|
||||
return Arrays.asList("server.port", "SERVER_PORT", "DOTENV_PATH", "COTURN_IP", "COTURN_PORT",
|
||||
"COTURN_INTERNAL_RELAY", "COTURN_SHARED_SECRET_KEY", "OPENVIDU_RECORDING_IMAGE", "OPENVIDU_RECORDING_ENABLE_GPU");
|
||||
"COTURN_INTERNAL_RELAY", "COTURN_SHARED_SECRET_KEY", "OPENVIDU_RECORDING_IMAGE",
|
||||
"OPENVIDU_RECORDING_ENABLE_GPU");
|
||||
}
|
||||
|
||||
protected List<String> getNonPrintablePropertiesIfEmpty() {
|
||||
|
|
|
@ -74,8 +74,8 @@ public class SessionEventsHandler {
|
|||
CDR.recordSessionDestroyed(session, reason);
|
||||
}
|
||||
|
||||
public void onParticipantJoined(Participant participant, String sessionId, String coturnIp, Set<Participant> existingParticipants,
|
||||
Integer transactionId, OpenViduException error) {
|
||||
public void onParticipantJoined(Participant participant, Recording recording, String coturnIp,
|
||||
Set<Participant> existingParticipants, Integer transactionId, OpenViduException error) {
|
||||
if (error != null) {
|
||||
rpcNotificationService.sendErrorResponse(participant.getParticipantPrivateId(), transactionId, null, error);
|
||||
return;
|
||||
|
@ -179,7 +179,9 @@ public class SessionEventsHandler {
|
|||
}
|
||||
|
||||
if (participant.getToken() != null) {
|
||||
|
||||
result.addProperty(ProtocolElements.PARTICIPANTJOINED_RECORD_PARAM, participant.getToken().record());
|
||||
|
||||
if (participant.getToken().getRole() != null) {
|
||||
result.addProperty(ProtocolElements.PARTICIPANTJOINED_ROLE_PARAM,
|
||||
participant.getToken().getRole().name());
|
||||
|
@ -198,6 +200,11 @@ public class SessionEventsHandler {
|
|||
result.addProperty(ProtocolElements.PARTICIPANTJOINED_TURNCREDENTIAL_PARAM,
|
||||
participant.getToken().getTurnCredentials().getCredential());
|
||||
}
|
||||
if (recording != null) {
|
||||
result.addProperty(ProtocolElements.PARTICIPANTJOINED_RECORDINGID_PARAM, recording.getId());
|
||||
result.addProperty(ProtocolElements.PARTICIPANTJOINED_RECORDINGNAME_PARAM, recording.getName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
rpcNotificationService.sendResponse(participant.getParticipantPrivateId(), transactionId, result);
|
||||
|
@ -680,18 +687,12 @@ public class SessionEventsHandler {
|
|||
recordingsToSendClientEvents.put(recording.getSessionId(), recording);
|
||||
}
|
||||
|
||||
protected Set<Participant> filterParticipantsByRole(OpenViduRole[] roles, Set<Participant> participants) {
|
||||
protected Set<Participant> filterParticipantsByRole(Set<OpenViduRole> roles, Set<Participant> participants) {
|
||||
return participants.stream().filter(part -> {
|
||||
if (ProtocolElements.RECORDER_PARTICIPANT_PUBLICID.equals(part.getParticipantPublicId())) {
|
||||
return false;
|
||||
}
|
||||
boolean isRole = false;
|
||||
for (OpenViduRole role : roles) {
|
||||
isRole = role.equals(part.getToken().getRole());
|
||||
if (isRole)
|
||||
break;
|
||||
}
|
||||
return isRole;
|
||||
return roles.contains(part.getToken().getRole());
|
||||
}).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ public class KurentoSessionManager extends SessionManager {
|
|||
String error = "Timeout of " + KmsManager.MAX_SECONDS_LOCK_WAIT
|
||||
+ " seconds waiting to acquire lock";
|
||||
log.error(error);
|
||||
sessionEventsHandler.onParticipantJoined(participant, sessionId, null, null, transactionId,
|
||||
sessionEventsHandler.onParticipantJoined(participant, null, null, null, transactionId,
|
||||
new OpenViduException(Code.ROOM_CANNOT_BE_CREATED_ERROR_CODE, error));
|
||||
return;
|
||||
}
|
||||
|
@ -169,7 +169,11 @@ public class KurentoSessionManager extends SessionManager {
|
|||
existingParticipants = getParticipants(sessionId);
|
||||
kSession.join(participant);
|
||||
String coturnIp = openviduConfig.getCoturnIp(kSession.getKms().getUri());
|
||||
sessionEventsHandler.onParticipantJoined(participant, sessionId, coturnIp, existingParticipants,
|
||||
|
||||
io.openvidu.server.recording.Recording recording = getActiveRecordingIfAllowedByParticipantRole(
|
||||
participant);
|
||||
|
||||
sessionEventsHandler.onParticipantJoined(participant, recording, coturnIp, existingParticipants,
|
||||
transactionId, null);
|
||||
} finally {
|
||||
kSession.joinLeaveLock.unlock();
|
||||
|
@ -178,21 +182,21 @@ public class KurentoSessionManager extends SessionManager {
|
|||
log.error(
|
||||
"Timeout waiting for join-leave Session lock to be available for participant {} of session {} in joinRoom",
|
||||
participant.getParticipantPublicId(), sessionId);
|
||||
sessionEventsHandler.onParticipantJoined(participant, sessionId, null, null, transactionId,
|
||||
sessionEventsHandler.onParticipantJoined(participant, null, null, null, transactionId,
|
||||
new OpenViduException(Code.GENERIC_ERROR_CODE, "Timeout waiting for Session lock"));
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
log.error(
|
||||
"InterruptedException waiting for join-leave Session lock to be available for participant {} of session {} in joinRoom",
|
||||
participant.getParticipantPublicId(), sessionId);
|
||||
sessionEventsHandler.onParticipantJoined(participant, sessionId, null,null, transactionId,
|
||||
sessionEventsHandler.onParticipantJoined(participant, null, null, null, transactionId,
|
||||
new OpenViduException(Code.GENERIC_ERROR_CODE,
|
||||
"InterruptedException waiting for Session lock"));
|
||||
}
|
||||
} catch (OpenViduException e) {
|
||||
log.error("PARTICIPANT {}: Error joining/creating session {}", participant.getParticipantPublicId(),
|
||||
sessionId, e);
|
||||
sessionEventsHandler.onParticipantJoined(participant, sessionId, null,null, transactionId, e);
|
||||
sessionEventsHandler.onParticipantJoined(participant, null, null, null, transactionId, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1406,6 +1410,16 @@ public class KurentoSessionManager extends SessionManager {
|
|||
return lessLoadedKms;
|
||||
}
|
||||
|
||||
private io.openvidu.server.recording.Recording getActiveRecordingIfAllowedByParticipantRole(
|
||||
Participant participant) {
|
||||
io.openvidu.server.recording.Recording recording = null;
|
||||
if (participant.getToken() != null && this.recordingManager.sessionIsBeingRecorded(participant.getSessionId())
|
||||
&& this.openviduConfig.getRolesFromRecordingNotification().contains(participant.getToken().getRole())) {
|
||||
recording = this.recordingManager.getActiveRecordingForSession(participant.getSessionId());
|
||||
}
|
||||
return recording;
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
@Override
|
||||
public void close() {
|
||||
|
|
|
@ -492,6 +492,14 @@ public class RecordingManager {
|
|||
|| this.sessionsRecordingsStarting.get(sessionId) != null);
|
||||
}
|
||||
|
||||
public Recording getActiveRecordingForSession(String sessionId) {
|
||||
Recording recording = this.sessionsRecordings.get(sessionId);
|
||||
if (recording == null) {
|
||||
recording = this.sessionsRecordingsStarting.get(sessionId);
|
||||
}
|
||||
return recording;
|
||||
}
|
||||
|
||||
public boolean sessionIsBeingRecordedIndividual(String sessionId) {
|
||||
if (!sessionIsBeingRecorded(sessionId)) {
|
||||
return false;
|
||||
|
|
|
@ -167,8 +167,8 @@ public class WebhookIntegrationTest {
|
|||
|
||||
// Client should have already received "connectionCreated" RPC response
|
||||
// nonetheless
|
||||
verify(sessionEventsHandler, times(1)).onParticipantJoined(refEq(participant), anyString(), anyString(), anySet(),
|
||||
anyInt(), refEq(null));
|
||||
verify(sessionEventsHandler, times(1)).onParticipantJoined(refEq(participant), refEq(null), anyString(),
|
||||
anySet(), anyInt(), refEq(null));
|
||||
|
||||
// Now webhook response for event "participantJoined" should be received
|
||||
CustomWebhook.waitForEvent("participantJoined", 1000, TimeUnit.MILLISECONDS);
|
||||
|
|
|
@ -255,7 +255,7 @@ public class OpenViduEventManager {
|
|||
return success;
|
||||
}
|
||||
|
||||
private AtomicInteger getNumEvents(String eventName) {
|
||||
public AtomicInteger getNumEvents(String eventName) {
|
||||
return this.eventNumbers.computeIfAbsent(eventName, k -> new AtomicInteger(0));
|
||||
}
|
||||
|
||||
|
|
|
@ -1185,7 +1185,43 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
|
|||
|
||||
user.getEventManager().waitUntilEventReaches("recordingStarted", 1);
|
||||
|
||||
Thread.sleep(5000);
|
||||
Thread.sleep(3000);
|
||||
|
||||
user.getDriver().findElement(By.id("close-dialog-btn")).click();
|
||||
Thread.sleep(500);
|
||||
|
||||
// A new user with PUBLISHER role should trigger recordingStarted event
|
||||
user.getDriver().findElement(By.id("add-user-btn")).click();
|
||||
user.getDriver().findElement(By.id("session-name-input-1")).clear();
|
||||
user.getDriver().findElement(By.id("session-name-input-1")).sendKeys(sessionName);
|
||||
user.getDriver().findElement(By.cssSelector("#openvidu-instance-1 .publish-checkbox")).click();
|
||||
user.getDriver().findElement(By.cssSelector("#openvidu-instance-1 .subscribe-checkbox")).click();
|
||||
user.getDriver().findElement(By.cssSelector("#openvidu-instance-1 .join-btn")).click();
|
||||
user.getEventManager().waitUntilEventReaches("connectionCreated", 4);
|
||||
user.getEventManager().waitUntilEventReaches("streamCreated", 2);
|
||||
user.getEventManager().waitUntilEventReaches("recordingStarted", 2);
|
||||
|
||||
// A new user with SUBSCRIBER role should not trigger recordingStarted event
|
||||
user.getDriver().findElement(By.id("add-user-btn")).click();
|
||||
user.getDriver().findElement(By.id("session-name-input-2")).clear();
|
||||
user.getDriver().findElement(By.id("session-name-input-2")).sendKeys(sessionName);
|
||||
user.getDriver().findElement(By.cssSelector("#openvidu-instance-2 .publish-checkbox")).click();
|
||||
user.getDriver().findElement(By.cssSelector("#openvidu-instance-2 .subscribe-checkbox")).click();
|
||||
user.getDriver().findElement(By.id("session-settings-btn-2")).click();
|
||||
Thread.sleep(500);
|
||||
user.getDriver().findElement(By.id("radio-btn-sub")).click();
|
||||
user.getDriver().findElement(By.id("save-btn")).click();
|
||||
Thread.sleep(500);
|
||||
user.getDriver().findElement(By.cssSelector("#openvidu-instance-2 .join-btn")).click();
|
||||
user.getEventManager().waitUntilEventReaches("connectionCreated", 9);
|
||||
user.getEventManager().waitUntilEventReaches("streamCreated", 3);
|
||||
|
||||
// No third recordingStarted event should be triggered for the SUBSCRIBER user
|
||||
Thread.sleep(3000);
|
||||
Assert.assertEquals(user.getEventManager().getNumEvents("recordingStarted").intValue(), 2);
|
||||
|
||||
user.getDriver().findElement(By.id("session-api-btn-0")).click();
|
||||
Thread.sleep(500);
|
||||
|
||||
user.getDriver().findElement(By.id("recording-id-field")).clear();
|
||||
user.getDriver().findElement(By.id("recording-id-field")).sendKeys(sessionName);
|
||||
|
@ -1256,7 +1292,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
|
|||
user.getDriver().findElement(By.id("close-dialog-btn")).click();
|
||||
Thread.sleep(500);
|
||||
|
||||
gracefullyLeaveParticipants(user, 1);
|
||||
gracefullyLeaveParticipants(user, 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in New Issue