O Chrome 66 permite que páginas da Web usem uma tela secundária anexada por meio do Presentation API e controlar seu conteúdo por meio do Presentation API Receiver.
![1/2. O usuário escolhe uma tela secundária anexada](https://developer.chrome.com/static/blog/present-web-pages-to-secondary-attached-displays/image/12-user-picks-secondar-03beeb097e67e.jpg?authuser=19&hl=pt)
![2/2. Uma página da Web é apresentada automaticamente na tela escolhida anteriormente](https://developer.chrome.com/static/blog/present-web-pages-to-secondary-attached-displays/image/22-web-page-is-automat-5dab3e95502c3.jpg?authuser=19&hl=pt)
Contexto
Até agora, os desenvolvedores Web podiam criar experiências em que um usuário veria o local conteúdo no Chrome diferente do que veria em um controle remoto e você pode controlar essa experiência localmente. Exemplos incluem gerenciar uma fila de reprodução no youtube.com enquanto os vídeos são reproduzidos na TV, ou ver um rolo de slides com anotações do apresentador em um laptop enquanto a tela apresentação é mostrada em uma sessão de Hangout.
No entanto, há cenários em que os usuários podem simplesmente querer apresentar conteúdo uma segunda tela conectada. Por exemplo, imagine um usuário em uma sala de conferências equipado com um projetor, ao qual eles são conectados por um cabo HDMI. Em vez de espelhar a apresentação em um endpoint remoto, o usuário quer apresentar os slides em tela cheia no projetor, sem deixar tela de laptop disponível para anotações do apresentador e controle de slides. Enquanto o site poderia dar suporte a isso de uma forma muito rudimentar (por exemplo, criando uma nova que o usuário precisa arrastar manualmente para a tela secundária e maximizar para tela cheia), é trabalhoso e oferece uma experiência experiência entre apresentação local e remota.
Apresentar uma página
Vamos ver como usar a API Presentation para apresentar uma página da Web. na tela secundária anexada. O resultado final está disponível em https://googlechrome.github.io/samples/presentation-api/.
Primeiro, vamos criar um novo objeto PresentationRequest
que vai conter o
URL que queremos apresentar na tela secundária anexada.
const presentationRequest = new PresentationRequest('receiver.html');
In this article, I won’t cover use cases where the parameter passed to
`PresentationRequest` can be an array like `['cast://foo’, 'apple://foo',
'https://example.com']` as this is not relevant there.
We can now monitor presentation display availability and toggle a "Present"
button visibility based on presentation displays availability. Note that we can
also decide to always show this button.
<aside class="caution"><b>Caution:</b> The browser may use more energy while the <code>availability</code> object is alive
and actively listening for presentation display availability changes. Please
use it with caution in order to save energy on mobile.</aside>
```js
presentationRequest.getAvailability()
.then(availability => {
console.log('Available presentation displays: ' + availability.value);
availability.addEventListener('change', function() {
console.log('> Available presentation displays: ' + availability.value);
});
})
.catch(error => {
console.log('Presentation availability not supported, ' + error.name + ': ' +
error.message);
});
A exibição de um prompt de exibição de apresentação exige um gesto do usuário, como um clique
em um botão. Então, vamos chamar presentationRequest.start()
com o clique de um botão e
aguardar a promessa ser resolvida depois que o usuário seleciona uma apresentação.
display (por exemplo, uma tela secundária conectada no nosso caso de uso).
function onPresentButtonClick() {
presentationRequest.start()
.then(connection => {
console.log('Connected to ' + connection.url + ', id: ' + connection.id);
})
.catch(error => {
console.log(error);
});
}
A lista apresentada ao usuário também pode incluir endpoints remotos, como dispositivos Chromecast, caso estejam conectados a uma rede que os anuncie. Observe que telas espelhadas não estão na lista. Consulte http://crbug.com/840466 (link em inglês).
![Seletor de exibição de apresentação](https://developer.chrome.com/static/blog/present-web-pages-to-secondary-attached-displays/image/presentation-display-pick-6b14dbd5ed08c.png?authuser=19&hl=pt)
Quando a promessa for resolvida, a página da Web no URL do objeto PresentationRequest
será
apresentadas na tela escolhida. Et voilà!
Agora podemos ir mais longe e monitorar a "conclusão" e "encerrar" eventos conforme mostrado
a seguir. É possível reconectar a uma rede
presentationConnection
com presentationRequest.reconnect(presentationId)
em que presentationId
é o ID do objeto presentationRequest
anterior.
function onCloseButtonClick() {
// Disconnect presentation connection but will allow reconnection.
presentationConnection.close();
}
presentationConnection.addEventListener('close', function() {
console.log('Connection closed.');
});
function onTerminateButtonClick() {
// Stop presentation connection for good.
presentationConnection.terminate();
}
presentationConnection.addEventListener('terminate', function() {
console.log('Connection terminated.');
});
Comunicar-se com a página
Agora você está pensando: "Tudo bem, mas como faço para transmitir mensagens entre
página de controlador (a que acabamos de criar) e a página receptora (aquela que
transmitidos para o objeto PresentationRequest
)?
Primeiro, vamos recuperar as conexões existentes na página receptora com
navigator.presentation.receiver.connectionList
e ouvir os recebidos
conforme mostrado abaixo.
// Receiver page
navigator.presentation.receiver.connectionList
.then(list => {
list.connections.map(connection => addConnection(connection));
list.addEventListener('connectionavailable', function(event) {
addConnection(event.connection);
});
});
function addConnection(connection) {
connection.addEventListener('message', function(event) {
console.log('Message: ' + event.data);
connection.send('Hey controller! I just received a message.');
});
connection.addEventListener('close', function(event) {
console.log('Connection closed!', event.reason);
});
}
Uma conexão que recebe uma mensagem dispara uma "mensagem" que você pode ouvir.
A mensagem pode ser uma string, um Blob, um ArrayBuffer ou um ArrayBufferView.
O envio é tão simples quanto chamar connection.send(message)
pelo
controladora ou página receptora.
// Controller page
function onSendMessageButtonClick() {
presentationConnection.send('Hello!');
}
presentationConnection.addEventListener('message', function(event) {
console.log('I just received ' + event.data + ' from the receiver.');
});
Jogue com a amostra em https://googlechrome.github.io/samples/presentation-api/ para ter uma noção do como ele funciona. Tenho certeza de que você vai gostar disso tanto quanto eu.
Exemplos e demonstrações
Confira o exemplo oficial do Chrome que usamos para este artigo.
Também recomendo conferir a demonstração interativa do Photowall. Esse app da Web permite vários controles para apresentar de forma colaborativa uma apresentação de slides uma tela de apresentação. O código está disponível em https://github.com/GoogleChromeLabs/presentation-api-samples.
![Captura de tela da demonstração do Photowall](https://developer.chrome.com/static/blog/present-web-pages-to-secondary-attached-displays/image/photowall-demo-screenshot-10527faacc264.jpg?authuser=19&hl=pt)
Mais uma coisa
O Chrome tem a opção "Transmitir" que os usuários do menu do navegador podem invocar a qualquer momento ao visitar um
site. Se você quiser controlar a apresentação padrão desse menu,
atribuir navigator.presentation.defaultRequest
a um
Objeto presentationRequest
criado anteriormente.
// Make this presentation the default one when using the "Cast" browser menu.
navigator.presentation.defaultRequest = presentationRequest;
Dicas para desenvolvedores
Para inspecionar e depurar a página receptora, acesse o
chrome://inspect
página, selecione "Outros" e clique no link "inspecionar" ao lado de
o URL apresentado no momento.
![Inspecionar páginas do receptor de apresentações](https://developer.chrome.com/static/blog/present-web-pages-to-secondary-attached-displays/image/inspect-presentation-rece-260dbbca83182.png?authuser=19&hl=pt)
Confira também o chrome://media-router-internals
interno
para conhecer os processos internos de descoberta/disponibilidade.
A seguir
A partir do Chrome 66, as plataformas ChromeOS, Linux e Windows serão compatíveis. Mac o suporte virá mais tarde.
Recursos
- Status do recurso do Chrome: https://www.chromestatus.com/features#presentation%20api
- Bugs de implementação: https://crbug.com/?q=component:Blink>PresentationAPI
- Especificação da API Presentation: https://w3c.github.io/presentation-api/
- Problemas com especificações: https://github.com/w3c/presentation-api/issues (em inglês)