Skip to content

Commit b93f2f5

Browse files
SMadanijeffswartz
andcommitted
Add Experience Composer API (#227)
* Added startRender * Added listRenders * Deserialize listRenders response to native List * Added stopRender & getRender * Use enum for Render status * Improved RenderProperties * Experience composer docs edits ... And other docs corrections Co-authored-by: Jeff Swartz <jeff.swartz@vonage.com>
1 parent edf766f commit b93f2f5

File tree

8 files changed

+785
-29
lines changed

8 files changed

+785
-29
lines changed

README.md

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ The OpenTok Java SDK provides methods for:
1616
* [Sending signals to clients connected to a session](https://tokbox.com/developer/guides/signaling/)
1717
* [Disconnecting clients from sessions](https://tokbox.com/developer/guides/moderation/rest/)
1818
* [Forcing clients in a session to disconnect or mute published audio](https://tokbox.com/developer/guides/moderation/)
19+
* Working with OpenTok [Experience Composers](https://tokbox.com/developer/guides/experience-composer)
1920

2021
## Installation
2122

@@ -411,10 +412,9 @@ For more information on signaling and exception codes, refer to the documentatio
411412

412413
You can broadcast OpenTok publishing streams to an HLS (HTTP live streaming) or
413414
to RTMP streams. To successfully start broadcasting a session, at least one client must be
414-
connected to the session. You can only have one active live streaming broadcast at a time
415-
for a session (however, having more than one would not be useful).
415+
connected to the session.
416416
The live streaming broadcast can target one HLS endpoint and up to five
417-
RTMP servers simulteneously for a session. You can only start live streaming
417+
RTMP servers simultaneously for a session. You can only start live streaming
418418
for sessions that use the OpenTok Media Router (with the media mode set to routed);
419419
you cannot use live streaming with sessions that have the media mode set to relayed.
420420
(See the [OpenTok Media Router and media
@@ -571,6 +571,25 @@ SipProperties properties = new SipProperties.Builder()
571571
Sip sip = opentok.dial(sessionId, token, properties);
572572
```
573573

574+
### Working with Experience Composers
575+
576+
You can start an [Experience Composer](https://tokbox.com/developer/guides/experience-composer)
577+
by calling the `OpenTok.startRender(String sessionId, String token, RenderProperties properties)`
578+
method:
579+
580+
```java
581+
RenderProperties properties = new RenderProperties.Builder()
582+
.url(("http://example.com/path-to-page/")
583+
.build();
584+
585+
Render render = opentok.startRender(sessionId, token, properties);
586+
```
587+
588+
You can stop an Experience Composer by calling the `OpenTok.stopRender(String renderId)` method.
589+
590+
You can get information about Experience Composers by calling the `OpenTok.getRender(String renderId)`,
591+
`OpenTok.listRenders()` or `OpenTok.listRenders(Integer offset, Integer count)` methods.
592+
574593
## Samples
575594

576595
There are two sample applications included with the SDK. To get going as fast as possible, clone the whole

src/main/java/com/opentok/ArchiveList.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
/**
1616
* Represents a list of archives of OpenTok session(s).
1717
*/
18-
@JsonFormat(shape= JsonFormat.Shape.OBJECT)
18+
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
1919
public class ArchiveList extends ArrayList<Archive> {
2020

2121
private int totalCount;

src/main/java/com/opentok/OpenTok.java

Lines changed: 110 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88
package com.opentok;
99
import com.fasterxml.jackson.core.JsonProcessingException;
10+
import com.fasterxml.jackson.databind.JsonNode;
1011
import com.fasterxml.jackson.databind.ObjectMapper;
1112
import com.fasterxml.jackson.databind.ObjectReader;
1213
import com.opentok.exception.InvalidArgumentException;
@@ -39,20 +40,17 @@ public class OpenTok {
3940
private int apiKey;
4041
private String apiSecret;
4142
protected HttpClient client;
42-
static protected ObjectReader archiveReader = new ObjectMapper()
43-
.readerFor(Archive.class);
44-
static protected ObjectReader archiveListReader = new ObjectMapper()
45-
.readerFor(ArchiveList.class);
46-
static protected ObjectReader createdSessionReader = new ObjectMapper()
47-
.readerFor(CreatedSession[].class);
48-
static protected ObjectReader streamReader = new ObjectMapper()
49-
.readerFor(Stream.class);
50-
static protected ObjectReader streamListReader = new ObjectMapper()
51-
.readerFor(StreamList.class);
52-
static protected ObjectReader sipReader = new ObjectMapper()
53-
.readerFor(Sip.class);
54-
static protected ObjectReader broadcastReader = new ObjectMapper()
55-
.readerFor(Broadcast.class);
43+
protected static final ObjectReader
44+
archiveReader = new ObjectMapper().readerFor(Archive.class),
45+
archiveListReader = new ObjectMapper().readerFor(ArchiveList.class),
46+
createdSessionReader = new ObjectMapper().readerFor(CreatedSession[].class),
47+
streamReader = new ObjectMapper().readerFor(Stream.class),
48+
streamListReader = new ObjectMapper().readerFor(StreamList.class),
49+
sipReader = new ObjectMapper().readerFor(Sip.class),
50+
broadcastReader = new ObjectMapper().readerFor(Broadcast.class),
51+
renderReader = new ObjectMapper().readerFor(Render.class),
52+
renderListReader = new ObjectMapper().readerForListOf(Render.class);
53+
5654
static final String defaultApiUrl = "https://api.opentok.com";
5755

5856
/**
@@ -545,7 +543,7 @@ public void setArchiveLayout(String archiveId, ArchiveProperties properties) thr
545543
}
546544

547545
/**
548-
* Use this method to start a live streaming for an OpenTok session.
546+
* Starts a live streaming broadcast for an OpenTok session.
549547
* This broadcasts the session to an HLS (HTTP live streaming) or to RTMP streams.
550548
* <p>
551549
* To successfully start broadcasting a session, at least one client must be connected to the session.
@@ -581,7 +579,7 @@ public Broadcast startBroadcast(String sessionId, BroadcastProperties properties
581579
}
582580

583581
/**
584-
* Use this method to stop a live broadcast of an OpenTok session.
582+
* Stops a live streaming broadcast of an OpenTok session.
585583
* Note that broadcasts automatically stop 120 minutes after they are started.
586584
* <p>
587585
* For more information on broadcasting, see the
@@ -819,10 +817,10 @@ public StreamList listStreams(String sessionId) throws OpenTokException {
819817
* such as phone numbers. (The OpenTok client libraries include properties for inspecting
820818
* the connection data for a client connected to a session.) See the
821819
* <a href="https://tokbox.com/developer/guides/signaling/">Token Creation developer guide</a>.
822-
. *
820+
*
823821
* @param properties The {@link SipProperties} object defining options for the SIP call.
824822
*
825-
* @return The {@link Sip} object.
823+
* @return The {@link Sip} object.
826824
*/
827825
public Sip dial(String sessionId, String token, SipProperties properties) throws OpenTokException {
828826
if ((StringUtils.isEmpty(sessionId) || StringUtils.isEmpty(token) || properties == null || StringUtils.isEmpty(properties.sipUri()))) {
@@ -863,6 +861,100 @@ public void playDTMF(String sessionId, String connectionId, String dtmfDigits) t
863861
client.playDtmfSingle(sessionId, connectionId, dtmfDigits);
864862
}
865863

864+
/**
865+
* Starts an Experience Composer render for an OpenTok session. For more information, see the
866+
* <a href="https://tokbox.com/developer/guides/experience-composer">Experience Composer developer guide</a>.
867+
*
868+
* @param sessionId The session ID.
869+
* @param properties The {@link RenderProperties} object defining the properties for the Render call.
870+
*
871+
* @return The {@link Render} response object.
872+
*
873+
* @throws OpenTokException
874+
*/
875+
public Render startRender(String sessionId, String token, RenderProperties properties) throws OpenTokException {
876+
if (StringUtils.isEmpty(sessionId) || StringUtils.isEmpty(token) || properties == null) {
877+
throw new InvalidArgumentException("Session id, token and properties are all required.");
878+
}
879+
String render = client.startRender(sessionId, token, properties);
880+
try {
881+
return renderReader.readValue(render);
882+
} catch (JsonProcessingException e) {
883+
throw new RequestException("Exception mapping json: " + e.getMessage());
884+
}
885+
}
886+
887+
/**
888+
* Gets a Render object, with details on an Experience Composer.
889+
*
890+
* @param renderId The ID of the Experience Composer to retrieve.
891+
*
892+
* @return The {@link Render} response object associated with the provided ID.
893+
*
894+
* @throws OpenTokException
895+
*/
896+
public Render getRender(String renderId) throws OpenTokException {
897+
if (StringUtils.isEmpty(renderId)) {
898+
throw new InvalidArgumentException("Render id is required.");
899+
}
900+
String render = client.getRender(renderId);
901+
try {
902+
return renderReader.readValue(render);
903+
} catch (JsonProcessingException e) {
904+
throw new RequestException("Exception mapping json: " + e.getMessage());
905+
}
906+
}
907+
908+
/**
909+
* Stops an Experience Composer of an OpenTok session. Note that by default
910+
* Experience Composers automatically stop 2 hours after they are started. You can also set a different
911+
* maxDuration value when you create the Experience Composer. When the Experience Composer ends, an event is
912+
* posted to the callback URL, if you have configured one for the project.
913+
*
914+
* @param renderId The ID of the Experience Composer to stop.
915+
*
916+
* @throws OpenTokException
917+
*/
918+
public void stopRender(String renderId) throws OpenTokException {
919+
if (StringUtils.isEmpty(renderId)) {
920+
throw new InvalidArgumentException("Render id is required.");
921+
}
922+
client.stopRender(renderId);
923+
}
924+
925+
/**
926+
* Gets a list of Render objects, representing Experience Composers associated with the
927+
* OpenTok project.
928+
*
929+
* @return The list of {@link Render} objects.
930+
*
931+
* @throws OpenTokException
932+
*/
933+
public List<Render> listRenders() throws OpenTokException {
934+
return listRenders(null, null);
935+
}
936+
937+
/**
938+
* Gets a list of Render objects, representing a list of Experience Composers associated
939+
* with the OpenTok project.
940+
*
941+
* @param offset (optional) Start offset in the list of existing Renders.
942+
* @param count (optional) Number of Renders to retrieve starting at offset. Maximum 1000.
943+
*
944+
* @return The list of {@link Render} objects.
945+
*
946+
* @throws OpenTokException
947+
*/
948+
public List<Render> listRenders(Integer offset, Integer count) throws OpenTokException {
949+
String response = client.listRenders(offset, count);
950+
try {
951+
JsonNode root = new ObjectMapper().readTree(response);
952+
return renderListReader.readValue(root.get("items"));
953+
} catch (IOException e) {
954+
throw new RequestException("Exception mapping json: " + e.getMessage());
955+
}
956+
}
957+
866958
/**
867959
* Used to create an OpenTok object with advanced settings. You can set
868960
* the request timeout for API calls and a proxy to use for API calls.

src/main/java/com/opentok/Render.java

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/**
2+
* OpenTok Java SDK
3+
* Copyright (C) 2022 Vonage.
4+
* http://www.tokbox.com
5+
*
6+
* Licensed under The MIT License (MIT). See LICENSE file for more information.
7+
*/
8+
package com.opentok;
9+
10+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
11+
import com.fasterxml.jackson.annotation.JsonProperty;
12+
13+
/**
14+
* Represents an Experience Composer element response.
15+
*/
16+
@JsonIgnoreProperties(ignoreUnknown = true)
17+
public class Render {
18+
@JsonProperty private String id;
19+
@JsonProperty private String sessionId;
20+
@JsonProperty private String projectId;
21+
@JsonProperty private long createdAt;
22+
@JsonProperty private long updatedAt;
23+
@JsonProperty private String url;
24+
@JsonProperty private String resolution;
25+
@JsonProperty private RenderStatus status;
26+
@JsonProperty private String streamId;
27+
@JsonProperty private String reason;
28+
29+
protected Render() {}
30+
31+
/**
32+
* The Render ID.
33+
*/
34+
public String getId() {
35+
return id;
36+
}
37+
38+
/**
39+
* The Session ID.
40+
*/
41+
public String getSessionId() {
42+
return sessionId;
43+
}
44+
45+
/**
46+
* The Project ID.
47+
*/
48+
public String getProjectId() {
49+
return projectId;
50+
}
51+
52+
/**
53+
* The time the Experience Composer started, expressed in milliseconds since the Unix epoch.
54+
*/
55+
public long getCreatedAt() {
56+
return createdAt;
57+
}
58+
59+
/**
60+
* This timestamp matches the createdAt timestamp when calling {@link OpenTok#getRender(String)}.
61+
*/
62+
public long getUpdatedAt() {
63+
return updatedAt;
64+
}
65+
66+
/**
67+
* A publicly reachable URL controlled by the customer and capable of generating the content to be rendered
68+
* without user intervention.
69+
*/
70+
public String getUrl() {
71+
return url;
72+
}
73+
74+
/**
75+
* The resolution of the Experience Composer (either "640x480", "1280x720", "480x640", or "720x1280").
76+
*/
77+
public String getResolution() {
78+
return resolution;
79+
}
80+
81+
/**
82+
* The status of the Experience Composer.
83+
*/
84+
public RenderStatus getStatus() {
85+
return status;
86+
}
87+
88+
/**
89+
* The ID of the composed stream being published. The streamId is not available when the status is "starting"
90+
* and may not be available when the status is "failed".
91+
*/
92+
public String getStreamId() {
93+
return streamId;
94+
}
95+
96+
/**
97+
* The reason field is only available when the status is either "stopped" or "failed". If the status is stopped,
98+
* the reason field will contain either "Max Duration Exceeded" or "Stop Requested." If the status is failed, the
99+
* reason will contain a more specific error message.
100+
*/
101+
public String getReason() {
102+
return reason;
103+
}
104+
}

0 commit comments

Comments
 (0)