Wyświetlanie stron internetowych na dodatkowych podłączonych wyświetlaczach

François Beaufort
François Beaufort

Chrome 66 umożliwia stronom internetowym korzystanie z dodatkowego wyświetlacza za pomocą interfejsu Presentation API oraz kontrolowanie jego zawartości za pomocą interfejsu Presentation Receiver API.

1/2. Użytkownik wybiera dodatkowy podłączony wyświetlacz
1/2. Użytkownik wybiera dodatkowy wyświetlacz
2/2. Strona internetowa jest automatycznie wyświetlana na wyświetlaczu wybranym wcześniej.
2/2. Strona internetowa jest automatycznie wyświetlana na wcześniej wybranym wyświetlaczu.

Tło

Do tej pory deweloperzy internetowi mogli tworzyć treści, w których użytkownik widzi w Chrome treści lokalne inne niż te, które widzi na zewnętrznym wyświetlaczu, a nadal może kontrolować te treści lokalnie. Przykłady takich działań to zarządzanie kolejką odtwarzania na stronie youtube.com podczas odtwarzania filmów na telewizorze lub wyświetlanie prezentacji z notatkami na laptopie podczas wyświetlania prezentacji na pełnym ekranie w sesji Hangout.

Czasami jednak użytkownicy chcą po prostu wyświetlić treści na drugim, podłączonym ekranie. Wyobraź sobie na przykład użytkownika w sali konferencyjnej wyposażonej w projektor, z którym jest połączony za pomocą kabla HDMI. Zamiast dublować prezentację na zdalnym urządzeniu końcowym, użytkownik chce wyświetlić slajdy na pełnym ekranie projektora, pozostawiając ekran laptopa do wyświetlania notatek i sterowania slajdami. Autor strony może udostępnić tę funkcję w bardzo prymitywny sposób (np. wyświetlając nowe okno, które użytkownik musi ręcznie przeciągnąć na dodatkowy wyświetlacz i zmaksymalizować do pełnego ekranu), ale jest to kłopotliwe i nie zapewnia spójnego środowiska podczas prezentacji lokalnej i zdalnej.

Prezentowanie strony

Pokażę Ci, jak za pomocą interfejsu Presentation API wyświetlić stronę internetową na dodatkowym ekranie. Wynik końcowy jest dostępny na stronie https://googlechrome.github.io/samples/presentation-api/.

Najpierw utworzymy nowy obiekt PresentationRequest, który będzie zawierać adres URL, który chcemy wyświetlać na dodatkowym wyświetlaczu.

const presentationRequest = new PresentationRequest('receiver.html');

In this article, I wont 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);
  });

Wyświetlenie promptu wyświetlania prezentacji wymaga od użytkownika wykonania czynności, takiej jak kliknięcie przycisku. Zatem wywołajmy funkcję presentationRequest.start() po kliknięciu przycisku i poczekajmy, aż obietnica zostanie spełniona, gdy użytkownik wybierze wyświetlacz prezentacji (np. dodatkowy podłączony wyświetlacz w naszym przypadku użycia).

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

Lista wyświetlana użytkownikowi może też zawierać odległe punkty końcowe, takie jak Chromecasty, jeśli jesteś połączony z siecią reklamującą te urządzenia. Pamiętaj, że wyświetlacze z odbiciem lustrzanym nie są uwzględniane na liście. Zobacz http://crbug.com/840466.

Selektor wyświetlania prezentacji
Menu wyboru wyświetlania prezentacji

Gdy obietnica zostanie spełniona, wybrany wyświetlacz wyświetli stronę internetową pod adresem URL obiektu PresentationRequest. Et voilà!

Możemy teraz przejść dalej i monitorować zdarzenia „close” (zamknięcie) i „terminate” (zakończenie), jak pokazano poniżej. Pamiętaj, że można ponownie połączyć „zamknięty” obiekt presentationConnection z obiektem presentationRequest.reconnect(presentationId), gdzie presentationId to identyfikator poprzedniego obiektu presentationRequest.

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

Kontakt z tą stroną

Teraz myślisz sobie: „To fajne, ale jak mogę przekazywać wiadomości między stroną kontrolera (która została właśnie utworzona) a stroną odbiorcy (która została przekazana do obiektu PresentationRequest)?”.

Najpierw pobierz istniejące połączenia na stronie odbiorcy za pomocą funkcjinavigator.presentation.receiver.connectionList i nasłuchuj przychodzące połączenia, jak pokazano poniżej.

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

Połączenie otrzymujące wiadomość powoduje wywołanie zdarzenia „message”, na które możesz się zarejestrować. Wiadomość może być ciągiem znaków, obiektem Blob, tablicą ArrayBuffer lub obiektem ArrayBufferView. Wystarczy wywołać funkcję connection.send(message) na stronie kontrolera lub stronie odbiornika.

// Controller page

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

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

Aby poznać działanie interfejsu API, wypróbuj przykładowy projekt na stronie https://googlechrome.github.io/samples/presentation-api/. Mam nadzieję, że spodoba Ci się to tak samo jak mnie.

Sample i wersje demonstracyjne

Zapoznaj się z oficjalnym przykładem kodu Chrome, którego użyliśmy w tym artykule.

Polecam też interaktywne demo Photowall. Ta aplikacja internetowa umożliwia wielu kontrolerom wspólne wyświetlanie pokazu slajdów na ekranie prezentera. Kod jest dostępny pod adresem https://github.com/GoogleChromeLabs/presentation-api-samples.

Zrzut ekranu z prezentacji fototapety
Zdjęcie autorstwa José Luis Mieza / CC BY-NC-SA 2.0

Jeszcze jedno

Chrome ma menu „Cast”, które użytkownicy mogą wywołać w dowolnym momencie podczas wizyty w witrynie. Jeśli chcesz kontrolować domyślną prezentację tego menu, przypisz navigator.presentation.defaultRequest do utworzonego wcześniej niestandardowego obiektu presentationRequest.

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

Wskazówki dla programistów

Aby sprawdzić stronę odbiorcy i przeprowadzić jej debugowanie, otwórz wewnętrzną stronę chrome://inspect, wybierz „Inne” i kliknij link „Sprawdź” obok aktualnie wyświetlanego adresu URL.

Sprawdzanie stron odbiorczych prezentacji
Sprawdzanie stron odbiorców prezentacji

Warto też zapoznać się z informacjami na wewnętrznej stronie chrome://media-router-internals, aby dowiedzieć się więcej o procesach wyszukiwania i dostępności.

Co dalej?

Od wersji 66 Chrome obsługuje platformy ChromeOS, Linux i Windows. Wsparcie dla użytkowników Mac będzie dostępne w późniejszym terminie.

Zasoby