Chrome 66 umożliwia stronom internetowym korzystanie z dodatkowego podłączonego wyświetlacza za pomocą interfejsu Presentation API i kontrolowanie ich zawartości za pomocą interfejsu Presentation Visitr API.
Wprowadzenie
Do tej pory programiści stron internetowych mogli tworzyć rozwiązania, w których użytkownicy mogli zobaczyć w Chrome treści lokalne inne niż te na zdalnym wyświetlaczu, a jednocześnie mogli je kontrolować lokalnie. Może to być na przykład zarządzanie kolejką odtwarzania na youtube.com podczas odtwarzania filmów na telewizorze lub wyświetlanie slajdu z notatkami na laptopie, gdy wyświetlana jest prezentacja pełnoekranowa podczas sesji Hangouts.
Istnieją jednak sytuacje, w których użytkownicy mogą po prostu zechcieć wyświetlić zawartość na drugim, podłączonym wyświetlaczu. Wyobraź sobie na przykład, że użytkownik w sali konferencyjnej wyposażony jest w projektor, do którego jest podłączony kablem HDMI. Zamiast powielać prezentację w zdalnym punkcie końcowym użytkownik chce wyświetlić slajdy na pełnym ekranie za pomocą projektora, pozostawiając ekran laptopa, na którym można zapisywać notatki i sterować slajdami. Choć autor witryny może obsługiwać to w bardzo prosty sposób (np. wyskakując nowe okno, które użytkownik musi następnie ręcznie przeciągnąć na dodatkowy ekran i maksymalizować do pełnego ekranu), jest to niewygodne i zapewnia niespójności między prezentacją lokalną i zdalną.
Zaprezentuj stronę
Przyjrzyjmy się teraz, jak za pomocą interfejsu Presentation API wyświetlać stronę internetową na dodatkowym podłączonym wyświetlaczu. Wynik jest dostępny na stronie https://googlechrome.github.io/samples/presentation-api/.
Najpierw utworzymy nowy obiekt PresentationRequest
zawierający adres URL, który chcemy prezentować na podłączonym drugim wyświetlaczu.
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);
});
Wyświetlenie promptu na ekranie prezentacji wymaga gestu użytkownika, takiego jak kliknięcie przycisku. Wywołajmy presentationRequest.start()
po kliknięciu przycisku i poczekaj na zakończenie obietnicy, gdy użytkownik wybierze wyświetlacz prezentacji (w naszym przypadku będzie to dodatkowy podłączony wyświetlacz).
function onPresentButtonClick() {
presentationRequest.start()
.then(connection => {
console.log('Connected to ' + connection.url + ', id: ' + connection.id);
})
.catch(error => {
console.log(error);
});
}
Lista prezentowana użytkownikowi może też zawierać zdalne punkty końcowe, takie jak urządzenia Chromecast, jeśli masz połączenie z siecią, która je reklamuje. Pamiętaj, że wyświetlaczy lustrzanych nie ma na liście. Wejdź na http://crbug.com/840466.
Gdy obietnica się zakończy, w wybranym elemencie displayowym będzie wyświetlana strona internetowa znajdująca się pod adresem URL obiektu PresentationRequest
. Gotowe!
Możemy teraz przejść dalej i monitorować zdarzenia zamknięcia oraz zakończenia, jak pokazano poniżej. Pamiętaj, że możesz ponownie połączyć się z „zamkniętym” obiektem presentationConnection
z parametrem 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.');
});
Komunikacja ze stroną
Myślisz, że to dobrze, ale jak przekazywać wiadomości między moją stroną kontrolera (tę, którą właśnie utworzyliśmy) a stroną odbierającą (tą, która została przekazana do obiektu PresentationRequest
)?
Zacznijmy od pobrania istniejących połączeń na stronie odbiorcy z adresem navigator.presentation.receiver.connectionList
i odsłuchania połączeń przychodzących, tak jak to 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 odbierające wiadomość uruchamia zdarzenie „wiadomość”, którego możesz nasłuchiwać.
Wiadomość może być ciągiem znaków, obiektem blob, obiektem SlateBuffer lub widokiem SlateBufferView.
Wysłanie jest tak proste, jak wywołanie connection.send(message)
ze strony kontrolera lub strony odbiorcy.
// Controller page
function onSendMessageButtonClick() {
presentationConnection.send('Hello!');
}
presentationConnection.addEventListener('message', function(event) {
console.log('I just received ' + event.data + ' from the receiver.');
});
Zobacz przykład na stronie https://googlechrome.github.io/samples/presentation-api/, aby zobaczyć, jak to działa. Na pewno spodoba Ci się to tak samo jak mi.
Sample i prezentacje
Zobacz oficjalną próbkę Chrome, którą użyliśmy w tym artykule.
Polecam też interaktywną prezentację funkcji Photowall. Ta aplikacja internetowa umożliwia wielu kontrolerom wspólne prezentowanie pokazu slajdów na wyświetlaczu prezentacji. Kod jest dostępny na stronie https://github.com/GoogleChromeLabs/presentation-api-samples.
Jeszcze jedno
Chrome ma menu „Przesyłaj”, które użytkownicy mogą wywołać w dowolnej chwili na stronie internetowej. Jeśli chcesz kontrolować domyślną prezentację w tym menu, przypisz navigator.presentation.defaultRequest
do niestandardowego obiektu presentationRequest
utworzonego wcześniej.
// 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 ją debugować, wejdź na wewnętrzną stronę chrome://inspect
, wybierz „Inne” i kliknij link „sprawdź” obok obecnie wyświetlanego adresu URL.
Możesz też zajrzeć na wewnętrzną stronę chrome://media-router-internals
, na której znajdziesz więcej informacji o wewnętrznych procesach odkrywania i dostępności.
Co dalej
Od Chrome 66 obsługiwane są platformy Chrome OS, Linux i Windows. Obsługa komputerów Mac pojawi się później.
Zasoby
- Stan funkcji Chrome: https://www.chromestatus.com/features#presentation%20api
- Błędy implementacji: https://crbug.com/?q=component:Blink>PresentationAPI
- Specyfikacja interfejsu Prezentacja API: https://w3c.github.io/presentation-api/
- Problemy ze specyfikacją: https://github.com/w3c/presentation-api/issues