在次要附加的螢幕上顯示網頁

François Beaufort
François Beaufort

Chrome 66 允許網頁透過 Presentation API 使用次要附屬螢幕,並透過 Presentation Receiver API 控管內容。

1/2. 使用者選擇次要連接螢幕
1/2. 使用者選擇次要連接螢幕
2/2。網頁會自動顯示在先前所選的顯示畫面中
2/2. 網頁會自動顯示在先前選取的螢幕上

背景

目前,網頁開發人員可以建構體驗,讓使用者在 Chrome 中查看與遠端顯示內容不同的本機內容,同時仍可在本機控管這項體驗。例如,在在電視上播放影片時管理 youtube.com 上的播放佇列,或是在電腦上觀看含有演講者備忘稿的投影片膠卷,而 Hangouts 工作階段會以全螢幕顯示畫面。

在某些情況下,使用者可能會只想將內容顯示在附加的螢幕上。舉例來說,假設有位使用者在會議室中裝有投影機,而對方透過 HDMI 傳輸線連接了投影機。使用者不想將簡報複製到遠端端點,而是希望透過投影機以全螢幕播放投影片,讓筆記型電腦螢幕可用於演講者備忘稿和投影片控制。雖然網站作者可以透過非常明確的方式支援這項功能 (例如彈出新視窗,使用者必須手動將視窗拖曳至次要螢幕並最大化為全螢幕),但這會很麻煩,且在本機和遠端簡報間提供不一致的體驗。

分享頁面

以下將為您逐步介紹如何使用 Presentation API,在次要連接螢幕上播放網頁。最終結果可在 https://googlechrome.github.io/samples/presentation-api/ 找到。

首先,我們要建立新的 PresentationRequest 物件,其中包含要在次要連接螢幕上呈現的網址。

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

使用者需透過手勢 (例如點選按鈕) 才能顯示簡報顯示提示。因此,我們要在按鈕點擊時呼叫 presentationRequest.start(),並等待使用者選取簡報畫面後 (例如本用途中的次要附加螢幕),等待承諾解決。

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

如果您連線至宣傳網路的網路,使用者看到的清單也可能包含遠端端點 (例如 Chromecast 裝置)。請注意,鏡像螢幕不在清單中。請參閱 http://crbug.com/840466

簡報顯示選擇器
簡報顯示挑選器

承諾解析時,PresentationRequest 物件網址的網頁將顯示為所選顯示畫面。呃,

我們現在可以進一步監控「關閉」和「終止」事件,如下所示。請注意,您可以使用 presentationRequest.reconnect(presentationId) 重新連線至「已關閉」的 presentationConnection,其中 presentationId 是前一個 presentationRequest 物件的 ID。

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

與頁面溝通

您現在認為這樣做很好,但該如何在控制器頁面 (我們剛才建立的網頁) 與接收端頁面 (我們傳遞至 PresentationRequest 物件) 之間傳遞訊息?

首先,讓我們使用 navigator.presentation.receiver.connectionList 在接收器頁面中擷取現有連線,並監聽傳入的連線,如下所示。

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

接收訊息的連線會觸發您可以監聽的「訊息」事件。訊息可以是字串、Blob、ArrayBuffer 或 ArrayBufferView。 傳送方法很簡單,只要從控制器頁面或接收器頁面呼叫 connection.send(message) 即可。

// Controller page

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

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

您可以試用 https://googlechrome.github.io/samples/presentation-api/ 範例,以瞭解其運作方式。我相信您可以和我一樣樂在其中。

範例與示範

歡迎查看本文所使用的 Chrome 官方範例

建議您也使用互動式 Photowall 示範。這個網頁應用程式可讓多個控制器在簡報顯示器上,共同進行相片投影播放。您可以前往 https://github.com/GoogleChromeLabs/presentation-api-samples 取得程式碼。

Photowall 示範螢幕截圖
José Luis Mieza 的 相片 / CC BY-NC-SA 2.0

還有一件事

Chrome 提供「投放」瀏覽器選單,使用者造訪網站時可以隨時叫用。如要控管這個選單的預設呈現方式,請將 navigator.presentation.defaultRequest 指派給先前建立的自訂 presentationRequest 物件。

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

開發人員提示

如要檢查接收器頁面並進行偵錯,請前往內部 chrome://inspect 頁面,選取「其他」,然後按一下目前顯示網址旁的「檢查」連結。

檢查簡報接收器頁面
檢查簡報接收器頁面

您也可以查看內部 chrome://media-router-internals 頁面,深入瞭解內部探索/可用性程序。

後續步驟

自 Chrome 66 起,我們支援 ChromeOS、Linux 和 Windows 平台。我們將在稍後支援 Mac。

資源