openvidu-recording-java: update to openvidu-java-client 2.3.0

This commit is contained in:
pabloFuente 2018-07-22 22:27:08 +02:00
parent 7cc0266406
commit ac52d0c3cb
7 changed files with 342 additions and 52 deletions

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<beansProjectDescription>
<version>1</version>
<pluginVersion><![CDATA[3.9.2.201712210913-RELEASE]]></pluginVersion>
<configSuffixes>
<configSuffix><![CDATA[xml]]></configSuffix>
</configSuffixes>
<enableImports><![CDATA[false]]></enableImports>
<configs>
<config>java:io.openvidu.recording.java.App</config>
</configs>
<autoconfigs>
</autoconfigs>
<configSets>
</configSets>
</beansProjectDescription>

View File

@ -19,7 +19,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<start-class>io.openvidu.js.java.App</start-class>
<start-class>io.openvidu.recording.java.App</start-class>
<docker.image.prefix>openvidu</docker.image.prefix>
</properties>
@ -95,7 +95,7 @@
<dependency>
<groupId>io.openvidu</groupId>
<artifactId>openvidu-java-client</artifactId>
<version>2.2.0</version>
<version>2.3.0</version>
</dependency>
</dependencies>

View File

@ -1,4 +1,4 @@
package io.openvidu.js.java;
package io.openvidu.recording.java;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

View File

@ -1,4 +1,4 @@
package io.openvidu.js.java;
package io.openvidu.recording.java;
import java.util.Collection;
import java.util.List;
@ -18,13 +18,13 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import io.openvidu.java.client.Recording;
import io.openvidu.java.client.OpenVidu;
import io.openvidu.java.client.OpenViduHttpException;
import io.openvidu.java.client.OpenViduJavaClientException;
import io.openvidu.java.client.OpenViduRole;
import io.openvidu.java.client.Recording;
import io.openvidu.java.client.Session;
import io.openvidu.java.client.TokenOptions;
import io.openvidu.java.client.OpenViduRole;
@RestController
@RequestMapping("/api")
@ -35,7 +35,8 @@ public class MyRestController {
// Collection to pair session names and OpenVidu Session objects
private Map<String, Session> mapSessions = new ConcurrentHashMap<>();
// Collection to pair session names and tokens (the inner Map pairs tokens and role associated)
// Collection to pair session names and tokens (the inner Map pairs tokens and
// role associated)
private Map<String, Map<String, OpenViduRole>> mapSessionNamesTokens = new ConcurrentHashMap<>();
// Collection to pair session names and recording objects
private Map<String, Boolean> sessionRecordings = new ConcurrentHashMap<>();
@ -101,7 +102,8 @@ public class MyRestController {
try {
// Create a new OpenVidu Session
Session session = this.openVidu.createSession();
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);
@ -157,6 +159,119 @@ public class MyRestController {
}
}
@RequestMapping(value = "/close-session", method = RequestMethod.DELETE)
public ResponseEntity<JSONObject> closeSession(@RequestBody String sessionName) throws Exception {
System.out.println("Closing session | {sessionName}=" + sessionName);
// Retrieve the param from BODY
JSONObject sessionNameJSON = (JSONObject) new JSONParser().parse(sessionName);
String session = (String) sessionNameJSON.get("sessionName");
// If the session exists
if (this.mapSessions.get(session) != null && this.mapSessionNamesTokens.get(session) != null) {
Session s = this.mapSessions.get(session);
s.close();
this.mapSessions.remove(session);
this.mapSessionNamesTokens.remove(session);
this.sessionRecordings.remove(s.getSessionId());
return new ResponseEntity<>(HttpStatus.OK);
} else {
// The SESSION does not exist
System.out.println("Problems in the app server: the SESSION does not exist");
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@RequestMapping(value = "/fetch-info", method = RequestMethod.POST)
public ResponseEntity<JSONObject> fetchInfo(@RequestBody String sessionName) {
try {
System.out.println("Fetching session info | {sessionName}=" + sessionName);
// Retrieve the param from BODY
JSONObject sessionNameJSON = (JSONObject) new JSONParser().parse(sessionName);
String session = (String) sessionNameJSON.get("sessionName");
// If the session exists
if (this.mapSessions.get(session) != null && this.mapSessionNamesTokens.get(session) != null) {
Session s = this.mapSessions.get(session);
boolean changed = s.fetch();
System.out.println("Any change: " + changed);
return new ResponseEntity<>(this.sessionToJson(s), HttpStatus.OK);
} else {
// The SESSION does not exist
System.out.println("Problems in the app server: the SESSION does not exist");
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
} catch (ParseException | OpenViduJavaClientException | OpenViduHttpException e) {
e.printStackTrace();
return getErrorResponse(e);
}
}
@RequestMapping(value = "/fetch-all", method = RequestMethod.GET)
public ResponseEntity<?> fetchAll() {
try {
System.out.println("Fetching all session info");
boolean changed = this.openVidu.fetch();
System.out.println("Any change: " + changed);
JSONArray jsonArray = new JSONArray();
for (Session s : this.openVidu.getActiveSessions()) {
jsonArray.add(this.sessionToJson(s));
}
return new ResponseEntity<>(jsonArray, HttpStatus.OK);
} catch (OpenViduJavaClientException | OpenViduHttpException e) {
e.printStackTrace();
return getErrorResponse(e);
}
}
@RequestMapping(value = "/force-disconnect", method = RequestMethod.DELETE)
public ResponseEntity<JSONObject> forceDisconnect(@RequestBody String sessionName) {
try {
// Retrieve the param from BODY
JSONObject sessionNameConnectionIdJSON = (JSONObject) new JSONParser().parse(sessionName);
String session = (String) sessionNameConnectionIdJSON.get("sessionName");
String connectionId = (String) sessionNameConnectionIdJSON.get("connectionId");
// If the session exists
if (this.mapSessions.get(session) != null && this.mapSessionNamesTokens.get(session) != null) {
Session s = this.mapSessions.get(session);
s.forceDisconnect(connectionId);
return new ResponseEntity<>(HttpStatus.OK);
} else {
// The SESSION does not exist
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
} catch (ParseException | OpenViduJavaClientException | OpenViduHttpException e) {
e.printStackTrace();
return getErrorResponse(e);
}
}
@RequestMapping(value = "/force-unpublish", method = RequestMethod.DELETE)
public ResponseEntity<JSONObject> forceUnpublish(@RequestBody String sessionName) {
try {
// Retrieve the param from BODY
JSONObject sessionNameStreamIdJSON = (JSONObject) new JSONParser().parse(sessionName);
String session = (String) sessionNameStreamIdJSON.get("sessionName");
String streamId = (String) sessionNameStreamIdJSON.get("streamId");
// If the session exists
if (this.mapSessions.get(session) != null && this.mapSessionNamesTokens.get(session) != null) {
Session s = this.mapSessions.get(session);
s.forceUnpublish(streamId);
return new ResponseEntity<>(HttpStatus.OK);
} else {
// The SESSION does not exist
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
} catch (ParseException | OpenViduJavaClientException | OpenViduHttpException e) {
e.printStackTrace();
return getErrorResponse(e);
}
}
/*******************/
/** Recording API **/
/*******************/
@ -269,5 +384,51 @@ public class MyRestController {
}
return array;
}
@SuppressWarnings("unchecked")
protected JSONObject sessionToJson(Session session) {
JSONObject json = new JSONObject();
json.put("sessionId", session.getSessionId());
json.put("customSessionId", session.getProperties().customSessionId());
json.put("recording", session.isBeingRecorded());
json.put("mediaMode", session.getProperties().mediaMode());
json.put("recordingMode", session.getProperties().recordingMode());
json.put("defaultRecordingLayout", session.getProperties().defaultRecordingLayout());
json.put("defaultCustomLayout", session.getProperties().defaultCustomLayout());
JSONObject connections = new JSONObject();
connections.put("numberOfElements", session.getActiveConnections().size());
JSONArray jsonArrayConnections = new JSONArray();
session.getActiveConnections().forEach(con -> {
JSONObject c = new JSONObject();
c.put("connectionId", con.getConnectionId());
c.put("role", con.getRole());
c.put("token", con.getToken());
c.put("clientData", con.getClientData());
c.put("serverData", con.getServerData());
JSONArray pubs = new JSONArray();
con.getPublishers().forEach(p -> {
JSONObject jsonP = new JSONObject();
jsonP.put("streamId", p.getStreamId());
jsonP.put("hasAudio", p.hasAudio());
jsonP.put("hasVideo", p.hasVideo());
jsonP.put("audioActive", p.isAudioActive());
jsonP.put("videoActive", p.isVideoActive());
jsonP.put("frameRate", p.getFrameRate());
jsonP.put("typeOfVideo", p.getTypeOfVideo());
jsonP.put("videoDimensions", p.getVideoDimensions());
pubs.add(jsonP);
});
JSONArray subs = new JSONArray();
con.getSubscribers().forEach(s -> {
subs.add(s);
});
c.put("publishers", pubs);
c.put("subscribers", subs);
jsonArrayConnections.add(c);
});
connections.put("content", jsonArrayConnections);
json.put("connections", connections);
return json;
}
}

View File

@ -41,6 +41,18 @@ function joinSession() {
});
});
session.on('sessionDisconnected', (event) => {
if (event.reason !== 'disconnect') {
removeUser();
}
if (event.reason !== 'sessionClosedByServer') {
session = null;
numVideos = 0;
$('#join').show();
$('#session').hide();
}
});
// --- 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) ---
@ -97,13 +109,8 @@ function joinSession() {
function leaveSession() {
// --- 9) Leave the session by calling 'disconnect' method over the Session object ---
session.disconnect();
session = null;
numVideos = 0;
$('#join').show();
$('#session').hide();
}
/* OPENVIDU METHODS */
@ -118,7 +125,7 @@ function getToken(callback) {
httpRequest(
'POST',
'api/get-token',
{sessionName: sessionName},
{ sessionName: sessionName },
'Request of TOKEN gone WRONG:',
(response) => {
token = response[0]; // Get token from response
@ -132,14 +139,76 @@ function removeUser() {
httpRequest(
'POST',
'api/remove-user',
{sessionName: sessionName, token: token},
'User couldn\'t be removed from session',
{ sessionName: sessionName, token: token },
'User couldn\'t be removed from session',
(response) => {
console.warn("You have been removed from session " + sessionName);
}
);
}
function closeSession() {
httpRequest(
'DELETE',
'api/close-session',
{ sessionName: sessionName },
'Session couldn\'t be closed',
(response) => {
console.warn("Session " + sessionName + " has been closed");
}
);
}
function fetchInfo() {
httpRequest(
'POST',
'api/fetch-info',
{ sessionName: sessionName },
'Session couldn\'t be fetched',
(response) => {
console.warn("Session info has been fetched");
$('#text-area').text(JSON.stringify(response, null, "\t"));
}
);
}
function fetchAll() {
httpRequest(
'GET',
'api/fetch-all',
{},
'All session info couldn\'t be fetched',
(response) => {
console.warn("All session info has been fetched");
$('#text-area').text(JSON.stringify(response, null, "\t"));
}
);
}
function forceDisconnect() {
httpRequest(
'DELETE',
'api/force-disconnect',
{ sessionName: sessionName, connectionId: document.getElementById('forceValue').value },
'Connection couldn\'t be closed',
(response) => {
console.warn("Connection has been closed");
}
);
}
function forceUnpublish() {
httpRequest(
'DELETE',
'api/force-unpublish',
{ sessionName: sessionName, streamId: document.getElementById('forceValue').value },
'Stream couldn\'t be closed',
(response) => {
console.warn("Stream has been closed");
}
);
}
function httpRequest(method, url, body, errorMsg, callback) {
$('#text-area').text('');
var http = new XMLHttpRequest();
@ -154,7 +223,7 @@ function httpRequest(method, url, body, errorMsg, callback) {
try {
callback(JSON.parse(http.responseText));
} catch (e) {
callback();
callback(e);
}
} else {
console.warn(errorMsg + ' (' + http.status + ')');
@ -165,28 +234,28 @@ function httpRequest(method, url, body, errorMsg, callback) {
}
}
var recordingId;
function startRecording() {
httpRequest(
'POST',
'api/recording/start',
{session: session.sessionId},
'Start recording WRONG',
{ session: session.sessionId },
'Start recording WRONG',
(response) => {
console.log(response);
recordingId = response.id;
document.getElementById('forceRecordingId').value = response.id;
checkBtnsRecordings();
$('#text-area').text(JSON.stringify(response, null, "\t"));
}
);
}
function stopRecording() {
var forceRecordingId = document.getElementById('forceRecordingId').value;
httpRequest(
'POST',
'api/recording/stop',
{recording: recordingId},
'Stop recording WRONG',
{ recording: forceRecordingId },
'Stop recording WRONG',
(response) => {
console.log(response);
$('#text-area').text(JSON.stringify(response, null, "\t"));
@ -195,10 +264,11 @@ function stopRecording() {
}
function deleteRecording() {
var forceRecordingId = document.getElementById('forceRecordingId').value;
httpRequest(
'DELETE',
'api/recording/delete',
{recording: recordingId},
{ recording: forceRecordingId },
'Delete recording WRONG',
() => {
console.log("DELETE ok");
@ -208,9 +278,10 @@ function deleteRecording() {
}
function getRecording() {
var forceRecordingId = document.getElementById('forceRecordingId').value;
httpRequest(
'GET',
'api/recording/get/' + recordingId,
'api/recording/get/' + forceRecordingId,
{},
'Get recording WRONG',
(response) => {
@ -265,4 +336,26 @@ function updateNumVideos(i) {
}
}
function checkBtnsForce() {
if (document.getElementById("forceValue").value === "") {
document.getElementById('buttonForceUnpublish').disabled = true;
document.getElementById('buttonForceDisconnect').disabled = true;
} else {
document.getElementById('buttonForceUnpublish').disabled = false;
document.getElementById('buttonForceDisconnect').disabled = false;
}
}
function checkBtnsRecordings() {
if (document.getElementById("forceRecordingId").value === "") {
document.getElementById('buttonGetRecording').disabled = true;
document.getElementById('buttonStopRecording').disabled = true;
document.getElementById('buttonDeleteRecording').disabled = true;
} else {
document.getElementById('buttonGetRecording').disabled = false;
document.getElementById('buttonStopRecording').disabled = false;
document.getElementById('buttonDeleteRecording').disabled = false;
}
}
/* APPLICATION BROWSER METHODS */

View File

@ -7,9 +7,12 @@
<link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon">
<!-- Bootstrap -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g="
crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- Bootstrap -->
@ -33,7 +36,7 @@
<a class="navbar-brand" href="/">
<img class="demo-logo" src="images/openvidu_vert_white_bg_trans_cropped.png" /> Recording Java</a>
<a class="navbar-brand nav-icon" href="https://github.com/OpenVidu/openvidu-tutorials/tree/master/openvidu-recording-java"
title="GitHub Repository" target="_blank">
title="GitHub Repository" target="_blank">
<i class="fa fa-github" aria-hidden="true"></i>
</a>
<a class="navbar-brand nav-icon" href="http://www.openvidu.io/docs/tutorials/openvidu-js-java/" title="Documentation" target="_blank">
@ -66,16 +69,25 @@
<div id="session" style="display: none">
<div id="session-header">
<h1 id="session-title"></h1>
<input class="btn btn-large btn-danger" type="button" id="buttonLeaveSession" onmouseup="removeUser(); leaveSession()" value="Leave session">
<input class="btn btn-sm btn-danger" type="button" id="buttonCloseSession" onmouseup="closeSession()" value="Close session">
<input class="btn btn-sm btn-danger" type="button" id="buttonLeaveSession" onmouseup="removeUser(); leaveSession()" value="Leave session">
<input class="btn btn-sm" type="button" id="buttonForceUnpublish" onmouseup="forceUnpublish()" value="Force unpublish" disabled>
<input class="btn btn-sm" type="button" id="buttonForceDisconnect" onmouseup="forceDisconnect()" value="Force disconnect"
disabled>
<input class="form-control" id="forceValue" type="text" onkeyup="checkBtnsForce()">
<input class="btn btn-sm" type="button" id="buttonFetchInfo" onmouseup="fetchInfo()" value="Fetch info">
<input class="btn btn-sm" type="button" id="buttonFetchAll" onmouseup="fetchAll()" value="Fetch all">
</div>
<div id="video-container" class="col-md-12"></div>
<div id="recording-btns">
<div id="btns">
<input class="btn btn-large" type="button" onmouseup="startRecording()" value="Start recording">
<input class="btn btn-large" type="button" onmouseup="stopRecording()" value="Stop recording">
<input class="btn btn-large" type="button" onmouseup="deleteRecording()" value="Delete recording">
<input class="btn btn-large" type="button" onmouseup="getRecording()" value="Get recording">
<input class="btn btn-large" type="button" onmouseup="listRecordings()" value="List recordings">
<input class="btn btn-md" type="button" id="buttonStartRecording" onmouseup="startRecording()" value="Start recording">
<input class="btn btn-md" type="button" id="buttonListRecording" onmouseup="listRecordings()" value="List recordings">
<input class="form-control" id="forceRecordingId" type="text" onkeyup="checkBtnsRecordings()">
<input class="btn btn-md" type="button" id="buttonGetRecording" onmouseup="getRecording()" value="Get recording" disabled>
<input class="btn btn-md" type="button" id="buttonStopRecording" onmouseup="stopRecording()" value="Stop recording" disabled>
<input class="btn btn-md" type="button" id="buttonDeleteRecording" onmouseup="deleteRecording()" value="Delete recording"
disabled>
</div>
<textarea id="text-area" readonly="true" class="form-control" name="comment">HTTP responses...</textarea>
</div>

View File

@ -46,7 +46,7 @@ nav i.fa:hover {
#main-container {
padding-bottom: 80px;
height: 100%;
margin-top: -70px;
margin-top: -70px;
}
.vertical-center {
@ -225,20 +225,27 @@ a:hover .demo-logo {
#session-header {
margin-bottom: 20px;
height: 8%;
margin-top: 70px;
margin-top: 70px;
}
#session-header form {
display: inline;
}
#session-header input.btn {
float: right;
margin-top: 20px;
margin-left: 5px;
}
#session-title {
display: inline-block;
}
#buttonLeaveSession {
#session-header .form-control {
width: initial;
float: right;
margin-top: 20px;
margin: 18px 0px 0px 5px;
}
#video-container {
@ -248,15 +255,15 @@ a:hover .demo-logo {
overflow: hidden;
}
#video-container video.two{
#video-container video.two {
width: 50%;
}
#video-container video.three{
#video-container video.three {
width: 33.33%;
}
#video-container video.four{
#video-container video.four {
width: 25%;
}
@ -295,7 +302,7 @@ video {
#session {
height: 100%;
padding-bottom: 80px;
padding-bottom: 80px;
}
#session img {
@ -353,19 +360,20 @@ table i {
height: 40%;
}
#recording-btns input {
margin-top: 5px;
#recording-btns #btns {
margin-top: 10px;
}
#recording-btns #btns {
margin-top: 5px;
#recording-btns #btns .form-control {
width: initial;
display: inline-block;
}
#recording-btns #text-area {
display: inline-block;
width: 100%;
height: 80%;
margin-top: 20px;
width: 100%;
height: 80%;
margin-top: 20px;
}
/* xs ans md screen resolutions*/