Transmissão ao vivo com a Video API da Vonage
A Video API da Vonage permite que você crie praticamente qualquer experiência de vídeo que desejar. Um caso de uso comum entre os desenvolvedores é a necessidade de situações em que uma ou poucas pessoas estejam transmitindo para um público maior que apenas assiste, como participantes assistindo à transmissão ao vivo de uma conferência.
Neste tutorial
A Video API da Vonage permite que você crie rapidamente uma sala para que uma única pessoa possa transmitir, e outras possam participar e assistir. Vamos mostrar como colocar uma demonstração em funcionamento usando nossas demonstrações já prontas, para que você não precise escrever nenhum código, mas também explicaremos o que o código está fazendo nos bastidores.
- Veja a demonstração - Confira a demonstração sem precisar escrever nenhum código
- Como funciona a demonstração – Lado do cliente - O que o código do lado do cliente está fazendo
- Como funciona a demonstração – O lado do servidor - O que o código do lado do servidor está fazendo
Pré-requisitos
Para concluir o tutorial, você precisa de:
- A Account da Vonage - para sua chave e seu segredo da API
Veja a demonstração
Se você quiser conferir a demonstração antes de escrevermos qualquer código, temos um servidor web de exemplo e um código em JavaScript para você testar como funciona uma videochamada básica. Todo o código é de código aberto e está disponível publicamente; assim, você pode experimentar a demonstração e, em seguida, usar o código para fazer suas próprias modificações.
Inicie o servidor Node.js
A demonstração em vídeo requer um servidor de back-end para lidar com tarefas como a criação de tokens de cliente para autorização e o gerenciamento geral de sessões. Embora você possa desenvolvê-lo em qualquer linguagem de sua preferência, temos um servidor já pronto que você pode usar para começar, disponível em Servidor de Aprendizado por Vídeo da Vonage (Node.js) no Code Hub. A partir do Documentação para desenvolvedores, clique em “Code Hub” na barra de navegação superior e, em seguida, role a página para baixo até encontrar o cartão “Vonage Video Learning Server (Node.js)”. Clique nele para abri-lo.
Você receberá uma descrição do que este projeto faz. Por enquanto, vamos clicar em “Obter código” para que possamos carregá-lo no editor online do Code Hub. Clique em “Criar um novo ambiente de desenvolvimento”. Nomeie o espaço de trabalho como “Vonage Video Demo”, já que podemos usar esse back-end para várias demonstrações. Esta demonstração exige que um número seja atribuído a ela, já que o servidor de aprendizagem suporta chamadas telefônicas via SIP. Embora não vamos usar isso nesta demonstração, vá em frente e clique em “Atribuir um número” para atribuir um número existente que você tenha da Vonage ou compre um novo para usar em demonstrações futuras.

O Code Hub criará automaticamente um aplicativo para você, incluindo a configuração das chaves pública e privada que nosso aplicativo utilizará. Assim que o espaço de trabalho for criado, você será direcionado para o editor de código, que é uma versão online do Visual Studio Code. Fique à vontade para acompanhar as partes seguintes desta demonstração para ver o código, e você pode editá-lo conforme necessário para seus próprios projetos.

Para executar o aplicativo, clique em “Exibir” na parte superior do editor e, em seguida, em “Terminal”. Isso abrirá uma linha de comando na qual podemos executar comandos. Basta digitar vcr deploy e o código será implantado. Isso levará alguns instantes, pois o sistema empacota o código e o executa nos servidores do Vonage Code Hub. É importante anotar o “endereço do host da instância” que é exibido perto do final.

Se tudo estiver funcionando corretamente, você deverá conseguir acessar o “endereço do host da instância” e ver a seguinte página:

Teste o front-end
O servidor de back-end funciona diretamente com todas as nossas demonstrações pré-criadas, incluindo esta demonstração individual. Acesse https://github.com/Vonage-Community/Video-API-web-samples/tree/main/Live-Broadcast, que é o código-fonte da parte front-end desta demonstração. Este exemplo permite que dois usuários, por meio da URL, participem da demonstração.
A maneira mais fácil de executar esta demonstração é clicar no botão “Abrir no Stackblitz” no arquivo README.

Isso abrirá o projeto no Stackblitz. Assim como no servidor de back-end, você pode examinar o código e modificá-lo aqui, se quiser. Para esta demonstração, tudo o que precisamos fazer é abrir o js/config.js arquivo e insira a URL da instância do Code Hub no SAMPLE_SERVER_BASE_URL variável:

Depois de salvar o arquivo, você pode atualizar a visualização da demonstração no lado direito do Stackblitz. Este exemplo está dividido em algumas partes, incluindo uma visualização do host e duas maneiras diferentes de exibir o vídeo propriamente dito. Vamos nos concentrar na transmissão que não utiliza RTMP.
Como funciona a demonstração
Configurar uma aplicação da Vonage
Para que nosso aplicativo de vídeo funcione, precisamos de uma maneira de nosso cliente e servidor se comunicarem com os servidores da Vonage. O Code Hub configura isso para nós, mas se você estiver executando o código localmente ou quiser saber o que isso envolve, saiba que um aplicativo de vídeo é configurado exatamente como qualquer outra API. Precisamos configurar uma aplicação da Vonage para abrigar toda a configuração da nossa aplicação, além de ajudar a gerar os itens necessários para que possamos realizar a autenticação.
Dê uma passada no seu Painel do Cliente da Vonage e faça login. Depois de fazer login:
- Clique em “Applications” na seção “Compilação”.
- Clique em “Criar um novo aplicativo”.
- Dê um nome ao aplicativo, como “Demonstração básica de vídeo”.
- Clique em “Gerar chave pública e privada”, o que fará com que você baixe um arquivo chamado
private.key. Guarde esse arquivo para consultar mais tarde. - Role a página para baixo e ative a opção “Vídeo”. Por enquanto, vamos deixar esses campos em branco.
- Clique em “Gerar novo pedido” para criar o pedido.
Assim que o aplicativo for criado, anote o ID do aplicativo. Se você estiver executando o código localmente, precisaremos desse ID para configurar o backend. Se estiver usando o Code Hub, o código do servidor já tem acesso ao ID do aplicativo e à chave privada.
O lado do cliente
A parte do lado do cliente da demonstração consiste em dois elementos distintos: alguns elementos HTML para inserir os feeds de vídeo e, em seguida, um código JavaScript para obter as informações de login e se comunicar com os servidores da Vonage Video.
Como se trata de uma demonstração no navegador, utilizamos o SDK do JavaScript disponível em https://unpkg.com/@vonage/client-sdk-video@latest/dist/js/opentok.js, e incluir isso em uma tag script no nosso HTML em index.html.
O Anfitrião
Para a tela do anfitrião, precisamos apenas visualizar a câmera do anfitrião, além de uma interface de usuário para controlar diferentes opções, como iniciar a transmissão, ativar a baixa latência e atualizações de status. Para visualizar sua própria câmera, criamos um <div> elemento para hospedar o elemento de vídeo:
// host.html
<div>
<h2 class="font-black text-2xl">Your Camera</h2>
<div class="h-80 w-80" id="host"></div>
</div>
O restante da página “Host” é composto por botões e configurações para a transmissão ao vivo propriamente dita. Vamos deixar todas as opções como estão e nos concentrar nos controles de transmissão. Trata-se apenas de alguns botões simples que vamos configurar para chamar o aplicativo do servidor e iniciar e interromper os feeds de transmissão.
// host.html
<div><h2 class="font-black text-2xl">Broadcast Controls</h2></div>
<div>
<button x-show="broadcastStatus == 'stopped'" x-on:click="broadcastStatus = 'started'" id="btn-start" class="bg-blue-500 bold text-white p-4 rounded">Start Broadcast</button>
<button x-show="broadcastStatus == 'started'" x-on:click="broadcastStatus = 'stopped'" id="btn-end" class="bg-red-500 bold text-white p-4 rounded">Stop Broadcast</button>
</div>
Nossa conexão em JavaScript é mínima em comparação com outras configurações nas quais várias pessoas participam juntas. Normalmente, nos conectaríamos à sessão e, em seguida, publicaríamos imediatamente nossos fluxos de vídeo e áudio, mas, como estamos controlando quando a transmissão começa e termina, faremos isso em duas etapas. Primeiro, nos conectamos à sessão como de costume:
// js/host.js
document.addEventListener('DOMContentLoaded', async () => {
const credentials = await getCredentials('host');
const session = OT.initSession(
credentials.applicationId,
credentials.sessionId,
{
connectEventsSuppressed: true
}
);
session.connect(credentials.token, (error) => {
if (error) {
console.error(error);
return;
}
let publisher = initPublisher();
// ...
Depois de nos conectarmos ao fluxo, adicionamos um ouvinte de eventos ao btn-start botão para que possamos realmente publicar e iniciar a transmissão quando o usuário clicar nesse botão. O início (e o término) da transmissão são gerenciados pelos SDKs do lado do servidor; portanto, enviamos uma solicitação ao nosso servidor de back-end para iniciar a transmissão.
// js/host.js
document.getElementById('btn-start').addEventListener('click', async (el, event) => {
const rtmp = [];
if (document.getElementById('rtmpAddress').value) {
rtmp.push({
serverUrl: document.getElementById('rtmpAddress').value,
streamName: document.getElementById('rtmpKey').value,
});
}
broadcast = await fetch(`${SAMPLE_SERVER_BASE_URL}/broadcast/session/start`, {
method: "POST",
body: JSON.stringify({
rtmp,
lowLatency: document.getElementById('lowLatency').checked,
dvr: document.getElementById('dvr').checked,
sessionId: session.id,
streamMode: "auto"
}),
headers: {
"Content-type": "application/json"
}
})
.then(res => {
// Once the broadcast starts we finally publish the host
session.publish(publisher);
shouldCheckBroadcast = true;
setTimeout(checkBroadcast, 5000);
return res.json()
})
.catch(error => console.error(error));
});
Neste momento, nosso anfitrião já está transmitindo por meio da própria transmissão, assim como qualquer outra pessoa que se conectar. A demonstração que temos oferece suporte a convidados; assim, à medida que os convidados são convidados para as reuniões, suas transmissões são automaticamente adicionadas à transmissão pela Video API do Vonage.
A interrupção da transmissão é feita pelo aplicativo do servidor; portanto, uma chamada rápida àquela rota em nosso servidor de back-end interromperá a própria transmissão. Atribuímos um ouvinte de eventos ao btn-stop botão que é acionado quando clicado.
// js/host.js
document.getElementById('btn-end').addEventListener('click', async (el, event) => {
broadcast = await fetch(`${SAMPLE_SERVER_BASE_URL}/broadcast/session/stop`, {
method: "POST",
body: JSON.stringify({
sessionId: session.id
}),
headers: {
"Content-type": "application/json"
}
})
.then(res => {
session.unpublish(publisher);
shouldCheckBroadcast = false;
publisher = initPublisher();
return res.json()
})
.catch(error => console.error(error));
});
The Viewer - Transmissão ao vivo
Para um espectador, precisamos apenas de um local para exibir o fluxo de vídeo do anfitrião. Como os espectadores não publicarão seus próprios fluxos, teremos muito menos código de front-end para trabalhar com eles. Vamos criar um <div> para exibir a transmissão do anfitrião.
// view.html
<div class="grid grid-cols-1 container mx-auto pt-4">
<h2 class="font-black text-2xl mx-auto">Host Camera</h2>
<div class="w-1/2 h-96 mx-auto" id="host"></div>
</div>
Como um espectador nunca publica suas próprias transmissões, nosso JavaScript simplesmente se conecta à transmissão e aguarda que as transmissões sejam criadas pela emissora:
// js/view.js
const credentials = await getCredentials('viewer');
const session = OT.initSession(
credentials.applicationId,
credentials.sessionId,
{
connectEventsSuppressed: true
}
);
session.connect(credentials.token, (error) => {
if (error) {
console.log(error);
return;
}
session.on('streamCreated', (event) => {
session.subscribe(event.stream, 'host', {
insertMode: 'append',
width: '100%',
height: '100%',
})
});
});
O Visualizador - HLS
Para executar o HLS, basta adicionar um <video> elemento, em vez de usar um <div>. Se você preferir usar o HLS, nós criamos um <video> elemento ao qual vamos associar uma fonte mais tarde. Observe que será necessário JavaScript adicional para a maioria dos navegadores; portanto, também incluiremos a biblioteca JavaScript do HLS, disponível no NPM:
// hls.html
<script src="https://cdn.jsdelivr.net/npm/hls.js@1"></script>
<div class="grid grid-cols-1 container mx-auto pt-4">
<h2 class="font-black text-2xl mx-auto">HLS Stream</h2>
<div id="host">
<video class="w-1/2 mx-auto" id="video" autoplay controls></video>
</div>
</div>
Em nossa demonstração, o usuário obtém uma URL do servidor, que conterá a URL da transmissão como um parâmetro de consulta. Usaremos essa URL para vincular essa transmissão ao reprodutor de vídeo. Também faremos algumas verificações básicas para garantir que o HLS seja compatível, já que nem todos os navegadores oferecem suporte ao HLS por padrão.
const video = document.getElementById('video');
const videoSource = new URLSearchParams(window.location.search).get('url');
if (!videoSource) {
alert('No HLS URL was passed. No video will be displayed');
return;
}
if (Hls.isSupported()) {
const hls = new Hls();
hls.on(Hls.Events.MEDIA_ATTACHED, () => {
video.muted = true;
video.play();
});
hls.loadSource(videoSource);
hls.attachMedia(video);
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = videoSource;
} else {
alert('Browser does not seem to have HLS capabilities. No video will be displayed');
return;
}
});
O lado do servidor
A parte do lado do servidor de qualquer aplicativo Vonage Video é usada para lidar com a criação de sessões, a geração de tokens de autenticação e tarefas administrativas, como iniciar e interromper arquivamentos. Para esta demonstração, nosso único objetivo é criar sessões e tokens para que os usuários possam entrar na sala. Embora a API em si seja uma API REST e possa ser chamada da maneira que você preferir, recomendamos que você use a SDK do Vonage Node que cuida de toda a autenticação e das chamadas HTTP para você. Você pode instalá-lo em seu próprio aplicativo com:
npm install -s @vonage/server-sdk
O código de demonstração já vem com isso pré-instalado. Se você estiver executando o código localmente, precisará executar:
npm install
para baixar todas as dependências e, em seguida, copiar .envcopy em um novo arquivo chamado .env. Você precisará preencher as informações solicitadas em .env como o ID do aplicativo, o local da chave privada no disco e sua chave e segredo da API da Vonage.
O Anfitrião
Vamos dar ao anfitrião um moderator função; assim, quando o front-end solicitar credenciais, criaremos a sessão com a função apropriada. Caso contrário, não há praticamente nenhuma diferença entre a sessão de um apresentador de transmissão ao vivo e a de um usuário comum de vídeo com a moderator função.
// routes/index.js
router.get('/broadcast/:name/host', async function (req, res) {
const broadcastName = req.params.name + '-broadcast';
await createSession(res, broadcastName, { initialLayoutClassList: ['full', 'focus'] }, 'moderator');
});
Para obter mais informações sobre como criar tokens, consulte nosso Caso de uso do vídeo individual que explica em detalhes como criar sessões.
Quando o usuário deseja iniciar efetivamente a transmissão, usamos o SDK do servidor para chamar o vonage.video.startBroadcast() método, que transformará os fluxos publicados em uma sessão de transmissão. Em seguida, retornamos esses dados ao cliente para que ele tenha todas as informações necessárias para localizar a transmissão e controlá-la posteriormente.
// routes/index.js
router.post('/broadcast/:room/start', async (req, res) => {
const { rtmp, lowLatency, fhd, dvr, sessionId, streamMode } = req.body;
// Kill any existing broadcasts we have, to be safe
vonage.video.searchBroadcasts({sessionId})
.then(list => {
list.items.map(async (broadcast) => {
vonage.video.stopBroadcast(broadcast.id)
})
})
vonage.video.startBroadcast(sessionId, {outputs: {rtmp, hls: {lowLatency, dvr}}, streamMode})
.then(data => {
broadcastsToSessionIdDictionary[sessionId] = data;
res.send(data)
})
.catch(error => {
console.error(error);
res.status(500).send(error)
})
})
Encerrar a transmissão é praticamente o mesmo — chamamos as funções do SDK do servidor vonage.video.stopBroadcast() método para encerrar a transmissão.
// routes/index.js
router.post('/broadcast/:room/stop', async (req, res) => {
const { sessionId } = req.body
if (broadcastsToSessionIdDictionary[sessionId]) {
vonage.video.stopBroadcast(broadcastsToSessionIdDictionary[sessionId].id)
.then(data => {
delete broadcastsToSessionIdDictionary[sessionId]
res.send(data)
})
.catch(err => {
console.error(err)
res.status(500).send(err)
})
}
})
The Viewer - Transmissão ao vivo
Em uma transmissão, basta fornecer ao espectador o tipo adequado de token de conexão. Todo o resto é tratado no navegador pelo código do lado do cliente.
router.get('/broadcast/:name/viewer', async function (req, res) {
const broadcastName = req.params.name + '-broadcast';
await createSession(res, broadcastName, { initialLayoutClassList: ['full', 'focus'] }, 'subscriber');
});
O Visualizador - HLS
Os espectadores que assistem via HLS não precisam de nenhuma informação especial de conexão, pois tudo é transmitido por meio do reprodutor de vídeo e da URL da transmissão. Dessa forma, não há necessidade de código do lado do servidor para gerar tokens. Se você quiser impedir que os espectadores assistam a uma transmissão, precisará incorporar essa funcionalidade ao seu aplicativo.
Conclusão
Neste tutorial, você viu o que é necessário no servidor de back-end tanto para transmissões baseadas em stream quanto para aquelas baseadas em HLS, como criar um cliente web para que os usuários assistam às transmissões, além de ter tido uma ideia de como é fácil usar o Vonage Code Hub e o Stack Blitz para testar rapidamente exemplos de código.