Publicar e assinar com o SDK de Transmissão na Web do IVS
Esta seção descreve as etapas envolvidas na publicação e assinatura de um estágio usando a sua aplicação Web.
Criar um padrão em HTML
Primeiro, criaremos o padrão em HTML e importaremos a biblioteca como uma etiqueta de script:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <!-- Import the SDK --> <script src="https://web-broadcast.live-video.net/1.17.0/amazon-ivs-web-broadcast.js"></script> </head> <body> <!-- TODO - fill in with next sections --> <script src="./app.js"></script> </body> </html>
Aceitar entrada de tokens e adicionar botões Ingressar/Sair
Aqui, preencheremos o corpo com nossos controles de entrada. Eles recebem o token como entrada e configuram os botões Ingressar e Sair. Normalmente, as aplicações solicitarão o token da API da sua aplicação, mas, para este exemplo, você copiará e colará o token na entrada do token.
<h1>IVS Real-Time Streaming</h1> <hr /> <label for="token">Token</label> <input type="text" id="token" name="token" /> <button class="button" id="join-button">Join</button> <button class="button" id="leave-button" style="display: none;">Leave</button> <hr />
Adicionar elementos de contêiner de mídia
Esses elementos manterão a mídia para nossos participantes locais e remotos. Adicionamos uma etiqueta de script para carregar a lógica da nossa aplicação definida em app.js
.
<!-- Local Participant --> <div id="local-media"></div> <!-- Remote Participants --> <div id="remote-media"></div> <!-- Load Script --> <script src="./app.js"></script>
Isso completa a página HTML, e você verá o seguinte ao carregar index.html
em um navegador:
Criar app.js
Agora definiremos o conteúdo do nosso arquivo app.js
. Comece com a importação de todas as propriedades necessárias do SDK global:
const { Stage, LocalStageStream, SubscribeType, StageEvents, ConnectionState, StreamType } = IVSBroadcastClient;
Criar variáveis da aplicação
Estabeleça variáveis para manter referências aos nossos elementos HTML dos botões Ingressar e Sair e armazenar o estado para a aplicação:
let joinButton = document.getElementById("join-button"); let leaveButton = document.getElementById("leave-button"); // Stage management let stage; let joining = false; let connected = false; let localCamera; let localMic; let cameraStageStream; let micStageStream;
Criar joinStage 1: definir a função e validar a entrada
A função joinStage
recebe o token de entrada, cria uma conexão com o palco e começa a publicar o vídeo e o áudio recuperados de getUserMedia
.
Para começar, definimos a função e validamos o estado e a entrada do token. Desenvolveremos essa função nas próximas seções.
const joinStage = async () => { if (connected || joining) { return; } joining = true; const token = document.getElementById("token").value; if (!token) { window.alert("Please enter a participant token"); joining = false; return; } // Fill in with the next sections };
Criar joinStage 2: obter mídia para publicação
Aqui está a mídia que será publicada no palco:
async function getCamera() { // Use Max Width and Height return navigator.mediaDevices.getUserMedia({ video: true, audio: false }); } async function getMic() { return navigator.mediaDevices.getUserMedia({ video: false, audio: true }); } // Retrieve the User Media currently set on the page localCamera = await getCamera(); localMic = await getMic(); // Create StageStreams for Audio and Video cameraStageStream = new LocalStageStream(localCamera.getVideoTracks()[0]); micStageStream = new LocalStageStream(localMic.getAudioTracks()[0]);
Criar joinStage 3: definir a estratégia do palco e criar o palco
Essa estratégia de palco corresponde ao ponto central da lógica de decisão que o SDK usa para definir o que publicar e em quais participantes se inscrever. Para obter mais informações sobre a finalidade da função, consulte Strategy.
Essa estratégia é simples. Após ingressar no palco, publique os streams que acabamos de recuperar e inscreva-se nos áudios e vídeos de todos os participantes remotos:
const strategy = { stageStreamsToPublish() { return [cameraStageStream, micStageStream]; }, shouldPublishParticipant() { return true; }, shouldSubscribeToParticipant() { return SubscribeType.AUDIO_VIDEO; } }; stage = new Stage(token, strategy);
Criar joinStage 4: lidar com eventos de palco e renderizar mídia
Os palcos emitem muitos eventos. Precisamos receber STAGE_PARTICIPANT_STREAMS_ADDED
e STAGE_PARTICIPANT_LEFT
para renderizar mídia e removê-la da página. Um conjunto mais completo de eventos está listado em Eventos.
Observe que criamos quatro funções auxiliares aqui para nos ajudar no gerenciamento dos elementos DOM necessários: setupParticipant
, teardownParticipant
, createVideoEl
e createContainer
.
stage.on(StageEvents.STAGE_CONNECTION_STATE_CHANGED, (state) => { connected = state === ConnectionState.CONNECTED; if (connected) { joining = false; joinButton.style = "display: none"; leaveButton.style = "display: inline-block"; } }); stage.on( StageEvents.STAGE_PARTICIPANT_STREAMS_ADDED, (participant, streams) => { console.log("Participant Media Added: ", participant, streams); let streamsToDisplay = streams; if (participant.isLocal) { // Ensure to exclude local audio streams, otherwise echo will occur streamsToDisplay = streams.filter( (stream) => stream.streamType === StreamType.VIDEO ); } const videoEl = setupParticipant(participant); streamsToDisplay.forEach((stream) => videoEl.srcObject.addTrack(stream.mediaStreamTrack) ); } ); stage.on(StageEvents.STAGE_PARTICIPANT_LEFT, (participant) => { console.log("Participant Left: ", participant); teardownParticipant(participant); }); // Helper functions for managing DOM function setupParticipant({ isLocal, id }) { const groupId = isLocal ? "local-media" : "remote-media"; const groupContainer = document.getElementById(groupId); const participantContainerId = isLocal ? "local" : id; const participantContainer = createContainer(participantContainerId); const videoEl = createVideoEl(participantContainerId); participantContainer.appendChild(videoEl); groupContainer.appendChild(participantContainer); return videoEl; } function teardownParticipant({ isLocal, id }) { const groupId = isLocal ? "local-media" : "remote-media"; const groupContainer = document.getElementById(groupId); const participantContainerId = isLocal ? "local" : id; const participantDiv = document.getElementById( participantContainerId + "-container" ); if (!participantDiv) { return; } groupContainer.removeChild(participantDiv); } function createVideoEl(id) { const videoEl = document.createElement("video"); videoEl.id = id; videoEl.autoplay = true; videoEl.playsInline = true; videoEl.srcObject = new MediaStream(); return videoEl; } function createContainer(id) { const participantContainer = document.createElement("div"); participantContainer.classList = "participant-container"; participantContainer.id = id + "-container"; return participantContainer; }
Criar joinStage 5: ingressar no palco
Concluiremos nossa função joinStage
ao finalmente ingressar no palco.
try { await stage.join(); } catch (err) { joining = false; connected = false; console.error(err.message); }
Criar leaveStage
Defina a função leaveStage
que o botão Sair invocará.
const leaveStage = async () => { stage.leave(); joining = false; connected = false; };
Inicializar manipuladores de eventos de entrada
Adicionaremos uma última função ao nosso arquivo app.js
. Essa função é invocada imediatamente quando a página é carregada e estabelece manipuladores de eventos para ingressar e sair do palco.
const init = async () => { try { // Prevents issues on Safari/FF so devices are not blank await navigator.mediaDevices.getUserMedia({ video: true, audio: true }); } catch (e) { alert( "Problem retrieving media! Enable camera and microphone permissions." ); } joinButton.addEventListener("click", () => { joinStage(); }); leaveButton.addEventListener("click", () => { leaveStage(); joinButton.style = "display: inline-block"; leaveButton.style = "display: none"; }); }; init(); // call the function
Executar a aplicação e fornecer um token
Nesse ponto, você pode compartilhar a página da Web localmente ou com outras pessoas, abrir a página, inserir um token de participante e ingressar no Stage.
E depois?
Para obter exemplos mais detalhados envolvendo npm, React etc, consulte SDK de Transmissão do IVS: Guia do Android (streaming em tempo real).