Personalização da interface do usuário — Web

Estas são as configurações que você pode fazer para personalizar a interface do usuário dos vídeos do OpenTok:

Definindo a posição inicial e as dimensões de um vídeo

Ao publicar um vídeo, você pode especificar o elemento DOM (ou seu ID) que o publisher substituirá. Você também pode especificar a largura e a altura iniciais do publisher:

// Replace the first parameter with ID of the target DOM element:
const publisher = OT.initPublisher('myPublisherElementId',
                                 {width:400, height:300});
session.publish(publisher);

Você também pode definir o insertMode propriedade das opções que você passa para o OT.initPublisher() método para 'append' Para que o publisher seja anexado como um elemento filho do elemento DOM (contêiner) que você especificar:

const publisherOptions = {
  insertMode: 'append',
  width: 400,
  height: 300
};
const publisher = OT.initPublisher('publisherContainerElementId', publisherOptions);
session.publish(publisher);

Da mesma forma, ao assinar um fluxo, você pode especificar o elemento DOM de destino (ou seu ID). Também é possível especificar a largura e a altura iniciais do assinante:

const options = {width: 400, height: 300, insertMode: 'append'}
const subscriber = session.subscribe(stream, 'containerElementId', options);

Você também pode especificar a largura e a altura iniciais como uma porcentagem do tamanho do elemento DOM pai:

const publisherOptions = {
  insertMode: 'append',
  width: '100%',
  height: '100%'
};
const publisher = OT.initPublisher(publisherContainerElement, publisherOptions);
session.publish(publisher);

Se você não especificar um ID para o elemento a ser substituído (ou defini-lo como nulo), o aplicativo acrescenta um novo elemento DOM ao corpo do HTML. A largura padrão é de 264 pixels, e a altura padrão é de 198 pixels.

Se você quiser aplicar várias regras CSS, aplique-as ao elemento DOM pai (contêiner):

<style>
	#publisherContainer.large
	{ width: 640px; height: 480px; }
	#publisherContainer.small
	{ width:100px; height: 100px; }
</style>
<div id="publisherContainer"></div>
<script>
	const publisher = OT.initPublisher('publisherContainer',
	{width: '100%', height: '100%', insertMode: 'append'}
</script>

Para aplicar um tamanho diferente a um vídeo em um dispositivo móvel, use consultas de mídia CSS:

<style>
	#publisherContainer
	{ width: 100px; height: 100px; }
	@media screen and (max-width: 650px) {
	#publisherContainer
	{ width: 89px; height: 50px; }
	}
</style>
<div id="publisherContainer"></div>
<script>
	const publisher = OT.initPublisher('publisherContainer',
	{width: '100%', height: '100%', insertMode: 'append'}
</script>

Se você quiser redimensionar o vídeo dinamicamente, defina o insertMode para 'append' e definir o height e width para '100%'.

Consulte a próxima seção para obter informações sobre como redimensionar ou reposicionar um vídeo de editor ou assinante.

Redimensionar ou reposicionar um vídeo

O element Uma propriedade do objeto Publisher ou Subscriber é seu elemento DOM HTML. É possível reposicioná-lo no DOM HTML e redimensionar o elemento editando seu style.width e style.height propriedades, da mesma forma que você faria com qualquer outro elemento do DOM:

document.getElementById("target").appendChild(publisher.element);
publisher.element.style.width = "100px";
publisher.element.style.height = "75px";

Se você especificar o valor inicial width e height do objeto Publisher ou Subscriber como uma porcentagem (como “100%”), é possível redimensioná-lo alterando o tamanho de um de seus elementos pais. O exemplo a seguir inclui uma função que redimensiona um Publisher:

<script type="text/javascript">
	const publisherOptions = {
		insertMode: "append",
		height: "100%",
		width: "100%"
	}
	const publisher = OT.initPublisher("publisherContainer", publisherOptions);
	session.publish(publisher);

	function resizePublisher() {
		const publisherContainer = document.getElementById("publisherContainer");
		publisherContainer.style.width = "1000px";
		publisherContainer.style.height = "750px";
	}
</script>

<div id="container">
	<div id="publisherContainer"></div>
	<a href="javascript:resizePublisher()">resize</a>
</div>

Consulte a seção anterior, Definindo as dimensões iniciais de um vídeo para obter informações sobre como definir a posição inicial e as dimensões de um editor ou assinante.

Importante: Se você desativar a interface de usuário padrão do editor ou do assinante definindo insertDefaultUI para false ao instanciar o objeto Publisher ou Subscriber, o element A propriedade do Editor ou do Assinante ficará indefinida. Verifique se há o videoElementCreated evento e usar o element propriedade do objeto de evento para acessar o elemento DOM HTML do Editor ou do Assinante. Consulte Acesso direto ao elemento de vídeo para um Editor ou Assinante.

Adicionar um nome a um stream publicado

Ao criar um Publisher, você pode (opcionalmente) especificar um nome a ser exibido no vídeo:

// Replace the first parameter with the target element ID:
const publisher = OT.initPublisher("myPublisher",
                                 {name: "John"})
session.publish(publisher);

Você pode usar esse nome para identificar o cliente.

Não utilize informações pessoais no campo “nome” do editor — o nome do editor pode ser exibido para outros participantes da sessão e também pode aparecer na Ferramenta de Inspeção e nos registros internos da Vonage; portanto, você nunca deve usar informações confidenciais ou pessoais não criptografadas no nome do editor. Veja as melhores práticas de segurança.

Observe que você também pode adicionar metadados sobre o cliente ao criar um token. Esse nome não é exibido automaticamente no vídeo. No entanto, ao adicionar esses dados durante a criação do token, você pode inserir informações de forma mais segura (já que os tokens são criados no servidor, e não no cliente). Para obter mais informações, consulte Criação de um token.

Os clientes podem optar por ocultar o nome na visualização do Editor ou do Assinante. Consulte a próxima seção

Exibir ou ocultar o nome em um vídeo

Ao publicar uma transmissão, você pode especificar um nome a ser exibido no vídeo (consulte a seção anterior).

Ao criar um Editor, você pode especificar se o nome será exibido no vídeo do Editor, definindo a style.nameDisplayMode propriedade das opções que você passa para o OT.initPublisher() método:

// Replace the first parameter with the target element ID:
const publisher = OT.initPublisher("myPublisher",
  {
    name: "John",
    style: { nameDisplayMode: "off" }
  });
session.publish(publisher);

O style.nameDisplayMode essa propriedade pode ser definida como um dos três valores:

  • "auto" — O nome é exibido quando a transmissão é exibida pela primeira vez e quando o usuário passa o mouse sobre o vídeo (padrão).
  • "off" — O nome não é exibido.
  • "on" — O nome é exibido.

Depois de criar o Publisher, você pode alterar o modo de exibição do nome, chamando o setStyle() método do objeto Publisher. (Consulte o documentação para o Publisher.setStyle() método.)

Ao se inscrever em um canal, você pode especificar se o nome será exibido no vídeo “Assinantes”, definindo o style.nameDisplayMode propriedade das opções que você passa para o Session.subscribe() método:

// Replace the first two parameters with the stream and target element ID:
const subscriber = session.subscribe(stream,
  "mySubscriber",
  {
    style: { nameDisplayMode: "off" }
  });

Depois de criar o Assinante, você pode alterar o modo de exibição do nome, chamando a função setStyle() método do objeto Subscriber. (Consulte o documentação para o Subscriber.setStyle() método.)

Exibir ou ocultar o botão de silenciar o áudio

Por padrão, a interface do usuário de um Emissor ou de um Assinante inclui um botão para silenciar o áudio. No caso de um Emissor, o usuário pode clicar nesse botão para ativar ou desativar o microfone. No caso de um Assinante, o usuário pode clicar nesse botão para ativar ou desativar o alto-falante.

Ao publicar uma transmissão, você pode especificar se o botão de silenciar será exibido passando um style.buttonDisplayMode propriedade na OT.initPublisher() método:

const publisher = OT.initPublisher(
  'publisher-element-id', // Replace with the replacement element ID
  {
     name: 'John',
     style: {buttonDisplayMode: 'on'}
  }
);
session.publish(publisher);

O style.buttonDisplayMode essa propriedade pode ser definida como um dos três valores:

  • "auto" — O botão de silenciar é exibido quando a transmissão é exibida pela primeira vez e quando o usuário passa o mouse sobre o vídeo (configuração padrão).
  • "off" — O botão de silenciar não aparece.
  • "on" — O botão de silenciar é exibido.

Da mesma forma, ao se inscrever em um stream, você pode especificar se o alto-falante silenciado será exibido passando um style.buttonDisplayMode propriedade na Session.subscribe() método:

const subscriber = session.subscribe(stream,
  'subscriber-element-id', // Replace with the replacement element ID
  {
     style: {buttonDisplayMode: 'on'}
  }
);

Depois de criar o Editor ou o Assinante, você pode alterar o modo de exibição do botão de silenciar, chamando a função setStyle() método do objeto Publisher ou do objeto Subscriber. (Consulte a documentação de Publisher.setStyle() e Subscriber.setStyle().)

Ajustando o recorte do vídeo e o formato letterbox

É possível especificar o recorte ou a exibição com barras de um vídeo do Editor ou do Assinante definindo o fitMode propriedade das opções que você passa para OT.initPublisher() ou Session.subscribe(). Passe uma das duas sequências de caracteres a seguir:

  • "cover" — O vídeo é cortado se suas dimensões não corresponderem às do elemento DOM. Essa é a configuração padrão para vídeos que transmitem imagens da câmera.
  • "contain" — O vídeo é exibido em formato letterbox caso suas dimensões não correspondam às do elemento DOM. Essa é a configuração padrão para vídeos compartilhados na tela.

Por exemplo, o código a seguir inicializa um publisher com o elemento de vídeo em formato letterbox:

const publisher = OT.initPublisher("publisher-element-id",
  {fitMode: "contain"});

O código a seguir assina um stream com o elemento de vídeo recortado:

const subscriber = session.subscribe(stream,
  "subscriber-element-id",
  {fitMode: "cover"});

Capturar um quadro de um vídeo

O código a seguir captura e exibe uma imagem estática do vídeo do Publisher:

const imgData = publisher.getImgData();
const img = document.createElement("img");
img.setAttribute("src", "data:image/png;base64," + imgData);

// Replace with the parent DIV for the img
document.getElementById("containerId").appendChild(img);

O código a seguir captura e exibe uma imagem estática de um vídeo de um assinante:

const imgData = subscriber.getImgData();
const img = document.createElement("img");
img.setAttribute("src", "data:image/png;base64," + imgData);

// Replace with the parent DIV for the img
document.getElementById("containerId").appendChild(img);

Configurar uma imagem para ser exibida no modo somente áudio

Você pode usar o backgroundImageURI estilo de um Assinante para definir a imagem a ser exibida quando não houver vídeo. O valor definido pode ser a URL de uma imagem na internet. Também pode ser um data: URL, como aquele que você obtém usando o getImgData() método do objeto Subscriber (consulte o seção anterior).

O código a seguir define a imagem de fundo do Assinante. Quando a chamada para Session.subscribe() Se a operação for concluída com sucesso, a imagem de fundo é definida. Se houver um fluxo de vídeo, o fundo é definido como uma imagem estática capturada do vídeo do assinante; caso contrário, é definido como uma imagem carregada a partir de um URL da web:

const subscriber = session.subscribe(event.stream, 'subscriberElement', function(error) {
  if (error) {
    console.log(error.message)'
    return;
  }
  if (subscriber.stream.hasVideo) {
    const imgData = subscriber.getImgData();
    subscriber.setStyle('backgroundImageURI', imgData);
  } else {
    subscriber.setStyle('backgroundImageURI',
      'data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" width="1" height="1"%3E%3Crect width="1" height="1" fill="%23f4eadf"/%3E%3C/svg%3E'
    );
  }
});

Se você não definir uma imagem de fundo para um Assinante, quando não houver vídeo, serão exibidas as iniciais da transmissão, caso elas tenham sido definidas quando o editor da transmissão a inicializou (consulte Inicializando um Publisher).

Você pode remover o plano de fundo atual não passando nenhuma imagem, por exemplo: subscriber.setStyle('backgroundImageURI', null). As iniciais serão exibidas, caso tenham sido definidas anteriormente.

Ajuste da interface do usuário com base nos níveis de áudio

Despacho dos objetos Publisher e Subscriber audioLevelUpdated eventos que ocorrem periodicamente para informar o nível de áudio. Você pode usar esses eventos para exibir um indicador de nível de áudio. Também é possível usar esses eventos para detectar alto-falantes ativos em uma sessão.

O exemplo a seguir ajusta o valor de um elemento de medidor que exibe o volume de um assinante. O código define o audioLevelDisplayMode estilo para 'off', o que desativa o medidor de nível de áudio padrão exibido no Subscriber. Observe que o nível de áudio é ajustado logaritmicamente e que é aplicada uma média móvel:

subscriber.setStyle('audioLevelDisplayMode', 'off');
const movingAvg = null;
subscriber.on('audioLevelUpdated', function(event) {
  if (movingAvg === null || movingAvg <= event.audioLevel) {
    movingAvg = event.audioLevel;
  } else {
    movingAvg = 0.7 * movingAvg + 0.3 * event.audioLevel;
  }

  // 1.5 scaling to map the -30 - 0 dBm range to [0,1]
  const logLevel = (Math.log(movingAvg) / Math.LN10) / 1.5 + 1;
  logLevel = Math.min(Math.max(logLevel, 0), 1);
  document.getElementById('subscriberMeter').value = logLevel;
});

O exemplo pressupõe que existe um elemento HTML `meter` com o ID “subscriberMeter”.

Observe que, no modo somente áudio, um elemento DOM do tipo Publisher ou Subscriber exibe um indicador de volume por padrão (no canto superior direito do elemento). É possível desativar esse elemento padrão da interface do usuário e exibir seu próprio medidor de volume. Consulte o próximo tópico, Ajustar a interface do usuário quando o vídeo estiver ativado ou desativado.

Você também pode usar o audioLevelUpdated evento para determinar quando o áudio de um emissor ou receptor está alto o suficiente por tempo suficiente para considerar que o participante começou a falar. Ou, se o áudio estiver baixo por tempo suficiente, é possível identificar que o participante parou de falar:

const subscriber = session.subscribe(event.stream);

SpeakerDetection(subscriber, function() {
  console.log('started talking');
}, function() {
  console.log('stopped talking');
});

const SpeakerDetection = function(subscriber, startTalking, stopTalking) {
  const activity = null;
  subscriber.on('audioLevelUpdated', function(event) {
    const now = Date.now();
    if (event.audioLevel > 0.2) {
      if (!activity) {
        activity = {timestamp: now, talking: false};
      } else if (activity.talking) {
        activity.timestamp = now;
      } else if (now- activity.timestamp > 1000) {
        // detected audio activity for more than 1s
        // for the first time.
        activity.talking = true;
        if (typeof(startTalking) === 'function') {
          startTalking();
        }
      }
    } else if (activity && now - activity.timestamp > 3000) {
      // detected low audio activity for more than 3s
      if (activity.talking) {
        if (typeof(stopTalking) === 'function') {
          stopTalking();
        }
      }
      activity = null;
    }
  });
};

(Em vez de registrar mensagens no console, seu aplicativo poderia ajustar um elemento da interface do usuário quando o usuário começar e parar de falar.)

Exibição de um elemento de interface do usuário personalizado quando o áudio do assinante estiver bloqueado

Alguns navegadores bloqueiam automaticamente a reprodução de áudio, exigindo um click evento que ocorre antes do início da reprodução de áudio para os assinantes. Esses navegadores incluem o Safari, o Firefox 66+ e o Chrome 71+.

O objeto Subscriber exibe um botão de reprodução de áudio caso a reprodução esteja bloqueada. É possível desativar o botão padrão de reprodução de áudio do Subscriber e exibir seu próprio elemento de interface do usuário, no qual o usuário clicará para iniciar a reprodução de áudio.

Para desativar a exibição do botão padrão de reprodução de áudio, defina o style.audioBlockedDisplayMode propriedade do options parâmetro do Session.subscribe() método):

const subscriberOptions = {
    style: { audioBlockedDisplayMode: "off" }
  };
const subscriber = session.subscribe(stream,
  'subscriber-element-id', // Replace with the replacement element ID
  subscriberOptions
);

Adicione ouvintes de eventos para o audioBlocked e audioUnblocked eventos disparados pelo Assinante para exibir e ocultar seu elemento de interface do usuário personalizado (indicando ao usuário que clique para reproduzir o áudio):

subscriber.on({
  audioBlocked: function(event) {
    // display custom UI
  },
  audioUnblocked: function(event) {
    // hide custom UI
  }
});

Quando o usuário clicar no seu elemento de interface de usuário personalizado, chame o OT.unblockAudio() método:

customElement.addEventListener('click', async () => {
  try {
    await OT.unblockAudio();
  } catch (err) {
    console.error('Unblocking audio failed.', err);
    return;
  }
  console.log('Unblocked audio successfully.');
});

Ajustar a interface do usuário quando o vídeo estiver ativado ou desativado

Ajustando a interface do usuário com base nos eventos do assinante

Um objeto Subscriber dispara os seguintes eventos relacionados à ativação ou desativação do vídeo na transmissão do assinante:

  • videoEnabled — Enviado quando o vídeo é ativado após ter sido desativado anteriormente.
  • videoDisabled — Enviado quando o vídeo for desativado. O reason A propriedade do objeto de evento indica o motivo pelo qual o vídeo foi desativado. (Esse objeto de evento é um Evento de alteração da ativação de vídeo objeto.)
  • videoDisableWarning — Enviado quando o OpenTok Media Router determina que a qualidade da transmissão se deteriorou e que o vídeo será desativado caso a qualidade se deteriore ainda mais. Se a qualidade se deteriorar ainda mais, o Assinante desativa o vídeo e envia um videoDisabled evento. Esse evento também pode ser disparado ao usar o recurso de fallback de áudio do emissor, caso a qualidade do stream do emissor seja prejudicada. Consulte o Guia do desenvolvedor sobre fallback de áudio.
  • videoDisableWarningLifted — O vídeo foi ativado depois de ter sido desativado anteriormente.

O videoDisableWarning e videoDisableWarningLifted os eventos só estão disponíveis em sessões que utilizam o Roteador de mídia OpenTok (sessões com o modo de mídia configurado como “routed”), a menos que se utilize o Recurso de alternativa de áudio do editor, onde os eventos estarão disponíveis em sessões transmitidas diretamente ou retransmitidas.

Por padrão, o Assinante exibe um indicador de aviso de vídeo desativado e um indicador de vídeo desativado quando o videoDisableWarning e videoDisableWarningLifted os eventos são acionados. É possível desativar a exibição padrão do indicador configurando o videoDisabledDisplayMode configuração de estilo do objeto Subscriber.

O exemplo a seguir utiliza o videoDisabledDisplayMode configuração de estilo para que o indicador de aviso de vídeo desativado e o indicador de vídeo desativado pisquem a cada segundo quando o videoDisableWarning e videoDisableWarningLifted os eventos são acionados:

const indicatorBlinker = new IndicatorBlinker(subscriber);

const IndicatorBlinker = function(subscriber) {
  const timer;
  const indicatorOn = false;
  subscriber.on({
    videoDisabled: function(event) {
      start();
    },
    videoDisableWarning: function(event) {
      start();
    },
    videoDisableWarningLifted: function(event) {
      stop();
    },
    videoEnabled: function(event) {
      stop();
    }
  });
  const start = function() {
    subscriber.setStyle('videoDisabledDisplayMode', 'on');
    if (timer) {
      clearInterval(timer);
    }
    timer = setInterval(function() {
      if (indicatorOn) {
        subscriber.setStyle('videoDisabledDisplayMode', 'off');
      } else {
        subscriber.setStyle('videoDisabledDisplayMode', 'on');
      }
      indicatorOn = !indicatorOn;
    }, 1000);
    indicatorOn = true;
  };
  const stop = function() {
    if (timer) {
      clearInterval(timer);
    }
  };
};

Você também pode definir o videoDisabledDisplayMode estilo para 'off' e adicione seus próprios elementos de interface de usuário com base no videoDisableWarning, videoDisabled, videoDisableWarningLifted, e videoEnabled eventos.

Ajustando a interface do usuário com base nos eventos do Publisher

Quando opção alternativa de áudio do editor Quando está ativado, o objeto Publisher dispara esses eventos em resposta a mudanças nas condições de qualidade:

  • videoDisableWarning — Enviado quando o editor constata que a qualidade da transmissão se deteriorou; o vídeo será desativado caso a qualidade se deteriore ainda mais.
  • videoDisableWarningLifted — Enviado quando o editor determinar que a qualidade da transmissão melhorou a ponto de o vídeo que está sendo desativado não representar mais um risco imediato.
  • videoDisabled — Enviado quando o Editor determina que a qualidade da transmissão se deteriorou e o transporte de vídeo de saída foi desativado. Observação: enquanto o vídeo estiver desativado, o Editor continua exibindo o vídeo do editor (como a imagem da câmera) na interface do usuário do cliente de publicação.
  • videoEnabled — Enviado com justificativa: quality quando o Editor determinar que a qualidade da transmissão melhorou e o transporte de vídeo de saída tiver sido reativado.

Por padrão, o Publisher exibe ícones quando o videoDisableWarning e videoDisabled ocorrem eventos.

O style propriedade do options parâmetro para OT.initPublisher() agora inclui um videoDisabledDisplayMode propriedade. Você pode definir a videoDisabledDisplayMode A atribuição dessa propriedade a um dos seguintes valores de string controla a forma como os elementos padrão da interface do usuário são exibidos:

  • auto (padrão) — Os ícones são exibidos automaticamente quando o vídeo está desativado ou corre o risco de ser desativado devido à baixa qualidade da transmissão.
  • off — Os ícones não são exibidos. Você pode exibir suas próprias notificações na interface do usuário com base nos eventos descritos acima.
  • on — Os ícones são exibidos automaticamente quando o vídeo é desativado ou corre o risco de ser desativado devido à baixa qualidade da transmissão.

Por exemplo, o código a seguir desativa os elementos padrão da interface de usuário relacionados ao vídeo desativado e lida com os eventos associados (para que você possa fornecer suas próprias notificações na interface de usuário):

// Enabled
const publisher = OT.initPublisher('target', {
  audioFallback: {
    publisher: true,
  },
  style: {
    videoDisabledDisplayMode: 'off',
  }
});

publisher.on({
  videoDisableWarning: () => {
    // Custom action — for example, add custom UI notification
  },
  videoDisableWarningLifted: () => {
    // Custom action — for example, remove custom UI notification
  },
  videoDisabled: () => {
    // Custom action — for example, add custom UI notification
  },
  videoEnabled: () => {
    // Custom action — for example, remove custom UI notification
  },
});

Você também pode definir o videoDisabledDisplayMode estilizar dinamicamente chamando a função Publisher.setStyle() método:

publisher.setStyle('videoDisabledDisplayMode', 'off');

// Alternately:

publisher.setStyle({
  videoDisabledDisplayMode: 'off',
  // other styles ...
});

Ocultar todos os controles integrados da interface do usuário para vídeos

Os objetos Publisher e Subscriber incluem os seguintes controles de interface de usuário integrados:

  • Exibição do nome do stream
  • O indicador de nível de áudio
  • O botão de silenciar o áudio
  • O indicador de vídeo desativado e o ícone de aviso de vídeo desativado (somente para assinantes)

Você pode desativar todas essas opções configurando o showControls propriedade para false no properties parâmetro que você passa para o OT.initPublisher() método ou o Session.subscribe() método.

Por exemplo, o código a seguir cria um objeto Publisher que não inclui controles de interface de usuário integrados:

const publisherOptions = {
     showControls: false
  };
const publisher = OT.initPublisher(
  'publisher-element-id', // Replace with the replacement element ID
  publisherOptions
);

O código a seguir cria um objeto Subscriber que não inclui controles de interface de usuário integrados:

const subscriberOptions = {
     showControls: false
  };
const subscriber = session.subscribe(stream,
  'subscriber-element-id', // Replace with the replacement element ID
  subscriberOptions
);

Você pode controlar a exibição de controles individuais da interface do usuário deixando o showControls propriedade definida como true (padrão); nesse caso, consulte estes tópicos:

Acesso direto ao elemento “Vídeo” para um Editor ou Assinante

É possível desativar os elementos padrão da interface do usuário para um Editor ou Assinante e acessar o HTML Video elemento diretamente. Ao publicar ou assinar um fluxo, defina o insertDefaultUI propriedade para false ao chamar o OT.initPublisher() ou Session.subscribe() método. Se você definir essa opção como false, o OpenTok.js não insere um elemento de interface do usuário padrão no DOM HTML, e o element A propriedade do objeto Publisher ou Subscriber está indefinida. Em vez disso, o elemento Publisher dispara um videoElementCreated evento em que o Video elemento é criado. O element A propriedade do objeto do evento é uma referência ao Video elemento. Adicione-o ao DOM HTML para exibir o vídeo.

O código a seguir inicializa um publisher e insere seu Video elemento no DOM HTML:

const publisher = OT.initPublisher({insertDefaultUI: false});
publisher.on('videoElementCreated', function(event) {
  document.getElementById('publisher-video-parent-id').appendChild(event.element);
});

O código a seguir assina um fluxo e insere seu Video elemento no DOM HTML:

const subscriber = session.subscribe(stream, {insertDefaultUI: false});
subscriber.on('videoElementCreated', function(event) {
  document.getElementById('subscriber-video-parent-id').appendChild(event.element);
});

Se você definir o insertDefaultUI propriedade para false, não defina o targetElement parâmetro ao chamar OT.initPublisher() ou Session.subscribe(). (Isso gera um erro.)

O elemento padrão da interface do usuário contém controles da interface, um indicador de carregamento de vídeo e o recorte automático do vídeo ou a exibição em formato letterbox, além do próprio vídeo. Se você deixar insertDefaultUI definir como true (padrão), você pode controlar as configurações individuais da interface do usuário usando o fitMode, showControls, e style opções. Consulte os outros tópicos desta página.

Você também pode acessar o objeto MediaStream de um assinante (e usá-lo em seu próprio Video elemento). Consulte a próxima seção.

Acesso a objetos do MediaStream para emissores e assinantes por meio da API do Media Stream Available

É possível acessar o objeto MediaStream monitorando o mediaStreamAvailable evento disparado por editores e assinantes. A API “Media Stream Available” foi disponibilizada na versão 2.27.7; as versões anteriores precisarão usar a Acesso a objetos MediaStream para assinantes em versões anteriores à 2.27.7 guia cujo link está abaixo.

Observações importantes:

  • Os objetos Publisher e Subscriber ainda devem ser usados para controlar todos os aspectos da Video API, como silenciar, desconectar e outros.
  • O áudio será reproduzido tanto pelo elemento personalizado quanto pelo widget do Editor ou do Assinante. Os elementos personalizados devem estar com o som desativado para evitar eco.
  • Os recursos do OpenTok para o Chrome, como a silhueta e os controles de vídeo, não estarão disponíveis.
  • O objeto MediaStream leva em conta quaisquer alterações causadas pelo roteamento adaptativo de mídia.

A seguir, apresentamos um exemplo dos hooks de contexto Session, Subscriber e Publisher do React utilizando a API Media Stream Available. Embora o exemplo utilize o React, a API Media Stream Available é independente de framework. Observe que o ouvinte deve ser acoplado imediatamente após a criação do publisher e dos subscribers, e não como parte do callback.

Componente de sessão

const [subscriberStream, setSubscriberStreams] = useState([]);
  async function subscribe(stream, session, options = {}) {
    if (session) {
      const subscriber = session.current.subscribe(stream, null, { ...options, insertDefaultUI: false });
      subscriber.on('mediaStreamAvailable', ({ mediaStream }) => {
        setSubscriberStreams((prev) => [...prev, { mediaStream, subscriber }]);
      });
    }
  }

Componente de assinante

import { useEffect, useRef } from 'react';

    const Subscriber = ({ subscriber, mediaStream }) => {
      const videoRef = useRef(null);

      useEffect(() => {
        if (mediaStream) {
          videoRef.current.srcObject = mediaStream;
        }
      }, [mediaStream]);

      return (
          <video
            ref={videoRef}
            autoPlay
            id={subscriber.streamId}
            playsInline
            muted
          ></video>
      );
    }

    export default Subscriber;

Componente de publicação

import { useEffect, useRef } from 'react';

    const Publisher = ({ publisher, mediaStream }) => {
      const videoRef = useRef(null);

      useEffect(() => {
        if (mediaStream) {
          videoRef.current.srcObject = mediaStream;
        }
      }, [mediaStream]);

      return (
          <video
            ref={videoRef}
            autoPlay
            id={publisher.streamId}
            playsInline
            muted
          ></video>
      );
    }

    export default Publisher;

Acesso a objetos MediaStream para assinantes em versões anteriores à 2.27.7

Observe que a API Media Stream Available, conforme descrito acima, é o método preferencial para acessar MediaStreams. Essa solução alternativa só é necessária nas versões do OpenTok anteriores à 2.27.7.

É possível acessar o objeto MediaStream utilizado por um assinante. O objeto HTMLVideoElement (no videoElementCreated evento disparado pelo Assinante, descrito na seção anterior), possui um srcObject propriedade. Este é o objeto MediaStream correspondente ao fluxo de áudio e vídeo do Assinante. Você pode usar esse objeto MediaStream como o MediaStream de origem para outro Video elemento (como seu srcObject propriedade):

session.on('streamCreated', function(event) {
  const subscriber = session.subscribe(event.stream, { insertDefaultUI: false });
  subscriber.on('videoElementCreated', event => {
    // myVideoElement is a Video element you have created:
    myVideoElement.srcObject = event.element.srcObject;
  });
});

Em uma sessão roteada que utiliza Roteamento Adaptativo de Mídia, o MediaStream de um assinante pode mudar quando a sessão passa de fluxos retransmitidos para fluxos roteados (consulte isto Artigo da base de conhecimento da Central de Ajuda). Adicione um ouvinte de evento para o play evento do elemento Video de um objeto Subscriber para obter a instância atualizada do MediaStream:

session.on('streamCreated', function(event) {
  const subscriber = session.subscribe(event.stream, { insertDefaultUI: false });
  subscriber.on('videoElementCreated', event => {
    // myVideoElement is a Video element you have created:
    myVideoElement.srcObject = event.element.srcObject;
    myVideoElement.play()
    event.element.addEventListener('play', () => {
      // The MediaStram has changed
      myVideoElement.srcObject = event.element.srcObject;
      myVideoElement.play();
    });
  });
});