The OpenTok Java SDK provides methods for:
- Generating sessions and tokens for OpenTok applications
- Working with OpenTok archives
- Working with OpenTok live streaming broadcasts
- Working with OpenTok SIP interconnect
- Sending signals to clients connected to a session
- Disconnecting clients from sessions
- Forcing clients in a session to disconnect or mute published audio
- Working with Experience Composers
- Working with Audio Connectors
This library is designed to work with the Tokbox/OpenTok platform, part of the Vonage Video API. If you are looking to use the Vonage Video API and using the Vonage Customer Dashboard, you will want to install the Vonage Server SDK for Java, which includes support for the Vonage Video API.
Not sure which exact platform you are using? Take a look at this guide.
If you are using the Tokbox platform, do not worry! The Tokbox platform is not going away, and this library will continue to be updated. While we encourage customers to check out the new Unified platform, there is no rush to switch. Both platforms run the exact same infrastructure and capabilities, with the main difference is a unified billing interface and easier access to Vonage’s other CPaaS APIs.
If you are new to the Vonage Video API, head on over to the Vonage Customer Dashboard to sign up for a developer account and check out the Vonage Server SDK for Java.
The Maven Central repository helps manage dependencies for JVM based projects. It can be used via several build tools, including Maven and Gradle.
When you use Maven as your build tool, you can manage dependencies in the pom.xml
file:
<dependency>
<groupId>com.tokbox</groupId>
<artifactId>opentok-server-sdk</artifactId>
<version>4.15.0</version>
</dependency>
When you use Gradle as your build tool, you can manage dependencies in the build.gradle
file:
dependencies {
compile group: 'com.tokbox', name: 'opentok-server-sdk', version: '4.15.0'
}
Download the jar file for the latest release from the Releases page. Include it in the classpath for your own project by using the JDK directly or in your IDE of choice.
Import the required classes in any class where it will be used. Then initialize a com.opentok.OpenTok
object with your own API Key and API Secret.
import com.opentok.OpenTok;
// inside a class or method...
int apiKey = 000000; // YOUR API KEY
String apiSecret = "YOUR API SECRET";
OpenTok opentok = new OpenTok(apiKey, apiSecret)
You can use OpenTok.Builder
to set advanced options. This class
includes the following methods:
-
.requestTimeout(int)
-- Call this to specify the timeout for HTTP requests (in seconds). The default timeout is 60 seconds. -
.proxy(Proxy)
-- Using ajava.net.Proxy
object, you can configure a proxy server that the HTTP client will use when call the OpenTok REST API.
Call the OpenTok.Builder()
constructor, passing in your API key and secret,
to instantiate an OpenTok.Builder
object. Then call the requestTimeout()
or proxy()
methods (or both). Then call the build()
method to return an
OpenTok object.
For example, the following code instantiates an OpenTok object, with the default timeout set to 10 seconds:
int apiKey = 12345; // YOUR API KEY
String apiSecret = "YOUR API SECRET";
int timeout = 10;
OpenTok opentok = new OpenTok.Builder(apiKey, apiSecret)
.requestTimeout(timeout)
.build();
Make sure you call the OpenTok.close()
method when you are done,
to prevent leaked file descriptors:
opentok.close();
To create an OpenTok Session, use the OpenTok
instance’s createSession(SessionProperties properties)
method. The properties
parameter is optional and it is used to specify two things:
- Whether the session uses the OpenTok Media Router
- A location hint for the OpenTok server.
- Whether the session is automatically archived.
An instance can be initialized using the com.opentok.SessionProperties.Builder
class.
The sessionId
property of the returned com.opentok.Session
instance, which you can read using
the getSessionId()
method, is useful to get an identifier that can be saved to a persistent store
(such as a database).
import com.opentok.MediaMode;
import com.opentok.ArchiveMode;
import com.opentok.Session;
import com.opentok.SessionProperties;
// A session that attempts to stream media directly between clients:
Session session = opentok.createSession();
// A session that uses the OpenTok Media Router:
Session session = opentok.createSession(new SessionProperties.Builder()
.mediaMode(MediaMode.ROUTED)
.build());
// A Session with a location hint:
Session session = opentok.createSession(new SessionProperties.Builder()
.location("12.34.56.78")
.build());
// A session that is automatically archived (it must used the routed media mode)
Session session = opentok.createSession(new SessionProperties.Builder()
.mediaMode(MediaMode.ROUTED)
.archiveMode(ArchiveMode.ALWAYS)
.build());
// Store this sessionId in the database for later use:
String sessionId = session.getSessionId();
Once a Session is created, you can start generating Tokens for clients to use when connecting to it.
You can generate a token either by calling an com.opentok.OpenTok
instance's
generateToken(String sessionId, TokenOptions options)
method, or by calling a com.opentok.Session
instance's generateToken(TokenOptions options)
method after creating it. The options
parameter
is optional and it is used to set the role, expire time, and connection data of the token. An
instance can be initialized using the TokenOptions.Builder
class.
import com.opentok.TokenOptions;
import com.opentok.Role;
// Generate a token from just a sessionId (fetched from a database)
String token = opentok.generateToken(sessionId);
// Generate a token by calling the method on the Session (returned from createSession)
String token = session.generateToken();
// Set some options in a token
String token = session.generateToken(new TokenOptions.Builder()
.role(Role.MODERATOR)
.expireTime((System.currentTimeMillis() / 1000L) + (7 * 24 * 60 * 60)) // in one week
.data("name=Johnny")
.build());
You can only archive sessions that use the OpenTok Media Router (sessions with the media mode set to routed).
You can start the recording of an OpenTok Session using a com.opentok.OpenTok
instance's
startArchive(String sessionId, String name)
method. This will return a com.opentok.Archive
instance.
The parameter name
is optional and used to assign a name for the Archive. Note that you can
only start an Archive on a Session that has clients connected.
import com.opentok.Archive;
// A simple Archive (without a name)
Archive archive = opentok.startArchive(sessionId, null);
// Store this archiveId in the database for later use
String archiveId = archive.getId();
You can also disable audio or video recording by calling the hasAudio(false)
or hasVideo(false)
methods of an ArchiveProperties
builder, and passing the built object into the
OpenTok.startArchive(String sessionId, ArchiveProperties properties)
method:
import com.opentok.Archive;
import com.opentok.ArchiveProperties;
// Start an audio-only archive
Archive archive = opentok.startArchive(sessionId, new ArchiveProperties.Builder()
.hasVideo(false)
.build());
// Store this archiveId in the database for later use
String archiveId = archive.getId();
Setting the output mode to Archive.OutputMode.INDIVIDUAL
setting causes each stream in the archive
to be recorded to its own individual file:
import com.opentok.Archive;
import com.opentok.ArchiveProperties;
Archive archive = opentok.startArchive(sessionId, new ArchiveProperties.Builder()
.outputMode(Archive.OutputMode.INDIVIDUAL)
.build());
// Store this archiveId in the database for later use
String archiveId = archive.getId();
The Archive.OutputMode.COMPOSED
option is the default value for outputMode
. It archives all streams to be recorded to a single (composed) file.
You can only specify the resolution
for composed archives using the ArchiveProperties
builder. If you set the resolution
property and also set the outputMode
property to Archive.OutputMode.INDIVIDUAL
, the method will throw an InvalidArgumentException
.
The accepted values for resolution
are:
"640x480"
(SD, the default)"1280x720"
(HD)Please note that setting any other value for the
resolution
property will result in an exception.
import com.opentok.ArchiveProperties;
ArchiveProperties properties = new ArchiveProperties.Builder().resolution("1280x720").build();
You can stop the recording of a started Archive using a com.opentok.Archive
instance's
stopArchive(String archiveId)
method.
// Stop an Archive from an archiveId (fetched from database)
Archive archive = opentok.stopArchive(archiveId);
To get an com.opentok.Archive
instance (and all the information about it) from an archiveId
, use
a com.opentok.OpenTok
instance's getArchive(String archiveId)
method.
Archive archive = opentok.getArchive(String archiveId);
To delete an Archive, you can call a com.opentok.OpenTok
instance's deleteArchive(String archiveId)
method.
// Delete an Archive from an archiveId (fetched from database)
opentok.deleteArchive(archiveId);
You can also get a list of all the Archives you've created (up to 1000) with your API Key. This is
done using a com.opentok.OpenTok
instance's listArchives(int offset, int count)
method. You may optionally
paginate the Archives you receive using the offset and count parameters. This will return a
List<Archive>
type. An InvalidArgumentException
will be thrown if the offset or count are
negative or if the count is greater than 1000.
// Get a list with the first 1000 archives created by the API Key
List<Archive> archives = opentok.listArchives();
// Get a list of the first 50 archives created by the API Key
List<Archive> archives = opentok.listArchives(0, 50);
// Get a list of the next 50 archives
List<Archive> archives = opentok.listArchives(50, 50);
You can also fetch the list of archives for a specific session ID , and optionally use the offset and count parameters as described above.
// Get a list with the first 1000 archives for a specific session)
ArchiveList archives = opentok.listArchives(sessionId);
// Get a list of the first 50 archives for a specific session
ArchiveList archives = sdk.listArchives(sessionId, 0, 50);
// Get a list of the next 50 archives for a specific session
ArchiveList archives = sdk.listArchives(sessionId, 50, 50);
Note that you can also create an automatically archived session, by passing ArchiveMode.ALWAYS
into the archiveMode()
method of the SessionProperties.Builder
object you use to build the
sessionProperties
parameter passed into the OpenTok.createSession()
method (see "Creating
Sessions," above).
For composed archives, you can dynamically set the archive layout (while the archive is being recorded) using the OpenTok.setArchiveLayout(String archiveId, ArchiveProperties properties)
method. See Customizing the video layout for composed
archives for more information. Use the ArchiveProperties
builder as follows:
ArchiveProperties properties = new ArchiveProperties.Builder()
.layout(new ArchiveLayout(ArchiveLayout.Type.VERTICAL))
.build();
opentok.setArchiveLayout(archiveId, properties);
For custom layouts the builder looks like:
ArchiveProperties properties = new ArchiveProperties.Builder()
.layout(new ArchiveLayout(ArchiveLayout.Type.CUSTOM, "stream { position: absolute; }"))
.build();
You can set the initial layout class for a client's streams by setting the layout
option when you create the token for the client, using the
OpenTok.generateToken(String sessionId, TokenOptions options)
method. And you can
also change the layout classes of a stream as follows:
StreamProperties streamProps = new StreamProperties.Builder()
.id(streamId)
.addLayoutClass("full")
.addLayoutClass("focus")
.build();
StreamListProperties properties = new StreamListProperties.Builder()
.addStreamProperties(streamProps)
.build();
opentok.setStreamLayouts(sessionId, properties);
If you want to change the layout of multiple streams, create a StreamProperties object for each stream, and add them to the StreamListProperties object as follows:
StreamListProperties properties = new StreamListProperties.Builder()
.addStreamProperties(streamProps1)
.addStreamProperties(streamProps2)
.build();
opentok.setStreamLayouts(sessionId, properties);
For more information on archiving, see the OpenTok archiving developer guide.
Your application server can disconnect a client from an OpenTok session by calling the forceDisconnect(sessionId, connectionId)
method of the com.opentok.OpenTok
instance.
opentok.forceDisconnect(sessionId, connectionId);
The connectionId
parameter is used to specify the connection ID of a client connection to the session.
For more information on the force disconnect functionality and exception codes, please see the REST API documentation.
You can force the publisher of a specific stream to stop publishing audio using the
Opentok.forceMuteStream(String sessionId, String streamId)
method.
You can force the publisher of all streams in a session (except for an optional list of streams)
to stop publishing audio using the Opentok.forceMuteAll(String sessionId, MuteAllProperties properties)
method. You can then disable the mute state of the session by calling the
Opentok.disableForceMute(String sessionId)
method.
For more information, see Muting the audio of streams in a session.
You can send signals to all the connections in a session or to a specific connection:
-
public void signal(String sessionId, SignalProperties props) throws OpenTokException , RequestException, InvalidArgumentException
-
public void signal(String sessionId, String connectionId, SignalProperties props) throws OpenTokException , RequestException , InvalidArgumentException
The SignalProperties
builder helps you to construct the signal data and type:
SignalProperties properties = new SignalProperties.Builder()
.type("test")
.data("This is a test string")
.build();
opentok.signal(sessionId, properties);
opentok.signal(sessionId, connectionId, properties);
Make sure that the type
string does not exceed the maximum length (128 bytes)
and the data
string does not exceed the maximum length (8 kB).
The SignalProperties
builder does not currently check for these limitations.
For more information on signaling and exception codes, refer to the documentation for the OpenTok signaling REST method.
You can broadcast OpenTok publishing streams to an HLS (HTTP live streaming) or to RTMP streams. To successfully start broadcasting a session, at least one client must be connected to the session. The live streaming broadcast can target one HLS endpoint and up to five RTMP servers simultaneously for a session. You can only start live streaming for sessions that use the OpenTok Media Router (with the media mode set to routed); you cannot use live streaming with sessions that have the media mode set to relayed. (See the OpenTok Media Router and media modes developer guide).
You can start a broadcast using the OpenTok.startBroadcast(sessionId, properties)
method,
where the properties
field is a BroadcastProperties
object. Initalize a BroadcastProperties
object as follows (see the Opentok Broadcast
REST method for more details):
BroadcastProperties properties = new BroadcastProperties.Builder()
.hasHls(true)
.addRtmpProperties(rtmpProps)
.addRtmpProperties(rtmpNextProps)
.maxDuration(1000)
.resolution("640x480")
.layout(layout)
.build();
// The Rtmp properties can be build using RtmpProperties as shown below
RtmpProperties rtmpProps = new RtmpProperties.Builder()
.id("foo")
.serverUrl("rtmp://myfooserver/myfooapp")
.streamName("myfoostream").build();
//The layout object is initialized as follows:
BroadcastLayout layout = new BroadcastLayout(BroadcastLayout.Type.PIP);
Finally, start a broadcast as shown below:
Broadcast broadcast = opentok.startBroadcast(sessionId, properties)
The Broadcast
object returned has the following info:
String broadcastId;
String sessionId;
int projectId;
long createdAt;
long updatedAt;
String resolution;
String status;
List<Rtmp> rtmpList = new ArrayList<>(); //not more than 5
String hls; // HLS url
// The Rtmp class mimics the RtmpProperties
To stop a broadcast use:
Broadcast broadcast = opentok.stopBroadcast(broadcastId);
To get more information about a live streaming broadcast, use:
Broadcast broadcast = opentok.getBroadcast(broadcastId);
The information returned is in the Broadcast
object and consists of HLS and/or Rtmp URLs,
along with the session ID, resolution, etc.
You can also change the layout of a live broadcast dynamically using:
opentok.setBroadcastLayout(broadcastId, properties);
//properties can be
BroadcastProperties properties = new BroadcastProperties.Builder()
.layout(new BroadcastLayout(BroadcastLayout.Type.VERTICAL))
.build();
To dynamically change the layout class of an individual stream, use
StreamProperties streamProps = new StreamProperties.Builder()
.id(streamId)
.addLayoutClass("full")
.addLayoutClass("focus")
.build();
StreamListProperties properties = new StreamListProperties.Builder()
.addStreamProperties(streamProps)
.build();
opentok.setStreamLayouts(sessionId, properties);
You can get information about a stream by calling the getStream(sessionId, streamId)
method
of the com.opentok.OpenTok
instance.
// Get stream info from just a sessionId (fetched from a database)
Stream stream = opentok.getStream(sessionId, streamId);
// Stream Properties
stream.getId(); // string with the stream ID
stream.getVideoType(); // string with the video type
stream.getName(); // string with the name
stream.layoutClassList(); // List with the layout class list
You can get information about all of the streams in a session by calling the listStreams(sessionId)
method of the com.opentok.OpenTok
instance.
// Get list of strems from just a sessionId (fetched from a database)
StreamList streamList = opentok.listStreams(sessionId);
streamList.getTotalCount(); // total count
You can add an audio-only stream from an external third party SIP gateway using the SIP Interconnect feature. This requires a SIP URI, the session ID you wish to add the audio-only stream to, and a token to connect to that session ID.
To connect your SIP platform to an OpenTok session, call the
OpenTok.dial(String sessionId, String token, SipProperties properties)
method.
The audio from your end of the SIP call is added to the OpenTok session as an audio-only stream.
The OpenTok Media Router mixes audio from other streams in the session and sends the mixed audio
to your SIP endpoint. The call ends when your SIP server sends a BYE message (to terminate
the call). You can also end a call using the OpenTok.forceDisconnect(sessionId, connectionId)
method to disconnect the SIP client from the session (see Disconnecting clients).
The OpenTok SIP gateway automatically ends a call after 5 minutes of inactivity (5 minutes without media received). Also, as a security measure, the OpenTok SIP gateway closes any SIP call that lasts longer than 6 hours.
The SIP interconnect feature requires that you use an OpenTok session that uses the OpenTok Media Router (a session with the media mode set to routed).
To connect an OpenTok session to a SIP gateway:
SipProperties properties = new SipProperties.Builder()
.sipUri("sip:[email protected];transport=tls")
.from("[email protected]")
.headersJsonStartingWithXDash(headerJson)
.userName("username")
.password("password")
.secure(true)
.build();
Sip sip = opentok.dial(sessionId, token, properties);
You can start an Experience Composer
by calling the OpenTok.startRender(String sessionId, String token, RenderProperties properties)
method:
RenderProperties properties = new RenderProperties.Builder()
.url("http://example.com/path-to-page/")
.build();
Render render = opentok.startRender(sessionId, token, properties);
You can stop an Experience Composer by calling the OpenTok.stopRender(String renderId)
method.
You can get information about Experience Composers by calling the OpenTok.getRender(String renderId)
,
OpenTok.listRenders()
or OpenTok.listRenders(Integer offset, Integer count)
methods.
You can start an Audio Connector stream
by calling the OpenTok.connectAudioStream(String sessionId, String token, AudioConnectorProperties properties)
method:
AudioConnectorProperties properties = new AudioConnectorProperties.Builder("wss://service.com/ws-endpoint")
.addStreams("streamId-1", "streamId-2")
.addHeader("X-CustomHeader-Key", "headerValue")
.build();
AudioConnector ac = opentok.connectAudioStream(sessionId, token, properties);
There are two sample applications included with the SDK. To get going as fast as possible, clone the whole repository and follow the Walkthroughs:
Reference documentation is available at https://tokbox.com/developer/sdks/java/reference/index.html.
You need an OpenTok API key and API secret, which you can obtain by logging into your Vonage Video API account.
The OpenTok Java SDK requires JDK 8 or greater to compile. Runtime requires Java SE 8 or greater. This project is tested on both OpenJDK and Oracle implementations.
For Java 7 please use OpenTok Java SDK v3.
See the Releases page for details about each release.
Changes in v2.2.1:
The default setting for the createSession()
method is to create a session with the media mode set
to relayed. In previous versions of the SDK, the default setting was to use the OpenTok Media Router
(with the media mode set to routed in v2.2.0, or with p2p.preference="disabled" in previous
versions). In a relayed session, clients will attempt to send streams directly between each other
(peer to peer); and if clients cannot connect due to firewall restrictions, the session uses the
OpenTok TURN server to relay audio-video streams.
Changes in v2.2.0:
This version of the SDK includes support for working with OpenTok archives.
This version of the SDK includes a number of improvements in the API design. These include a number of API changes. See the OpenTok 2.2 SDK Reference for details on the new API.
The API_Config class has been removed. Store your OpenTok API key and API secret in code outside of the SDK files.
The create_session()
method has been renamed createSession()
. Also, the method has changed to
take one parameter: a SessionProperties object. You now generate a SessionProperties object using a Builder pattern.
The generate_token()
method has been renamed generateToken()
. Also, the method has changed to
take two parameters: the session ID and a TokenOptions object.
Interested in contributing? We ❤️ pull requests! See the Development and Contribution guidelines.
We love to hear from you so if you have questions, comments or find a bug in the project, let us know! You can either:
- Open an issue on this repository
- See https://support.tokbox.com/ for support options
- Tweet at us! We're @VonageDev on Twitter
- Or join the Vonage Developer Community Slack