Presentare pagine web su display secondari collegati

Francesco Beaufort
François Beaufort

Chrome 66 consente alle pagine web di utilizzare un display collegato secondario tramite l'API Presentation e di controllarne i contenuti tramite l'API PresentationReceivedr.

1/2 L'utente sceglie un display secondario collegato
1/2. L'utente sceglie un display secondario collegato
2/2. Viene visualizzata automaticamente una pagina web nella visualizzazione selezionata in precedenza
2/2. Viene visualizzata automaticamente una pagina web nella visualizzazione selezionata in precedenza.

Contesto

Finora, gli sviluppatori web potevano creare esperienze in cui gli utenti visualizzavano contenuti locali in Chrome diversi da quelli visualizzati su un display remoto, pur potendo controllare quell'esperienza localmente. Alcuni esempi includono la gestione di una coda di riproduzione su youtube.com durante la riproduzione dei video sulla TV o la visualizzazione di una bobina di slide con le note del relatore su un laptop mentre la presentazione a schermo intero viene mostrata in una sessione di Hangout.

Esistono però casi in cui gli utenti potrebbero voler semplicemente presentare i contenuti su un secondo display collegato. Ad esempio, immagina un utente in una sala conferenze attrezzata con un proiettore a cui è collegato tramite un cavo HDMI. Anziché eseguire il mirroring della presentazione su un endpoint remoto, l'utente vuole davvero presentare le slide a schermo intero sul proiettore, lasciando disponibile lo schermo del laptop per le note del relatore e il controllo delle slide. Sebbene l'autore del sito possa supportare questa funzionalità in modo molto rudimentale (ad esempio, aprendo una nuova finestra, che l'utente deve poi trascinare manualmente sul display secondario e ingrandirla a schermo intero), è difficile e offre un'esperienza incoerente tra la presentazione locale e quella remota.

Presentare una pagina

Vediamo come utilizzare l'API Presentazione per presentare una pagina web sul display secondario collegato. Il risultato finale è disponibile all'indirizzo https://googlechrome.github.io/samples/presentation-api/.

Innanzitutto, creeremo un nuovo oggetto PresentationRequest che conterrà l'URL da presentare sul display collegato secondario.

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);
  });

Per mostrare un prompt di visualizzazione della presentazione è necessario un gesto dell'utente, ad esempio un clic su un pulsante. Chiamiamo quindi presentationRequest.start() con un clic su un pulsante e attendiamo che la promessa venga risolta dopo che l'utente ha selezionato una visualizzazione della presentazione (ad esempio, un display collegato secondario nel nostro caso d'uso).

function onPresentButtonClick() {
  presentationRequest.start()
  .then(connection => {
    console.log('Connected to ' + connection.url + ', id: ' + connection.id);
  })
  .catch(error => {
    console.log(error);
  });
}

L'elenco presentato all'utente potrebbe anche includere endpoint remoti, come i dispositivi Chromecast se è collegata a una rete che li pubblicizza. Tieni presente che i display speculari non sono nell'elenco. Visita la pagina http://crbug.com/840466.

Selettore visualizzazione presentazione
Selettore della visualizzazione della presentazione

Quando la promessa si risolve, la pagina web all'URL dell'oggetto PresentationRequest viene presentata alla visualizzazione scelta. E voilà!

Ora possiamo andare oltre e monitorare gli eventi "chiusura" e "terminazione" come mostrato di seguito. Tieni presente che è possibile riconnetterti a un elemento presentationConnection "chiuso" con presentationRequest.reconnect(presentationId), dove presentationId è l'ID dell'oggetto presentationRequest precedente.

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.');
});

Comunicare con la pagina

Stai pensando, va bene, ma come posso passare i messaggi tra la pagina del controller (quella che abbiamo appena creato) e la pagina del destinatario (quella che abbiamo passato all'oggetto PresentationRequest)?

Innanzitutto, recuperiamo le connessioni esistenti nella pagina del destinatario con navigator.presentation.receiver.connectionList e ascoltiamo le connessioni in entrata come mostrato di seguito.

// 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);
  });
}

Una connessione che riceve un messaggio attiva un evento "messaggio" che puoi ascoltare. Il messaggio può essere una stringa, un Blob, un ArrayBuffer o un ArrayBufferView. Inviare l'email è semplice come chiamare connection.send(message) dalla pagina del controller o dalla pagina del destinatario.

// Controller page

function onSendMessageButtonClick() {
  presentationConnection.send('Hello!');
}

presentationConnection.addEventListener('message', function(event) {
  console.log('I just received ' + event.data + ' from the receiver.');
});

Guarda l'esempio all'indirizzo https://googlechrome.github.io/samples/presentation-api/ per avere un'idea di come funziona. Sicuramente ti piacerà quanto piace a me.

Esempi e demo

Dai un'occhiata all'esempio ufficiale di Chrome che abbiamo utilizzato per questo articolo.

Ti consiglio anche la demo interattiva di Photowall. Questa applicazione web consente a più controller di presentare in collaborazione una slideshow di foto su un display per presentazioni. Il codice è disponibile all'indirizzo https://github.com/GoogleChromeLabs/presentation-api-samples.

Screenshot della demo di Photowall
Foto di José Luis Mieza/ CC BY-NC-SA 2.0

Un'ultima cosa

Chrome ha un menu del browser "Trasmetti" che gli utenti possono richiamare in qualsiasi momento mentre visitano un sito web. Se vuoi controllare la presentazione predefinita per questo menu, assegna navigator.presentation.defaultRequest a un oggetto presentationRequest personalizzato creato in precedenza.

// Make this presentation the default one when using the "Cast" browser menu.
navigator.presentation.defaultRequest = presentationRequest;

Suggerimenti per sviluppatori

Per esaminare la pagina del destinatario ed eseguirne il debug, vai alla pagina chrome://inspect interna, seleziona "Altro" e fai clic sul link "Controlla" accanto all'URL attualmente presentato.

Ispeziona le pagine del destinatario della presentazione
Esamina le pagine del destinatario della presentazione

Puoi anche consultare la pagina chrome://media-router-internals interna per informazioni sui processi interni di scoperta/disponibilità.

Passaggi successivi

A partire da Chrome 66, sono supportate le piattaforme ChromeOS, Linux e Windows. Il supporto Mac sarà più avanti.

Risorse