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

프랑수아 보포르
프랑수아 보포르

Chrome 66에서는 웹페이지에서 프레젠테이션 API를 통해 보조 연결 디스플레이를 사용하고 프레젠테이션 수신기 API를 통해 콘텐츠를 제어할 수 있습니다.

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

배경

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

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

페이지 표시

프레젠테이션 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 기기를 광고하는 네트워크에 연결된 경우 사용자에게 표시되는 목록에는 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);
  });
}

메시지를 수신하는 연결은 수신 대기할 수 있는 "message" 이벤트를 실행합니다. 메시지는 문자열, 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 지원은 나중에 제공될 예정입니다.

자료