diff --git a/openvidu-recording-java/.gitignore b/openvidu-recording-java/.gitignore
index 950fc085..6c57dbc8 100644
--- a/openvidu-recording-java/.gitignore
+++ b/openvidu-recording-java/.gitignore
@@ -22,3 +22,4 @@
hs_err_pid*
target/
+.vscode/*
diff --git a/openvidu-recording-java/pom.xml b/openvidu-recording-java/pom.xml
index 145a1974..cf2e68a3 100644
--- a/openvidu-recording-java/pom.xml
+++ b/openvidu-recording-java/pom.xml
@@ -1,4 +1,5 @@
-
4.0.0
@@ -13,7 +14,7 @@
org.springframework.boot
spring-boot-starter-parent
- 1.4.1.RELEASE
+ 2.1.2.RELEASE
@@ -21,6 +22,11 @@
1.8
io.openvidu.recording.java.App
openvidu
+
+
+ 5.0.3
+ 1.3.2
+ 3.1.0
@@ -36,7 +42,7 @@
org.springframework
springloaded
- 1.2.6.RELEASE
+ 2.1.2.RELEASE
@@ -48,35 +54,11 @@
${start-class}
-
-
- com.spotify
- docker-maven-plugin
- 0.2.3
-
- ${docker.image.prefix}/${project.artifactId}
- src/main/docker
-
-
- /
- ${project.build.directory}
- ${project.build.finalName}.war
-
-
-
-
-
-
- junit
- junit
- test
-
-
org.springframework.boot
spring-boot-starter-web
@@ -86,17 +68,59 @@
org.springframework.boot
spring-boot-devtools
-
-
- com.googlecode.json-simple
- json-simple
-
-
io.openvidu
openvidu-java-client
2.8.1
+
+ org.junit.jupiter
+ junit-jupiter-api
+ test
+
+
+ io.github.bonigarcia
+ selenium-jupiter
+ ${selenium-jupiter.version}
+ test
+
+
+ io.github.bonigarcia
+ webdrivermanager
+ 2.2.0
+ test
+
+
+ org.junit.platform
+ junit-platform-runner
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ test
+
+
+ com.google.guava
+ guava
+ 23.0
+ test
+
+
+
+
+ ws.schild
+ jave-all-deps
+ 2.4.5
+
+
+ ws.schild
+ jave-core
+ 2.4.5
+
+
diff --git a/openvidu-recording-java/src/main/java/io/openvidu/recording/java/MyRestController.java b/openvidu-recording-java/src/main/java/io/openvidu/recording/java/MyRestController.java
index 7ce2f00b..53fa5f25 100644
--- a/openvidu-recording-java/src/main/java/io/openvidu/recording/java/MyRestController.java
+++ b/openvidu-recording-java/src/main/java/io/openvidu/recording/java/MyRestController.java
@@ -1,6 +1,5 @@
package io.openvidu.recording.java;
-import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -92,37 +91,43 @@ public class MyRestController {
// Return the response to the client
return new ResponseEntity<>(responseJson, HttpStatus.OK);
- } catch (Exception e) {
- // If error generate an error message and return it to client
- return getErrorResponse(e);
+ } catch (OpenViduJavaClientException e1) {
+ // If internal error generate an error message and return it to client
+ return getErrorResponse(e1);
+ } catch (OpenViduHttpException e2) {
+ if (404 == e2.getStatus()) {
+ // Invalid sessionId (user left unexpectedly). Session object is not valid
+ // anymore. Clean collections and continue as new session
+ this.mapSessions.remove(sessionName);
+ this.mapSessionNamesTokens.remove(sessionName);
+ }
}
+ }
- } else {
- // New session
- System.out.println("New session " + sessionName);
- try {
+ // New session
+ System.out.println("New session " + sessionName);
+ try {
- // Create a new OpenVidu Session
- Session session = this.openVidu.createSession();// new
- // SessionProperties.Builder().customSessionId("CUSTOMSESSIONID").defaultRecordingLayout(RecordingLayout.CUSTOM).defaultCustomLayout("CUSTOM/LAYOUT").recordingMode(RecordingMode.ALWAYS).build());
- // Generate a new token with the recently created tokenOptions
- String token = session.generateToken(tokenOptions);
+ // Create a new OpenVidu Session
+ Session session = this.openVidu.createSession();// new
+ // SessionProperties.Builder().customSessionId("CUSTOMSESSIONID").defaultRecordingLayout(RecordingLayout.CUSTOM).defaultCustomLayout("CUSTOM/LAYOUT").recordingMode(RecordingMode.ALWAYS).build());
+ // Generate a new token with the recently created tokenOptions
+ String token = session.generateToken(tokenOptions);
- // Store the session and the token in our collections
- this.mapSessions.put(sessionName, session);
- this.mapSessionNamesTokens.put(sessionName, new ConcurrentHashMap<>());
- this.mapSessionNamesTokens.get(sessionName).put(token, role);
+ // Store the session and the token in our collections
+ this.mapSessions.put(sessionName, session);
+ this.mapSessionNamesTokens.put(sessionName, new ConcurrentHashMap<>());
+ this.mapSessionNamesTokens.get(sessionName).put(token, role);
- // Prepare the response with the sessionId and the token
- responseJson.put(0, token);
+ // Prepare the response with the sessionId and the token
+ responseJson.put(0, token);
- // Return the response to the client
- return new ResponseEntity<>(responseJson, HttpStatus.OK);
+ // Return the response to the client
+ return new ResponseEntity<>(responseJson, HttpStatus.OK);
- } catch (Exception e) {
- // If error generate an error message and return it to client
- return getErrorResponse(e);
- }
+ } catch (Exception e) {
+ // If error generate an error message and return it to client
+ return getErrorResponse(e);
}
}
diff --git a/openvidu-recording-java/src/main/resources/static/app.js b/openvidu-recording-java/src/main/resources/static/app.js
index 0de93909..8fd38e5b 100644
--- a/openvidu-recording-java/src/main/resources/static/app.js
+++ b/openvidu-recording-java/src/main/resources/static/app.js
@@ -21,27 +21,48 @@ function joinSession() {
// --- 3) Specify the actions when events take place in the session ---
+ session.on('connectionCreated', event => {
+ pushEvent(event);
+ });
+
+ session.on('connectionDestroyed', event => {
+ pushEvent(event);
+ });
+
// On every new Stream received...
- session.on('streamCreated', (event) => {
+ session.on('streamCreated', event => {
+ pushEvent(event);
// Subscribe to the Stream to receive it
// HTML video will be appended to element with 'video-container' id
var subscriber = session.subscribe(event.stream, 'video-container');
// When the HTML video has been appended to DOM...
- subscriber.on('videoElementCreated', (event) => {
+ subscriber.on('videoElementCreated', event => {
+ pushEvent(event);
// Add a new HTML element for the user's name and nickname over its video
updateNumVideos(1);
});
// When the HTML video has been appended to DOM...
- subscriber.on('videoElementDestroyed', (event) => {
+ subscriber.on('videoElementDestroyed', event => {
+ pushEvent(event);
// Add a new HTML element for the user's name and nickname over its video
updateNumVideos(-1);
});
+
+ // When the subscriber stream has started playing media...
+ subscriber.on('streamPlaying', event => {
+ pushEvent(event);
+ });
});
- session.on('sessionDisconnected', (event) => {
+ session.on('streamDestroyed', event => {
+ pushEvent(event);
+ });
+
+ session.on('sessionDisconnected', event => {
+ pushEvent(event);
if (event.reason !== 'disconnect') {
removeUser();
}
@@ -53,6 +74,14 @@ function joinSession() {
}
});
+ session.on('recordingStarted', event => {
+ pushEvent(event);
+ });
+
+ session.on('recordingStopped', event => {
+ pushEvent(event);
+ });
+
// --- 4) Connect to the session passing the retrieved token and some more data from
// the client (in this case a JSON with the nickname chosen by the user) ---
@@ -70,28 +99,62 @@ function joinSession() {
var publisher = OV.initPublisher('video-container', {
audioSource: undefined, // The source of audio. If undefined default microphone
videoSource: undefined, // The source of video. If undefined default webcam
- publishAudio: true, // Whether you want to start publishing with your audio unmuted or not
- publishVideo: true, // Whether you want to start publishing with your video enabled or not
- resolution: '640x480', // The resolution of your video
- frameRate: 30, // The frame rate of your video
- insertMode: 'APPEND', // How the video is inserted in the target element 'video-container'
- mirror: false // Whether to mirror your local video or not
+ publishAudio: true, // Whether you want to start publishing with your audio unmuted or not
+ publishVideo: true, // Whether you want to start publishing with your video enabled or not
+ resolution: '640x480', // The resolution of your video
+ frameRate: 30, // The frame rate of your video
+ insertMode: 'APPEND', // How the video is inserted in the target element 'video-container'
+ mirror: false // Whether to mirror your local video or not
});
// --- 7) Specify the actions when events take place in our publisher ---
+ // When the publisher stream has started playing media...
+ publisher.on('accessAllowed', event => {
+ pushEvent({
+ type: 'accessAllowed'
+ });
+ });
+
+ publisher.on('accessDenied', event => {
+ pushEvent(event);
+ });
+
+ publisher.on('accessDialogOpened', event => {
+ pushEvent({
+ type: 'accessDialogOpened'
+ });
+ });
+
+ publisher.on('accessDialogClosed', event => {
+ pushEvent({
+ type: 'accessDialogClosed'
+ });
+ });
+
+ // When the publisher stream has started playing media...
+ publisher.on('streamCreated', event => {
+ pushEvent(event);
+ });
+
// When our HTML video has been added to DOM...
- publisher.on('videoElementCreated', (event) => {
+ publisher.on('videoElementCreated', event => {
+ pushEvent(event);
updateNumVideos(1);
$(event.element).prop('muted', true); // Mute local video
});
// When the HTML video has been appended to DOM...
- publisher.on('videoElementDestroyed', (event) => {
+ publisher.on('videoElementDestroyed', event => {
+ pushEvent(event);
// Add a new HTML element for the user's name and nickname over its video
updateNumVideos(-1);
});
+ // When the publisher stream has started playing media...
+ publisher.on('streamPlaying', event => {
+ pushEvent(event);
+ });
// --- 8) Publish your stream ---
@@ -128,8 +191,8 @@ function getToken(callback) {
sessionName: sessionName
},
'Request of TOKEN gone WRONG:',
- (response) => {
- token = response[0]; // Get token from response
+ res => {
+ token = res[0]; // Get token from response
console.warn('Request of TOKEN gone WELL (TOKEN:' + token + ')');
callback(token); // Continue the join operation
}
@@ -144,7 +207,7 @@ function removeUser() {
token: token
},
'User couldn\'t be removed from session',
- (response) => {
+ res => {
console.warn("You have been removed from session " + sessionName);
}
);
@@ -157,7 +220,7 @@ function closeSession() {
sessionName: sessionName
},
'Session couldn\'t be closed',
- (response) => {
+ res => {
console.warn("Session " + sessionName + " has been closed");
}
);
@@ -170,9 +233,9 @@ function fetchInfo() {
sessionName: sessionName
},
'Session couldn\'t be fetched',
- (response) => {
+ res => {
console.warn("Session info has been fetched");
- $('#text-area').text(JSON.stringify(response, null, "\t"));
+ $('#textarea-http').text(JSON.stringify(res, null, "\t"));
}
);
}
@@ -182,9 +245,9 @@ function fetchAll() {
'GET',
'api/fetch-all', {},
'All session info couldn\'t be fetched',
- (response) => {
+ res => {
console.warn("All session info has been fetched");
- $('#text-area').text(JSON.stringify(response, null, "\t"));
+ $('#textarea-http').text(JSON.stringify(res, null, "\t"));
}
);
}
@@ -197,7 +260,7 @@ function forceDisconnect() {
connectionId: document.getElementById('forceValue').value
},
'Connection couldn\'t be closed',
- (response) => {
+ res => {
console.warn("Connection has been closed");
}
);
@@ -211,14 +274,14 @@ function forceUnpublish() {
streamId: document.getElementById('forceValue').value
},
'Stream couldn\'t be closed',
- (response) => {
+ res => {
console.warn("Stream has been closed");
}
);
}
function httpRequest(method, url, body, errorMsg, callback) {
- $('#text-area').text('');
+ $('#textarea-http').text('');
var http = new XMLHttpRequest();
http.open(method, url, true);
http.setRequestHeader('Content-type', 'application/json');
@@ -236,16 +299,16 @@ function httpRequest(method, url, body, errorMsg, callback) {
} else {
console.warn(errorMsg + ' (' + http.status + ')');
console.warn(http.responseText);
- $('#text-area').text(errorMsg + ": HTTP " + http.status + " (" + http.responseText + ")");
+ $('#textarea-http').text(errorMsg + ": HTTP " + http.status + " (" + http.responseText + ")");
}
}
}
}
function startRecording() {
- var outputMode = document.querySelector('input[name="outputMode"]:checked').value;
- var hasAudio = !!document.querySelector("#has-audio-checkbox:checked");
- var hasVideo = !!document.querySelector("#has-video-checkbox:checked");
+ var outputMode = $('input[name=outputMode]:checked').val();
+ var hasAudio = $('#has-audio-checkbox').prop('checked');
+ var hasVideo = $('#has-video-checkbox').prop('checked');
httpRequest(
'POST',
'api/recording/start', {
@@ -255,11 +318,11 @@ function startRecording() {
hasVideo: hasVideo
},
'Start recording WRONG',
- (response) => {
- console.log(response);
- document.getElementById('forceRecordingId').value = response.id;
+ res => {
+ console.log(res);
+ document.getElementById('forceRecordingId').value = res.id;
checkBtnsRecordings();
- $('#text-area').text(JSON.stringify(response, null, "\t"));
+ $('#textarea-http').text(JSON.stringify(res, null, "\t"));
}
);
}
@@ -272,9 +335,9 @@ function stopRecording() {
recording: forceRecordingId
},
'Stop recording WRONG',
- (response) => {
- console.log(response);
- $('#text-area').text(JSON.stringify(response, null, "\t"));
+ res => {
+ console.log(res);
+ $('#textarea-http').text(JSON.stringify(res, null, "\t"));
}
);
}
@@ -287,9 +350,9 @@ function deleteRecording() {
recording: forceRecordingId
},
'Delete recording WRONG',
- () => {
+ res => {
console.log("DELETE ok");
- $('#text-area').text("DELETE ok");
+ $('#textarea-http').text("DELETE ok");
}
);
}
@@ -300,9 +363,9 @@ function getRecording() {
'GET',
'api/recording/get/' + forceRecordingId, {},
'Get recording WRONG',
- (response) => {
- console.log(response);
- $('#text-area').text(JSON.stringify(response, null, "\t"));
+ res => {
+ console.log(res);
+ $('#textarea-http').text(JSON.stringify(res, null, "\t"));
}
);
}
@@ -312,9 +375,9 @@ function listRecordings() {
'GET',
'api/recording/list', {},
'List recordings WRONG',
- (response) => {
- console.log(response);
- $('#text-area').text(JSON.stringify(response, null, "\t"));
+ res => {
+ console.log(res);
+ $('#textarea-http').text(JSON.stringify(res, null, "\t"));
}
);
}
@@ -325,6 +388,8 @@ function listRecordings() {
/* APPLICATION BROWSER METHODS */
+events = '';
+
window.onbeforeunload = function () { // Gracefully leave session
if (session) {
removeUser();
@@ -373,4 +438,18 @@ function checkBtnsRecordings() {
}
}
+function pushEvent(event) {
+ events += (!events ? '' : '\n') + event.type;
+ $('#textarea-events').text(events);
+}
+
+function clearHttpTextarea() {
+ $('#textarea-http').text('');
+}
+
+function clearEventsTextarea() {
+ $('#textarea-events').text('');
+ events = '';
+}
+
/* APPLICATION BROWSER METHODS */
\ No newline at end of file
diff --git a/openvidu-recording-java/src/main/resources/static/index.html b/openvidu-recording-java/src/main/resources/static/index.html
index 0cd0b071..ae86e6ed 100644
--- a/openvidu-recording-java/src/main/resources/static/index.html
+++ b/openvidu-recording-java/src/main/resources/static/index.html
@@ -60,7 +60,7 @@
-
+
@@ -89,10 +89,10 @@
@@ -89,10 +89,10 @@