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 as dimensões iniciais de um vídeo
- Redimensionar ou reposicionar um vídeo
- Adicionar um nome a um stream publicado
- Exibir ou ocultar o nome em um vídeo
- Exibir ou ocultar o botão de silenciar o áudio
- Ajustando o recorte do vídeo e o formato letterbox
- Capturar um quadro de um vídeo
- Configurar uma imagem para ser exibida no modo somente áudio
- Ajuste da interface do usuário com base nos níveis de áudio
- Exibição de um elemento de interface do usuário personalizado quando o áudio do assinante estiver bloqueado
- Ajustar a interface do usuário quando o vídeo estiver ativado ou desativado
- Ocultar todos os controles integrados da interface do usuário para vídeos
- Acesso direto ao elemento de vídeo para um Editor ou Assinante
- Acesso a objetos MediaStream por meio da API Media Stream Available
- Acesso a objetos MediaStream para assinantes
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. OreasonA 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 umvideoDisabledevento. 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:qualityquando 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:
- Exibir ou ocultar o nome em um vídeo
- Exibir ou ocultar o botão de silenciar o áudio
- Detectar quando o vídeo de um assinante está desativado
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();
});
});
});