보조 연결 디스플레이에 웹페이지 표시

François Beaufort
François Beaufort

Chrome 66을 사용하면 웹페이지에서 Presentation API를 통해 보조 연결 디스플레이를 사용하고 Presentation Receiver API를 통해 콘텐츠를 제어할 수 있습니다.

1/2. 사용자가 보조 연결된 디스플레이를 선택
1월 2일 사용자가 보조 연결된 디스플레이를 선택
2월 2일 이전에 선택한 디스플레이에 웹페이지가 자동으로 표시됩니다.
2월 2일 이전에 선택한 디스플레이에 웹페이지가 자동으로 표시됩니다.

배경

지금까지 웹 개발자는 사용자가 원격 디스플레이에서 보는 콘텐츠와 다른 로컬 콘텐츠를 Chrome에서 보는 환경을 빌드하면서 로컬에서 이러한 환경을 계속 제어할 수 있었습니다. 예를 들어 TV에서 동영상이 재생되는 동안 youtube.com에서 재생 대기열을 관리하거나 전체 화면 프레젠테이션이 행아웃 세션에서 표시될 때 노트북에서 발표자 노트가 포함된 슬라이드 릴을 표시하는 것을 들 수 있습니다.

하지만 사용자가 단순히 두 번째 연결된 디스플레이에 콘텐츠를 표시하고 싶어 하는 시나리오도 있습니다. 예를 들어 프로젝터가 장착된 회의실에 있는 사용자가 HDMI 케이블을 통해 연결된다고 상상해 보세요. 프레젠테이션을 원격 엔드포인트에 미러링하는 대신 사용자는 슬라이드를 전체 화면으로 프로젝터에서 보고 노트북 화면에서 발표자 노트와 슬라이드 제어를 사용하고 싶어 합니다. 사이트 작성자는 매우 기본적인 방식으로 이를 지원할 수 있지만 (예: 사용자가 수동으로 보조 디스플레이로 드래그하여 전체 화면으로 확대해야 하는 새 창을 열 수 있음), 이는 번거롭고 로컬 프레젠테이션과 원격 프레젠테이션 간에 일관되지 않은 환경을 제공합니다.

페이지 표시

Presentation API를 사용하여 보조 연결 디스플레이에 웹페이지를 표시하는 방법을 안내해 드리겠습니다. 최종 결과는 https://googlechrome.github.io/samples/presentation-api/에서 확인할 수 있습니다.

먼저 보조 연결된 디스플레이에 표시할 URL을 포함하는 새 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 객체 URL의 웹페이지가 선택한 디스플레이에 표시됩니다. 끝났습니다!

이제 아래와 같이 'close' 및 'terminate' 이벤트를 모니터링할 수 있습니다. 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 데모 스크린샷
사진 , 호세 루이스 미에자/ CC BY-NC-SA 2.0

한 가지 더 알려드릴 사항이 있습니다

Chrome에는 사용자가 웹사이트를 방문하는 동안 언제든지 호출할 수 있는 '전송' 브라우저 메뉴가 있습니다. 이 메뉴의 기본 표시를 제어하려면 이전에 만든 맞춤 presentationRequest 객체에 navigator.presentation.defaultRequest를 할당합니다.

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

개발자 도움말

수신자 페이지를 검사하고 디버그하려면 내부 chrome://inspect 페이지로 이동하여 '기타'를 선택한 다음 현재 표시된 URL 옆의 '검사' 링크를 클릭합니다.

프레젠테이션 수신자 페이지 검사
프레젠테이션 수신자 페이지 검사

내부 chrome://media-router-internals 페이지에서 내부 검색/가용성 프로세스를 자세히 알아볼 수도 있습니다.

다음 단계

Chrome 66부터 ChromeOS, Linux, Windows 플랫폼이 지원됩니다. Mac 지원은 나중에 제공될 예정입니다.

리소스