openvidu-java-client recording support

pull/30/merge
pabloFuente 2018-03-13 16:14:37 +01:00
parent c5a66f0efb
commit d529918000
4 changed files with 314 additions and 116 deletions

View File

@ -0,0 +1,81 @@
package io.openvidu.java.client;
import org.json.simple.JSONObject;
public class Archive {
public enum Status {
starting, // The recording is starting (cannot be stopped)
started, // The recording has started and is going on
stopped, // The recording has finished OK
available, // The recording is available for downloading. This status is reached for all
// stopped recordings if property 'openvidu.recording.free-access' is true
failed; // The recording has failed
}
private Archive.Status status;
private String id;
private String name;
private String sessionId;
private long createdAt; // milliseconds (UNIX Epoch time)
private long size = 0; // bytes
private double duration = 0; // seconds
private String url;
private boolean hasAudio = true;
private boolean hasVideo = true;
public Archive(JSONObject json) {
this.id = (String) json.get("id");
this.name = (String) json.get("name");
this.sessionId = (String) json.get("sessionId");
this.createdAt = (long) json.get("createdAt");
this.size = (long) json.get("size");
this.duration = (double) json.get("duration");
this.url = (String) json.get("url");
this.hasAudio = (boolean) json.get("hasAudio");
this.hasVideo = (boolean) json.get("hasVideo");
this.status = Archive.Status.valueOf((String) json.get("status"));
}
public Archive.Status getStatus() {
return status;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getSessionId() {
return sessionId;
}
public long getCreatedAt() {
return createdAt;
}
public long getSize() {
return size;
}
public double getDuration() {
return duration;
}
public String getUrl() {
return url;
}
public boolean hasAudio() {
return hasAudio;
}
public boolean hasVideo() {
return hasVideo;
}
}

View File

@ -1,18 +1,38 @@
package io.openvidu.java.client; package io.openvidu.java.client;
import java.io.IOException;
import java.security.KeyManagementException; import java.security.KeyManagementException;
import java.security.KeyStoreException; import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope; import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider; import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient; import org.apache.http.client.HttpClient;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.client.methods.HttpDelete;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy; import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder; import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import io.openvidu.java.client.OpenViduException.Code;
public class OpenVidu { public class OpenVidu {
@ -20,6 +40,10 @@ public class OpenVidu {
private String secret; private String secret;
private HttpClient myHttpClient; private HttpClient myHttpClient;
final static String API_RECORDINGS = "api/recordings";
final static String API_RECORDINGS_START = "/start";
final static String API_RECORDINGS_STOP = "/stop";
public OpenVidu(String urlOpenViduServer, String secret) { public OpenVidu(String urlOpenViduServer, String secret) {
this.urlOpenViduServer = urlOpenViduServer; this.urlOpenViduServer = urlOpenViduServer;
@ -30,23 +54,28 @@ public class OpenVidu {
this.secret = secret; this.secret = secret;
TrustStrategy trustStrategy = new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
};
CredentialsProvider provider = new BasicCredentialsProvider(); CredentialsProvider provider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("OPENVIDUAPP", this.secret); UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("OPENVIDUAPP", this.secret);
provider.setCredentials(AuthScope.ANY, credentials); provider.setCredentials(AuthScope.ANY, credentials);
SSLContextBuilder builder = new SSLContextBuilder(); SSLContext sslContext;
try { try {
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); sslContext = new SSLContextBuilder().loadTrustMaterial(null, trustStrategy).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build(), } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); throw new RuntimeException(e);
/*SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
builder.build());*/
this.myHttpClient = HttpClients.custom().setSSLSocketFactory(
sslsf).setDefaultCredentialsProvider(provider).build();
} catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
this.myHttpClient = HttpClients.custom().setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.setSSLContext(sslContext).setDefaultCredentialsProvider(provider).build();
} }
public Session createSession() throws OpenViduException { public Session createSession() throws OpenViduException {
@ -59,12 +88,107 @@ public class OpenVidu {
return s; return s;
} }
public void startRecording(String sessionId) { @SuppressWarnings("unchecked")
// TODO: REST POST to start recording in OpenVidu Server public Archive startRecording(String sessionId) throws OpenViduException {
try {
HttpPost request = new HttpPost(this.urlOpenViduServer + API_RECORDINGS + API_RECORDINGS_START);
JSONObject json = new JSONObject();
json.put("session", sessionId);
StringEntity params = new StringEntity(json.toString());
request.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
request.setEntity(params);
HttpResponse response = myHttpClient.execute(request);
int statusCode = response.getStatusLine().getStatusCode();
if ((statusCode == org.apache.http.HttpStatus.SC_OK)) {
return new Archive(OpenVidu.httpResponseToJson(response));
} else {
throw new OpenViduException(Code.RECORDING_START_ERROR_CODE, Integer.toString(statusCode));
}
} catch (Exception e) {
throw new OpenViduException(Code.RECORDING_START_ERROR_CODE,
"Unable to start recording for session '" + sessionId + "': " + e.getMessage());
}
} }
public void stopRecording(String sessionId) { public Archive stopRecording(String recordingId) throws OpenViduException {
// TODO: REST POST to end recording in OpenVidu Server try {
HttpPost request = new HttpPost(
this.urlOpenViduServer + API_RECORDINGS + API_RECORDINGS_STOP + "/" + recordingId);
HttpResponse response = myHttpClient.execute(request);
int statusCode = response.getStatusLine().getStatusCode();
if ((statusCode == org.apache.http.HttpStatus.SC_OK)) {
return new Archive(OpenVidu.httpResponseToJson(response));
} else {
throw new OpenViduException(Code.RECORDING_STOP_ERROR_CODE, Integer.toString(statusCode));
}
} catch (Exception e) {
throw new OpenViduException(Code.RECORDING_STOP_ERROR_CODE,
"Unable to stop recording '" + recordingId + "': " + e.getMessage());
}
}
public Archive getRecording(String recordingId) throws OpenViduException {
try {
HttpGet request = new HttpGet(this.urlOpenViduServer + API_RECORDINGS + "/" + recordingId);
HttpResponse response = myHttpClient.execute(request);
int statusCode = response.getStatusLine().getStatusCode();
if ((statusCode == org.apache.http.HttpStatus.SC_OK)) {
return new Archive(OpenVidu.httpResponseToJson(response));
} else {
throw new OpenViduException(Code.RECORDING_LIST_ERROR_CODE, Integer.toString(statusCode));
}
} catch (Exception e) {
throw new OpenViduException(Code.RECORDING_LIST_ERROR_CODE, "Unable to get recording '" + recordingId + "': " + e.getMessage());
}
}
@SuppressWarnings("unchecked")
public List<Archive> listRecordings() throws OpenViduException {
try {
HttpGet request = new HttpGet(this.urlOpenViduServer + API_RECORDINGS);
HttpResponse response = myHttpClient.execute(request);
int statusCode = response.getStatusLine().getStatusCode();
if ((statusCode == org.apache.http.HttpStatus.SC_OK)) {
List<Archive> archives = new ArrayList<>();
JSONObject json = OpenVidu.httpResponseToJson(response);
JSONArray array = (JSONArray) json.get("items");
array.forEach(item -> {
archives.add(new Archive((JSONObject) item));
});
return archives;
} else {
throw new OpenViduException(Code.RECORDING_LIST_ERROR_CODE, Integer.toString(statusCode));
}
} catch (Exception e) {
throw new OpenViduException(Code.RECORDING_LIST_ERROR_CODE, "Unable to list recordings: " + e.getMessage());
}
}
public void deleteRecording(String recordingId) throws OpenViduException {
try {
HttpDelete request = new HttpDelete(this.urlOpenViduServer + API_RECORDINGS + "/" + recordingId);
HttpResponse response = myHttpClient.execute(request);
int statusCode = response.getStatusLine().getStatusCode();
if (!(statusCode == org.apache.http.HttpStatus.SC_NO_CONTENT)) {
throw new OpenViduException(Code.RECORDING_DELETE_ERROR_CODE, Integer.toString(statusCode));
}
} catch (Exception e) {
throw new OpenViduException(Code.RECORDING_DELETE_ERROR_CODE,
"Unable to delete recording '" + recordingId + "': " + e.getMessage());
}
}
public static JSONObject httpResponseToJson(HttpResponse response) throws ParseException, IOException {
JSONParser parser = new JSONParser();
return (JSONObject) parser.parse(EntityUtils.toString(response.getEntity()));
} }
} }

View File

@ -23,25 +23,29 @@ public class OpenViduException extends RuntimeException {
public static enum Code { public static enum Code {
GENERIC_ERROR_CODE(999), GENERIC_ERROR_CODE(999),
TRANSPORT_ERROR_CODE(803), TRANSPORT_RESPONSE_ERROR_CODE(802), TRANSPORT_REQUEST_ERROR_CODE( TRANSPORT_ERROR_CODE(803), TRANSPORT_RESPONSE_ERROR_CODE(802), TRANSPORT_REQUEST_ERROR_CODE(801),
801),
MEDIA_MUTE_ERROR_CODE(307), MEDIA_NOT_A_WEB_ENDPOINT_ERROR_CODE( MEDIA_MUTE_ERROR_CODE(307), MEDIA_NOT_A_WEB_ENDPOINT_ERROR_CODE(306), MEDIA_RTP_ENDPOINT_ERROR_CODE(
306), MEDIA_RTP_ENDPOINT_ERROR_CODE(305), MEDIA_WEBRTC_ENDPOINT_ERROR_CODE( 305), MEDIA_WEBRTC_ENDPOINT_ERROR_CODE(
304), MEDIA_ENDPOINT_ERROR_CODE( 304), MEDIA_ENDPOINT_ERROR_CODE(303), MEDIA_SDP_ERROR_CODE(302), MEDIA_GENERIC_ERROR_CODE(301),
303), MEDIA_SDP_ERROR_CODE(302), MEDIA_GENERIC_ERROR_CODE(301),
ROOM_CANNOT_BE_CREATED_ERROR_CODE(204), ROOM_CLOSED_ERROR_CODE(203), ROOM_NOT_FOUND_ERROR_CODE( ROOM_CANNOT_BE_CREATED_ERROR_CODE(204), ROOM_CLOSED_ERROR_CODE(203), ROOM_NOT_FOUND_ERROR_CODE(
202), ROOM_GENERIC_ERROR_CODE(201), 202), ROOM_GENERIC_ERROR_CODE(201),
USER_NOT_STREAMING_ERROR_CODE(105), EXISTING_USER_IN_ROOM_ERROR_CODE( USER_NOT_STREAMING_ERROR_CODE(105), EXISTING_USER_IN_ROOM_ERROR_CODE(104), USER_CLOSED_ERROR_CODE(
104), USER_CLOSED_ERROR_CODE(
103), USER_NOT_FOUND_ERROR_CODE(102), USER_GENERIC_ERROR_CODE(101), 103), USER_NOT_FOUND_ERROR_CODE(102), USER_GENERIC_ERROR_CODE(101),
USER_UNAUTHORIZED_ERROR_CODE(401), ROLE_NOT_FOUND_ERROR_CODE(402), USER_UNAUTHORIZED_ERROR_CODE(401), ROLE_NOT_FOUND_ERROR_CODE(402), SESSIONID_CANNOT_BE_CREATED_ERROR_CODE(
SESSIONID_CANNOT_BE_CREATED_ERROR_CODE(403), TOKEN_CANNOT_BE_CREATED_ERROR_CODE(404), 403), TOKEN_CANNOT_BE_CREATED_ERROR_CODE(404),
USER_METADATA_FORMAT_INVALID_ERROR_CODE(500); USER_METADATA_FORMAT_INVALID_ERROR_CODE(500),
SIGNAL_FORMAT_INVALID_ERROR_CODE(600), SIGNAL_TO_INVALID_ERROR_CODE(601), SIGNAL_MESSAGE_INVALID_ERROR_CODE(
602),
RECORDING_FILE_EMPTY_ERROR(707), RECORDING_DELETE_ERROR_CODE(706), RECORDING_LIST_ERROR_CODE(
705), RECORDING_STOP_ERROR_CODE(704), RECORDING_START_ERROR_CODE(
703), RECORDING_REPORT_ERROR_CODE(702), RECORDING_COMPLETION_ERROR_CODE(701);
private int value; private int value;

View File

@ -1,16 +1,11 @@
package io.openvidu.java.client; package io.openvidu.java.client;
import java.io.BufferedReader; import org.apache.http.HttpHeaders;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient; import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity; import org.apache.http.entity.StringEntity;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import io.openvidu.java.client.OpenViduException.Code; import io.openvidu.java.client.OpenViduException.Code;
@ -21,6 +16,9 @@ public class Session {
private String sessionId; private String sessionId;
private SessionProperties properties; private SessionProperties properties;
final static String API_SESSIONS = "api/sessions";
final static String API_TOKENS = "api/tokens";
protected Session(HttpClient httpClient, String urlOpenViduServer) throws OpenViduException { protected Session(HttpClient httpClient, String urlOpenViduServer) throws OpenViduException {
this.httpClient = httpClient; this.httpClient = httpClient;
this.urlOpenViduServer = urlOpenViduServer; this.urlOpenViduServer = urlOpenViduServer;
@ -35,6 +33,7 @@ public class Session {
this.sessionId = this.getSessionId(); this.sessionId = this.getSessionId();
} }
@SuppressWarnings("unchecked")
public String getSessionId() throws OpenViduException { public String getSessionId() throws OpenViduException {
if (this.hasSessionId()) { if (this.hasSessionId()) {
@ -42,15 +41,15 @@ public class Session {
} }
try { try {
HttpPost request = new HttpPost(this.urlOpenViduServer + API_SESSIONS);
JSONObject json = new JSONObject(); JSONObject json = new JSONObject();
json.put("archiveMode", properties.archiveMode().name());
json.put("archiveLayout", properties.archiveLayout().name()); json.put("archiveLayout", properties.archiveLayout().name());
json.put("archiveMode", properties.archiveMode().name());
json.put("mediaMode", properties.mediaMode().name()); json.put("mediaMode", properties.mediaMode().name());
HttpPost request = new HttpPost(this.urlOpenViduServer + "api/sessions");
StringEntity params = new StringEntity(json.toString()); StringEntity params = new StringEntity(json.toString());
request.addHeader("content-type", "application/json");
request.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
request.setEntity(params); request.setEntity(params);
HttpResponse response = httpClient.execute(request); HttpResponse response = httpClient.execute(request);
@ -58,7 +57,7 @@ public class Session {
if ((statusCode == org.apache.http.HttpStatus.SC_OK)) { if ((statusCode == org.apache.http.HttpStatus.SC_OK)) {
System.out.println("Returning a SESSIONID"); System.out.println("Returning a SESSIONID");
String id = ""; String id = "";
id = this.httpResponseToString(response); id = (String) OpenVidu.httpResponseToJson(response).get("id");
this.sessionId = id; this.sessionId = id;
return id; return id;
} else { } else {
@ -75,6 +74,7 @@ public class Session {
return this.generateToken(new TokenOptions.Builder().role(OpenViduRole.PUBLISHER).build()); return this.generateToken(new TokenOptions.Builder().role(OpenViduRole.PUBLISHER).build());
} }
@SuppressWarnings("unchecked")
public String generateToken(TokenOptions tokenOptions) throws OpenViduException { public String generateToken(TokenOptions tokenOptions) throws OpenViduException {
if (!this.hasSessionId()) { if (!this.hasSessionId()) {
@ -82,15 +82,15 @@ public class Session {
} }
try { try {
HttpPost request = new HttpPost(this.urlOpenViduServer + API_TOKENS);
JSONObject json = new JSONObject(); JSONObject json = new JSONObject();
json.put("session", this.sessionId); json.put("session", this.sessionId);
json.put("role", tokenOptions.getRole().name()); json.put("role", tokenOptions.getRole().name());
json.put("data", tokenOptions.getData()); json.put("data", tokenOptions.getData());
HttpPost request = new HttpPost(this.urlOpenViduServer + "api/tokens");
StringEntity params = new StringEntity(json.toString()); StringEntity params = new StringEntity(json.toString());
request.addHeader("content-type", "application/json");
request.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
request.setEntity(params); request.setEntity(params);
HttpResponse response = httpClient.execute(request); HttpResponse response = httpClient.execute(request);
@ -98,7 +98,7 @@ public class Session {
int statusCode = response.getStatusLine().getStatusCode(); int statusCode = response.getStatusLine().getStatusCode();
if ((statusCode == org.apache.http.HttpStatus.SC_OK)) { if ((statusCode == org.apache.http.HttpStatus.SC_OK)) {
System.out.println("Returning a TOKEN"); System.out.println("Returning a TOKEN");
return this.httpResponseToString(response); return (String) OpenVidu.httpResponseToJson(response).get("id");
} else { } else {
throw new OpenViduException(Code.TOKEN_CANNOT_BE_CREATED_ERROR_CODE, Integer.toString(statusCode)); throw new OpenViduException(Code.TOKEN_CANNOT_BE_CREATED_ERROR_CODE, Integer.toString(statusCode));
} }
@ -118,17 +118,6 @@ public class Session {
return this.sessionId; return this.sessionId;
} }
private String httpResponseToString(HttpResponse response) throws IOException, ParseException {
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer buf = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
buf.append(line);
}
JSONParser parser = new JSONParser();
return ((String) ((JSONObject) parser.parse(buf.toString())).get("id"));
}
private boolean hasSessionId() { private boolean hasSessionId() {
return (this.sessionId != null && !this.sessionId.isEmpty()); return (this.sessionId != null && !this.sessionId.isEmpty());
} }