Java Server SDK
O SDK Java da Vonage oferece métodos para:
- Gerando fichas
- Criando sessões
- Moderação de usuários nas sessões
- Gerenciamento arquivos
- Gerenciamento transmissões ao vivo
- Trabalhando com correntes
- Envio de sinais aos clientes conectados a uma sessão
- Interagindo com chamadas via SIP
Instalação
A Video API foi adicionada na versão 8.0.0 do SDK em 2023; no entanto, recomenda-se usar a versão mais recente por motivos de segurança, correções de bugs e recursos adicionados em versões posteriores.
Maven Central:
A melhor maneira de incluir o SDK do Servidor Java da Vonage no seu projeto é adicionar a dependência ao sistema de compilação do seu projeto. As instruções podem ser encontradas na Repositório do GitHub além de Maven Central para Maven, Gradle, Ivy, SBT, Leiningen etc.
Maven
Ao usar o Maven como ferramenta de compilação, você pode gerenciar as dependências no pom.xml arquivo:
<dependency>
<groupId>com.vonage</groupId>
<artifactId>server-sdk</artifactId>
<version>9.3.1</version>
</dependency>
Gradle
Ao usar o Gradle como ferramenta de compilação, você pode gerenciar as dependências no build.gradle arquivo:
dependencies {
implementation 'com.vonage:server-sdk:9.+'
}
Uso
O SDK Java da Vonage permite que você utilize APIs REST da Vonage utilizando seus subclientes, um para cada API. Para trabalhar com o Video API, use o com.vonage.client.video.VideoClient classe. Ela contém métodos para todos os endpoints suportados na especificação da API. É possível obtê-la chamando o getVideoClient() método de VonageClient.
Inicializando
Inicializar um com.vonage.client.VonageClient objeto com seu ID do aplicativo de vídeo e sua chave privada. Isso retorna um objeto com todos os métodos necessários para trabalhar com a 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();
Geração de tokens
Para funcionar, seu aplicativo Vonage Video precisará de um token no lado do cliente. Esse token pode ser gerado pelo SDK do servidor por meio do VideoClient#generateToken(String sessionId, TokenOptions options) método. Você precisará passar o ID da sessão, mas o options o parâmetro não é obrigatório (pode ser nulo, ou você pode chamar o VideoClient#generateToken(String sessionId) (por conveniência). O método retornará um JWT assinado com as reivindicações apropriadas, na forma de uma string codificada em Base64, que você poderá passar para o cliente.
String jwt = videoClient.generateToken(sessionId);
Por padrão, o token terá um prazo de validade de 24 horas e a função será definida como “publisher” (com.vonage.video.client.Role#PUBLISHER). O prazo máximo permitido é de 24 horas. Você pode definir esses valores usando o TokenOptions parâmetro, que utiliza o padrão builder. Também é possível definir os metadados da conexão, mas eles não podem exceder 1.000 caracteres.
TokenOptions tokenOptions = TokenOptions.builder()
.expiryLength(Duration.ofHours(6))
.role(Role.SUBSCRIBER)
.build();
String jwt = videoClient.generateToken(sessionId, tokenOptions);
Veja o guia para a criação de tokens para obter uma explicação mais detalhada das opções de configuração.
Criação de sessões
Para criar uma sessão de vídeo da Vonage, use o VideoClient#createSession(CreateSessionRequest request) método. O request O parâmetro é opcional e é usado para especificar:
- Se a sessão utiliza o Vonage Video Media Router
- Uma sugestão de localização para o servidor do Vonage Video.
- Se a sessão é arquivada automaticamente.
Assim como na maioria das outras propriedades de solicitação, utiliza-se o padrão builder. Para instanciá-lo, comece com o método estático builder() método, definir as propriedades e chamar build() para criar uma instância.
Se a solicitação foi bem-sucedida, um CreateSessionResponse é retornado. A propriedade mais útil é o ID da sessão, que pode ser obtido chamando o getSessionId() método. Talvez seja interessante salvar o ID da sessão para uso futuro, já que ele é um parâmetro comum em outras chamadas de método.
// 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 be used for 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();
Trabalhando com arquivos
Só é possível arquivar sessões que utilizem o Vonage Video Media Router (ou seja, sessões com o modo de mídia definido como MediaMode.ROUTED).
Para obter mais informações sobre arquivamento, consulte o Arquivamento de vídeos do Vonage guia do desenvolvedor.
Criar arquivo
Você pode iniciar manualmente a gravação de uma sessão de vídeo da Vonage usando o createArchive(Archive request) método. Se for bem-sucedido, isso preencherá propriedades adicionais no com.vonage.client.video.Archive instância com a resposta do servidor.
Observe que só é possível iniciar um arquivamento em uma sessão que tenha clientes conectados.
O Archive A solicitação segue o padrão “builder” para sua construção. Todas as propriedades, exceto o ID da sessão, são opcionais; por isso, o Archive.builder(String sessionId) O método exige esse parâmetro.
// 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();
Você também pode desativar a gravação de áudio ou vídeo chamando a função hasAudio(false) ou hasVideo(false) métodos de um Archive construtor.
// Audio-only archive
Archive.builder(sessionId).hasVideo(false).hasAudio(true).build();
Definir o modo de saída como OutputMode.INDIVIDUAL faz com que cada fluxo no arquivo seja gravado em seu próprio arquivo individual:
Archive.builder(sessionId).outputMode(OutputMode.INDIVIDUAL).name("My recording").build();
O OutputMode.COMPOSED essa opção é o valor padrão para outputMode. Ele arquiva todos os fluxos a serem gravados em um único arquivo (composto).
Você só pode especificar o resolution para arquivos compostos. Se você definir o resolution propriedade e também definir o outputMode propriedade para OutputMode.INDIVIDUAL, o build() O método lançará uma IllegalStateException.
// Set the archive resolution to 1280x720
Archive.builder(sessionId).resolution(Resolution.HD_LANDSCAPE).build();
Parar a gravação
Você pode interromper a gravação de um arquivo já iniciado usando o VideoClient#stopArchive(String archiveId) método.
// Stop an Archive
Archive archive = videoClient.stopArchive(archiveId);
Excluir um arquivo
Para excluir um arquivo, use o VideoClient#deleteArchive(String archiveId) método.
// Delete an Archive
videoClient.deleteArchive(archiveId);
Recuperar um único arquivo
Para conseguir uma pessoa Archive instância (e todas as informações a respeito dela) a partir de um ID de arquivo, use o VideoClient#getArchive(String archiveId) método.
// Retrieve archive info
Archive archive = videoClient.getArchive(archiveId);
Recuperar vários arquivos
Você pode obter uma lista de todos os arquivos que criou (até 1.000) em seu aplicativo usando o VideoClient#listArchives() método. Para filtrar os resultados retornados, chame o VideoClient#listArchives(ListArchivesRequest request) método, em vez disso.
O objeto request é construído usando o padrão builder e possui três parâmetros opcionais:
sessionId: permite limitar os resultados aos arquivos associados a uma sessão específica.count: limita o número de resultados retornados.offset: descarta um número inicial de resultados (útil quando há mais de 1.000 arquivos).
Um IllegalArgumentException será gerada se o offset ou count são negativos ou se o count é maior que 1000.
A lista resultante de Archiveserá em data/hora ordem, do mais recente ao mais antigo.
// 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()
);
Você também pode obter a lista de arquivos de uma ID de sessão específica e, opcionalmente, usar os parâmetros offset e count, conforme descrito acima.
// 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()
);
Definir o layout do arquivo
Para arquivos compostos, é possível definir dinamicamente o layout do arquivo (enquanto ele está sendo gravado) usando o VideoClient#setArchiveLayout(String archiveId, ArchiveLayout layout) método.
Você também pode definir o layout ao criar o arquivo (consulte Archive.Builder#layout(ArchiveLayout layout)). Veja Personalização do layout do vídeo para arquivos compostos para mais informações.
Use o ArchiveProperties gerador da seguinte forma:
StreamCompositionLayout layout = StreamCompositionLayout.standardLayout(ScreenLayoutType.VERTICAL);
videoClient.updateArchiveLayout(archiveId, layout);
Para layouts personalizados, é necessário especificar a folha de estilo (em CSS):
StreamCompositionLayout layout = StreamCompositionLayout.customLayout("stream { position: absolute; }")
Você também pode definir o tipo de layout ao compartilhar a tela, sendo que o layout inicial será definido como ScreenLayoutType.BEST_FIT:
StreamCompositionLayout layout = StreamCompositionLayout.screenshareLayout(ScreenLayoutType.PIP);
Adicionar transmissão a um arquivo
É possível adicionar um fluxo a um arquivo composto que tenha sido iniciado com o comando streamMode definir como StreamMode.MANUAL usando o VideoClient#addArchiveStream(String archiveId, String streamId) método, passando o ID do arquivo e ID da transmissão que você deseja adicionar ao arquivo, respectivamente.
O VideoClient#addArchiveStream(String archiveId, String streamId, Boolean audio, Boolean video) Uma variante desse método permite ativar ou desativar o áudio e o vídeo.
Por padrão, ambas estão ativadas (ou seja, true).Passando false para o audio O parâmetro desativará o áudio, passando false para vídeo desativará o vídeo (resultando em uma transmissão apenas com áudio). Definir qualquer um desses valores como null é equivalente ao padrão (ou seja, true em ambos os casos).
// 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);
Remover uma transmissão de um arquivo
É possível remover um fluxo de um arquivo composto usando o VideoClient#removeArchiveStream(String archiveId, String streamId) método.
Assim como na adição de um fluxo, o arquivo deve ter sido iniciado com streamMode configure como “manual”.
videoClient.removeArchiveStream(archiveId, streamId);
Trabalhando com transmissões
Trabalhar com transmissões ao vivo é muito semelhante a trabalhar com arquivos
Listar todas as transmissões ao vivo
List<Broadcast> broadcasts = videoClient.listBroadcasts();
Obter detalhes sobre uma transmissão específica
Broadcast broadcast = videoClient.getBroadcast(broadcastId);
Iniciar uma transmissão ao vivo
Para iniciar com sucesso a transmissão de uma sessão, é necessário que pelo menos um cliente esteja conectado à sessão. A transmissão ao vivo pode ser direcionada a um ponto de extremidade HLS e a até cinco servidores RTMP simultaneamente para uma sessão. É necessário fornecer o ID da sessão e deve ser especificado pelo menos um fluxo de saída (RTMP e/ou HLS).
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()
);
Interromper uma gravação de transmissão
Broadcast broadcast = videoClient.stopBroadcast(broadcastId);
Alteração dinâmica do tipo de layout de uma transmissão ao vivo
videoClient.updateBroadcastLayout(broadcastId,
StreamCompositionLayout.standardLayout(ScreenLayoutType.HORIZONTAL)
);
Adicionar ou remover uma transmissão em uma transmissão ao vivo
Alterar os streams incluídos em uma transmissão iniciada com o streamMode definido como SteamMode.MANUAL:
videoClient.addBroadcastStream(broadcastId, streamId);
videoClient.removeBroadcastStream(broadcastId, streamId);
Trabalhando com fluxos
É possível obter informações sobre um fluxo chamando a função VideoClient#getStream(String sessionId, String streamId) método.
Se a solicitação foi bem-sucedida, um com.vonage.client.video.GetStreamResponse Será retornada uma instância, que poderá ser usada para consultar as propriedades de interesse relacionadas ao fluxo.
GetStreamResponse stream = videoClient.getStream(sessionId, streamId);
// Stream Properties
VideoType videoType = stream.getVideoType();
String name = stream.getName();
List<String> layoutClassList = stream.layoutClassList();
É possível obter informações sobre todos os fluxos de uma sessão usando o VideoClient#listStreams(String sessionId) método.
Isso retornará um List de GetStreamResponse instâncias, pelas quais você pode navegar para encontrar as informações que está procurando.
// 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
));
Definir o layout do fluxo
É possível alterar as classes de layout de um stream usando o VideoClient#setStreamLayout(String sessionId, List<SessionStream> streams) método.
Ele recebe como entrada o ID da sessão e a lista de fluxos a serem alterados.
Cada fluxo é representado por um SessionStream objeto, que é construído usando o padrão builder, sendo que o ID do fluxo é utilizado para identificar o fluxo (esse é um parâmetro obrigatório).
Use o SessionStream.Builder#layoutClassList(List<String> layoutClassList) método para definir os layouts do fluxo (ou a variante com argumentos variáveis, por conveniência).
Para ilustrar, suponhamos que tenhamos dois fluxos; vamos chamá-los de stream1 e stream2.
Suponha que stream1Id e stream2Id são cadeias de caracteres com os IDs de stream1 e stream2 respectivamente, e quero definir stream1as classes de layout de full e focus, mas stream2's para min.
Veja como isso pode ser feito:
SessionStream
stream1 = SessionStream.builder(stream1Id)
.layoutClassList("full", "focus").build(),
stream2 = SessionStream.builder(stream2Id)
.layoutClassList("min").build();
videoClient.setStreamLayout(sessionId, stream1, stream2);
Moderação
Desconectando clientes
Seu servidor de aplicativos pode desconectar um cliente de uma sessão do Vonage Video chamando a função VideoClient#forceDisconnect(String sessionId, String connectionId) método.
videoClient.forceDisconnect(sessionId, connectionId);
O connectionId O parâmetro é usado para especificar o ID de conexão de um cliente conectado à sessão.
Para obter mais informações sobre a funcionalidade de desconexão forçada e os códigos de exceção, consulte o Documentação da API REST.
Forçar os clientes em uma sessão a silenciar o áudio publicado
Você pode forçar o emissor de um stream específico a interromper a transmissão de áudio usando o VideoClient#muteStream(String sessionId, String streamId) método.
videoClient.muteStream(sessionId, streamId);
É possível forçar o emissor de todas as transmissões em uma sessão (exceto uma lista opcional de transmissões) a interromper a transmissão de áudio usando o VideoClient#muteSession(String sessionId, boolean active, String... excludedStreamIds) método.
O active O parâmetro determina se os streams existentes e novos ficarão silenciados por padrão. O opcional excludedStreamIds O parâmetro permite que você especifique os fluxos a serem excluídos desta solicitação de silenciamento.
videoClient.muteSession(sessionId, true);
Para obter mais informações, consulte Silenciar o áudio das transmissões em uma sessão.
Sinalização
Você pode enviar sinais a todos os participantes de uma sessão usando o VideoClient#signalAll(String sessionId, SignalRequest request) método.
Para sinalizar um participante específico, use o VideoClient#signal(String sessionId, String connectionId, SignalRequest request) método, em vez disso.
O SignalRequest A classe (criada usando o padrão builder) possui dois campos: type e data, sendo ambos obrigatórios. Eles correspondem aos parâmetros de tipo e de dados passados nos manipuladores de sinal recebido do cliente. Certifique-se de que o type a string não excede o comprimento máximo (128 bytes) e o data a string não excede o comprimento máximo (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);
Para obter mais informações sobre códigos de sinalização e de exceção, consulte o Especificação da API REST.
SIP
Conecte sua plataforma SIP a uma sessão de vídeo da Vonage usando o VideoClient#sipDial(SipDialRequest request) método. É necessário fornecer o URI, o sessionId e o token na solicitação. É possível especificar se a negociação entre a Vonage e o terminal SIP será realizada de forma segura (usando TLS) definindo o secure parâmetro de SipDialRequest.Builder#uri(URI uri, boolean secure) para true. Você também pode, se desejar, especificar um nome de usuário e uma senha para autenticação na solicitação.
SipDialRequest request = SipDialRequest.builder()
.uri(URI.create("sip:user@sip.partner.com"), false)
.sessionId(sessionId).token(token).build();
SipDialResponse parsed = videoClient.sipDial(request);
É possível reproduzir tons DTMF para todos os participantes de uma chamada usando o VideoClient#sendDtmf(String sessionId, String digits) método. Para enviar tons apenas a um participante específico, use o VideoClient#sendDtmf(String sessionId, String connectionId, String digits) método, em vez disso.
String digits = "*0123456789#";
// Send to all participants in the session
videoClient.sendDtmf(sessionId, digits);
// Send to a specific participant
videoClient.sendDtmf(sessionId, connectionId, digits);
Requisitos
Você precisa de um ID do aplicativo Vonage Video e de uma chave privada, que podem ser obtidos ao fazer login na sua Account da Video API da Vonage.
O SDK Java da Vonage requer o JDK 8 ou superior para ser compilado. O ambiente de execução requer o Java SE 8 ou superior.
Notas de lançamento
Veja o Comunicados página com detalhes sobre cada lançamento.