Java Server SDK

The Vonage Java SDK provides methods for:

Installation

Maven Central:

The best way to add the Vonage Java Server SDK to your project is to add the dependency to your project build system. Instructions can be found on the GitHub repo as well as Maven Central for Maven, Gradle, Ivy, SBT, Leiningen etc.

Maven

When you use Maven as your build tool, you can manage dependencies in the pom.xml file:

<dependency>
    <groupId>com.vonage</groupId>
    <artifactId>server-sdk</artifactId>
    <version>8.15.1</version>
</dependency>

Gradle

When you use Gradle as your build tool, you can manage dependencies in the build.gradle file:

dependencies {
  implementation 'com.vonage:server-sdk:8.15.1'
}

Usage

The Vonage Java SDK allows you to use Vonage REST APIs using its subclients, one for each API. To work with the Video API, use the com.vonage.client.video.VideoClient class. This contains methods for all of the supported endpoints in the API specification. You can obtain this by calling the getVideoClient() method of VonageClient.

Initializing

Initialize a com.vonage.client.VonageClient object with your Video Application ID and private key. This returns an object with all the methods needed to work with the video API.

import com.vonage.client.VonageClient;
import com.vonage.client.video.*;

// Inside a class or method...
VideoClient videoClient = VonageClient.builder()
    .applicationId("APP_ID")
    .privateKeyPath("/path/to/private.key")
    .build().getVideoClient();

Generating Tokens

Your Vonage Video application will need a token on the client side to be useful. This token can be generated by the server SDK via the VideoClient#generateToken(String sessionId, TokenOptions options) method. You will need to pass in the session ID, but the options parameter is not mandatory (it can be null, or you can call the VideoClient#generateToken(String sessionId) for convenience). The method will return a signed JWT with the appropriate claims, as a Base64-encoded string which you can pass to the client.

String jwt = videoClient.generateToken(sessionId);

By default, the token will have an expiration time of 24 hours and the role will be set to "publisher" (com.vonage.video.client.Role#PUBLISHER). The maximum permitted expiration time is 30 days. You can set these using the TokenOptions parameter, which uses the builder pattern. You can also set the connection metadata, but this cannot exceed 1000 characters.

TokenOptions tokenOptions = TokenOptions.builder()
        .expiryLength(Duration.ofHours(6))
        .role(Role.SUBSCRIBER)
        .build();
String jwt = videoClient.generateToken(sessionId, tokenOptions);

See the token creation guide for a more detailed explanation of the configuration options.

Creating Sessions

To create a Vonage Video Session, use the VideoClient#createSession(CreateSessionRequest request) method. The request parameter is optional and it is used to specify:

  • Whether the session uses the Vonage Video Media Router
  • A location hint for the Vonage Video server.
  • Whether the session is automatically archived.

As with most other request properties, the builder pattern is used. To instantiate, start with the static builder() method, set the properties and call build() to construct an instance.

If the request was successful, a CreateSessionResponse is returned. The most useful property is the session ID, which can be obtained by calling the getSessionId() method. You may want to persist the session ID for future use, as it is a common parameter for other method calls.

// A session that attempts to stream media directly between clients:
CreateSessionResponse session = videoClient.createSession();

// A session that uses the Vonage Video Media Router:
CreateSessionResponse session = videoClient.createSession(
    CreateSessionRequest.builder().mediaMode(MediaMode.ROUTED).build()
);

// A Session with a location hint:
CreateSessionResponse session = videoClient.createSession(
    CreateSessionRequest.builder().location("12.34.56.78").build()
);

// A session that is automatically archived (it must used the routed media mode)
CreateSessionResponse session = videoClient.createSession(
    CreateSessionRequest.builder()
      .mediaMode(MediaMode.ROUTED)
      .archiveMode(ArchiveMode.ALWAYS)
      .build()
);

// Store this sessionId in the database for later use:
String sessionId = session.getSessionId();

Working with Archives

You can only archive sessions that use the Vonage Video Media Router (i.e. sessions with the media mode set to MediaMode.ROUTED). For more information on archiving, see the Vonage Video archiving developer guide.

Create Archive

You can manually start the recording of a Vonage Video Session using the createArchive(Archive request) method. If successful, this will populate additional properties in the com.vonage.client.video.Archive instance with the server's response.

Note that you can only start an Archive on a Session that has clients connected. The Archive request follows the builder pattern for construction. All properties except the session ID are optional, hence the Archive.builder(String sessionId) method requires this parameter.

// A simple Archive with the default property values
Archive archive = videoClient.createArchive(Archive.builder(sessionId).build());

// Store this archiveId in the database for later use
UUID archiveId = archive.getId();

You can also disable audio or video recording by calling the hasAudio(false) or hasVideo(false) methods of an Archive builder.

// Audio-only archive
Archive.builder(sessionId).hasVideo(false).hasAudio(true).build();

Setting the output mode to OutputMode.INDIVIDUAL causes each stream in the archive to be recorded to its own individual file:

Archive.builder(sessionId).outputMode(OutputMode.INDIVIDUAL).name("My recording").build();

The 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. If you set the resolution property and also set the outputMode property to OutputMode.INDIVIDUAL, the build() method will throw an IllegalStateException.

// Set the archive resolution to 1280x720
Archive.builder(sessionId).resolution(Resolution.HD_LANDSCAPE).build();

Stop Recording

You can stop the recording of a started Archive using the VideoClient#stopArchive(String archiveId) method.

// Stop an Archive
Archive archive = videoClient.stopArchive(archiveId);

Delete an Archive

To delete an Archive, use the VideoClient#deleteArchive(String archiveId) method.

// Delete an Archive
videoClient.deleteArchive(archiveId);

Retrieve a single Archive

To get an individual Archive instance (and all the information about it) from an archive ID, use the VideoClient#getArchive(String archiveId) method.

// Retrieve archive info
Archive archive = videoClient.getArchive(archiveId);

Retrieve multiple Archives

You can get a list of all the Archives you've created (up to 1000) within your application using the VideoClient#listArchives() method. To filter the returned results, call the VideoClient#listArchives(ListArchivesRequest request) method instead. The request object is constructed using the builder pattern and has three optional parameters:

  • sessionId: allows you to limit the results to archives associated with a specific session.
  • count: limits the number of returned results.
  • offset: discards an initial number of results (useful for when there are more than 1000 archives).

An IllegalArgumentException will be thrown if the offset or count are negative or if the count is greater than 1000. The resulting list of Archives will be in date/time order, from newest to oldest.

// Get a list with the first 1000 archives
List<Archive> archives = videoClient.listArchives();

// Get a list of the first 50 archives created
List<Archive> archives = videoClient.listArchives(
    Archive.builder().count(50).build()
);

// Get a list of the next 50 archives
List<Archive> archives = videoClient.listArchives(
    Archive.builder().offset(50).count(50).build()
);

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
List<Archive> archives = videoClient.listArchives(
    ListStreamCompositionsRequest.builder().sessionId(sessionId).build()
);

// Get a list of the next 1000 archives for a specific session
List<Archive> archives = videoClient.listArchives(
    ListStreamCompositionsRequest.builder()
      .offset(1000)
      .sessionId(sessionId)
      .build()
);

Set Archive layout

For composed archives, you can dynamically set the archive layout (while the archive is being recorded) using the VideoClient#setArchiveLayout(String archiveId, ArchiveLayout layout) method.

You can also set the layout when creating the archive (see Archive.Builder#layout(ArchiveLayout layout)). See Customizing the video layout for composed archives for more information.

Use the ArchiveProperties builder as follows:

StreamCompositionLayout layout = StreamCompositionLayout.builder(ScreenLayoutType.VERTICAL).build();
videoClient.updateArchiveLayout(archiveId, layout);

For custom layouts, you must specify the stylesheet (in CSS) as well:

StreamCompositionLayout layout = StreamCompositionLayout.builder(ScreenLayoutType.CUSTOM)
    .stylesheet("stream { position: absolute; }")
    .build();

You can also set the layout type when screensharing, but the initial layout must be set to ScreenLayoutType.BEST_FIT:

StreamCompositionLayout layout = StreamCompositionLayout.builder(ScreenLayoutType.BEST_FIT)
    .screenshareType(ScreenLayoutType.PIP)
    .build();

Add Stream to an Archive

You can add a stream to a composed archive that was started with the streamMode set to StreamMode.MANUAL using the VideoClient#addArchiveStream(String archiveId, String streamId) method, passing in the Archive ID and stream ID you wish to add to the archive, respectively.

The VideoClient#addArchiveStream(String archiveId, String streamId, Boolean audio, Boolean video) variant of this method allows you to enable or disable audio and video.

By default, both are enabled (i.e. true).Passing in false for the audio parameter will disable audio, passing false for video will disable video (resulting in an audio-only stream). Setting either of these values to null is equivalent to the default (i.e. true in both cases).

// Add stream to archive
videoClient.addArchiveStream(archiveId, streamId);

// Add stream to archive without audio
videoClient.addArchiveStream(archiveId, streamId, false, true);

// Add stream to archive without video
videoClient.addArchiveStream(archiveId, streamId, true, false);

Remove a Stream from an Archive

You can remove a stream from a composed archive using the VideoClient#removeArchiveStream(String archiveId, String streamId) method. As with adding a stream, the archive must have been started with streamMode set to "manual".

videoClient.removeArchiveStream(archiveId, streamId);

Working with Broadcasts

Working with live Broadcasts is very similar to working with Archives

List all live Broadcasts

List<Broadcast> broadcasts = videoClient.listBroadcasts();

Get details about a specific Broadcast

Broadcast broadcast = videoClient.getBroadcast(broadcastId);

Start a live streaming Broadcast

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. Session ID is required and at least one output stream (RTMP and/or HLS) should be specified.

Broadcast broadcast = videoClient.createBroadcast(
		Broadcast.builder(sessionId)
            .hls(Hls.builder().lowLatency(true).build())
            .resolution(Resolution.HD_LANDSCAPE)
		    .streamMode(StreamMode.MANUAL)
            .layout(StreamCompositionLayout.builder(ScreenLayoutType.BEST_FIT)
                    .screenshareType(ScreenLayoutType.PIP)
                    .build()
            )
            .maxDuration(Duration.ofMinutes(45))
        .build()
);

Stop a Broadcast recording

Broadcast broadcast = videoClient.stopBroadcast(broadcastId);

Dynamically changing the layout type of a live streaming Broadcast

videoClient.updateBroadcastLayout(broadcastId,
		StreamCompositionLayout.builder(ScreenLayoutType.HORIZONTAL).build()
);

Add or remove stream in a live streaming Broadcast

Change the streams included in a broadcast that was started with the streamMode set to SteamMode.MANUAL:

videoClient.addBroadcastStream(broadcastId, streamId);
videoClient.removeBroadcastStream(broadcastId, streamId);

Working with Streams

You can get information about a stream by calling the VideoClient#getStream(String sessionId, String streamId) method. If the request was successful, a com.vonage.client.video.GetStreamResponse instance will be returned, which can be used to query the properties of interest pertaining to the stream.

GetStreamResponse stream = videoClient.getStream(sessionId, streamId);

// Stream Properties
VideoType videoType = stream.getVideoType();
String name = stream.getName();
List<String> layoutClassList = stream.layoutClassList();

You can get information about all of the streams in a session using the VideoClient#listStreams(String sessionId) method. This will return a List of GetStreamResponse instances, which you can traverse to find the information you're looking for.

// Get list of streams from a session ID
List<GetStreamResponse> streams = videoClient.listStreams(sessionId);
int count = streams.size();

// Get stream ID for a given stream name
UUID myStreamId = streams.stream()
    .filter(s -> "My Stream".equals(s.getName()))
    .findFirst().ifPresent(GetStreamResponse::getId)
    .orElseThrow(() -> new IllegalStateException(
          "Could not find stream in session "+sessionId
    ));

Set Stream Layout

You can change the layout classes of a stream using the VideoClient#setStreamLayout(String sessionId, List<SessionStream> streams) method. This takes as input the session ID and the list of streams to change. Each stream is represented by a SessionStream object, which is constructed using the builder pattern, with the stream ID being used to identify the stream (this is a mandatory parameter). Use the SessionStream.Builder#layoutClassList(List<String> layoutClassList) method to set the layouts for the stream (or the varargs variant for convenience). To demonstrate, suppose we have two streams, let's call them stream1 and stream2. Assume stream1Id and stream2Id are strings with the IDs of stream1 and stream2 respectively, and want to set stream1's layout classes to full and focus, but stream2's to min.

Here's how that can be achieved:

SessionStream
    stream1 = SessionStream.builder(stream1Id)
        .layoutClassList("full", "focus").build(),
    stream2 = SessionStream.builder(stream2Id)
        .layoutClassList("min").build();

videoClient.setStreamLayout(sessionId, stream1, stream2);

Moderation

Disconnecting Clients

Your application server can disconnect a client from a Vonage Video session by calling the VideoClient#forceDisconnect(String sessionId, String connectionId) method.

videoClient.forceDisconnect(sessionId, connectionId);

The connectionId parameter is used to specify the connection ID of a client connected to the session.

For more information on the force disconnect functionality and exception codes, please see the REST API documentation.

Forcing clients in a session to mute published audio

You can force the publisher of a specific stream to stop publishing audio using the VideoClient#muteStream(String sessionId, String streamId) method.

videoClient.muteStream(sessionId, streamId);

You can force the publisher of all streams in a session (except for an optional list of streams) to stop publishing audio using the VideoClient#muteSession(String sessionId, boolean active, String... excludedStreamIds) method. The active parameter determines whether existing and new streams will be muted by default. The optional excludedStreamIds parameter allows you to pass in the streams to exclude from this mute request.

videoClient.muteSession(sessionId, true);

For more information, see Muting the audio of streams in a session.

Signaling

You can send signals to all the participants in a session using the VideoClient#signalAll(String sessionId, SignalRequest request) method. To signal a specific participant, use the VideoClient#signal(String sessionId, String connectionId, SignalRequest request) method instead.

The SignalRequest class (constructed using the builder pattern) has two fields: type and data, both of which are mandatory. These correspond to the type and data parameters passed in the client signal received handlers. 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).

SignalRequest signal = SignalRequest.builder()
    .type("chat")
    .data("Hello, World!")
    .build();

// Signal all connections in the session
videoClient.signalAll(sessionId, signal);

// Signal a specific connection in the session
videoClient.signal(sessionId, connectionId, signal);

For more information on signaling and exception codes, refer to the REST API specification.

SIP

Connect your SIP platform to a Vonage video session using the VideoClient#sipDial(SipDialRequest request) method. You must provide the URI, sessionId and token in the request. You can specify whether the negotiation between Vonage and the SIP endpoint will be done securely (using TLS) by setting the secure parameter of SipDialRequest.Builder#uri(URI uri, boolean secure) to true. You can also optionally specify a username and password for authentication in the request.

SipDialRequest request = SipDialRequest.builder()
	.uri(URI.create("sip:user@sip.partner.com"), false)
	.sessionId(sessionId).token(token).build();

SipDialResponse parsed = videoClient.sipDial(request);

You can play DTMF tones to all participants in a call using the VideoClient#sendDtmf(String sessionId, String digits) method. To send tones to a specific participant only, use the VideoClient#sendDtmf(String sessionId, String connectionId, String digits) method instead.

String digits = "*0123456789#";
// Send to all participants in the session
videoClient.sendDtmf(sessionId, digits);

// Send to a specific participant
videoClient.sendDtmf(sessionId, connectionId, digits);

Requirements

You need a Vonage Video App ID and private key, which you can obtain by logging into your Vonage Video API account.

The Vonage Java SDK requires JDK 8 or greater to compile. Runtime requires Java SE 8 or greater.

Release Notes

See the Releases page for details about each release.