웹 전송 앱에 Cast SDK 통합

이 개발자 가이드에서는 Cast SDK를 사용하여 웹 발신기 앱에 Google Cast 지원을 추가하는 방법을 설명합니다.

용어

휴대기기 또는 브라우저는 재생을 보내는 발신자이며 Google Cast 기기는 재생할 수 있는 화면의 콘텐츠를 표시하는 수신자입니다.

웹 발신자 SDK는 Framework API(cast.framework)와 Base API(chrome.cast)의 두 부분으로 구성됩니다. 일반적으로 더 단순한 상위 수준 Framework API에서 호출을 실행한 다음 하위 수준 Base API에서 처리합니다.

발신자 프레임워크는 하위 수준 기능에 대한 래퍼를 제공하는 프레임워크 API, 모듈 및 관련 리소스를 의미합니다. 발신자 앱 또는 Google Cast Chrome 앱은 발신자 기기의 Chrome 브라우저 내에서 실행되는 웹 (HTML/자바스크립트) 앱을 의미합니다. 웹 수신기 앱은 Chromecast 또는 Google Cast 기기에서 실행되는 HTML/자바스크립트 앱을 의미합니다.

발신자 프레임워크는 비동기 콜백 디자인을 사용하여 발신기 앱에 이벤트를 알리고 Cast 앱 수명 주기의 다양한 상태 간에 전환합니다.

라이브러리 로드

앱에서 Google Cast의 기능을 구현하려면 아래와 같이 Google Cast 웹 발신자 SDK의 위치를 알아야 합니다. loadCastFramework URL 쿼리 매개변수를 추가하여 Web Sender Framework API도 로드합니다. 앱의 모든 페이지는 다음과 같이 라이브러리를 참조해야 합니다.

<script src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>

프레임워크

웹 발신자 SDK는 cast.framework.* 네임스페이스를 사용합니다. 네임스페이스는 다음을 나타냅니다.

  • API에서 작업을 호출하는 메서드 또는 함수
  • API의 리스너 함수에 대한 이벤트 리스너

프레임워크는 다음과 같은 주요 구성요소로 이루어져 있습니다.

  • CastContext는 현재 Cast 상태에 관한 정보를 제공하고 Cast 상태 및 Cast 세션 상태 변경사항에 관한 이벤트를 트리거하는 싱글톤 객체입니다.
  • CastSession 객체는 세션을 관리합니다. 이 클래스는 상태 정보를 제공하고 기기 볼륨, 음소거 상태, 앱 메타데이터의 변경과 같은 이벤트를 트리거합니다.
  • 전송 버튼 요소: HTML 버튼을 확장하는 간단한 HTML 맞춤 요소입니다. 제공된 전송 버튼이 충분하지 않으면 전송 상태를 사용하여 전송 버튼을 구현할 수 있습니다.
  • RemotePlayerController는 원격 플레이어의 구현을 간소화하기 위한 데이터 결합을 제공합니다.

네임스페이스에 대한 전체 설명은 Google Cast Web Sender API 참조를 확인하세요.

전송 버튼

앱의 전송 버튼 구성요소는 프레임워크에 의해 전적으로 처리됩니다. 여기에는 가시성 관리와 클릭 이벤트 처리가 포함됩니다.

<google-cast-launcher></google-cast-launcher>

또는 프로그래매틱 방식으로 버튼을 만들 수 있습니다.

document.createElement("google-cast-launcher");

필요에 따라 크기나 위치 지정과 같은 추가 스타일을 요소에 적용할 수 있습니다. --connected-color 속성을 사용하여 연결된 웹 수신기 상태의 색상을 선택하고 연결 해제된 상태의 --disconnected-color를 선택합니다.

초기화

프레임워크 API를 로드한 후 앱은 window.__onGCastApiAvailable 핸들러를 호출합니다. 발신자 라이브러리를 로드하기 전에 앱이 window에서 이 핸들러를 설정했는지 확인해야 합니다.

이 핸들러 내에서 CastContextsetOptions(options) 메서드를 호출하여 Cast 상호작용을 초기화합니다.

예를 들면 다음과 같습니다.

<script>
window['__onGCastApiAvailable'] = function(isAvailable) {
  if (isAvailable) {
    initializeCastApi();
  }
};
</script>

그런 다음 API를 다음과 같이 초기화합니다.

initializeCastApi = function() {
  cast.framework.CastContext.getInstance().setOptions({
    receiverApplicationId: applicationId,
    autoJoinPolicy: chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED
  });
};

먼저 앱은 프레임워크에서 제공하는 CastContext 객체의 싱글톤 인스턴스를 검색합니다. 그런 다음 CastOptions 객체를 사용하여 setOptions(options)를 사용하여 applicationID을 설정합니다.

등록할 필요가 없는 기본 미디어 수신기를 사용하는 경우 아래와 같이 applicationID 대신 웹 발신자 SDK가 사전 정의한 상수를 사용합니다.

cast.framework.CastContext.getInstance().setOptions({
  receiverApplicationId: chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID
});

미디어 제어

CastContext가 초기화되면 앱은 언제든지 getCurrentSession()를 사용하여 현재 CastSession를 검색할 수 있습니다.

var castSession = cast.framework.CastContext.getInstance().getCurrentSession();

CastSessionloadMedia(loadRequest)를 통해 연결된 Cast 기기에 미디어를 로드하는 데 사용할 수 있습니다. 먼저 contentIdcontentType뿐만 아니라 콘텐츠와 관련된 다른 정보를 사용하여 MediaInfo를 만듭니다. 그런 다음 LoadRequest를 만들고 요청과 관련된 모든 정보를 설정합니다. 마지막으로 CastSession에서 loadMedia(loadRequest)를 호출합니다.

var mediaInfo = new chrome.cast.media.MediaInfo(currentMediaURL, contentType);
var request = new chrome.cast.media.LoadRequest(mediaInfo);
castSession.loadMedia(request).then(
  function() { console.log('Load succeed'); },
  function(errorCode) { console.log('Error code: ' + errorCode); });

loadMedia 메서드는 성공적인 결과를 얻기 위해 필요한 작업을 실행하는 데 사용할 수 있는 프로미스를 반환합니다. 프로미스가 거부되면 함수 인수는 chrome.cast.ErrorCode가 됩니다.

RemotePlayer에서 플레이어 상태 변수에 액세스할 수 있습니다. 미디어 이벤트 콜백 및 명령어를 비롯한 RemotePlayer와의 모든 상호작용은 RemotePlayerController로 처리됩니다.

var player = new cast.framework.RemotePlayer();
var playerController = new cast.framework.RemotePlayerController(player);

RemotePlayerController는 로드된 미디어에 관한 앱의 전체 미디어 제어 권한을 PLAY, PAUSE, STOP, SEEK에 부여합니다.

  • 재생/일시중지: playerController.playOrPause();
  • 정류장: playerController.stop();
  • 찾기: playerController.seek();

RemotePlayerRemotePlayerController를 Polymer 또는 Angular와 같은 데이터 결합 프레임워크와 함께 사용하여 원격 플레이어를 구현할 수 있습니다.

다음은 Angular의 코드 스니펫입니다.

<button id="playPauseButton" class="playerButton"
  ng-disabled="!player.canPause"
  ng-click="controller.playOrPause()">
    {{player.isPaused ? 'Play' : 'Pause'}}
</button>
<script>
var player = new cast.framework.RemotePlayer();
var controller = new cast.framework.RemotePlayerController(player);
// Listen to any player update, and trigger angular data binding
update.controller.addEventListener(
  cast.framework.RemotePlayerEventType.ANY_CHANGE,
  function(event) {
    if (!$scope.$$phase) $scope.$apply();
  });
</script>

미디어 상태

미디어 재생 중에 RemotePlayerController 객체의 다양한 cast.framework.RemotePlayerEventType 이벤트에 관한 리스너를 설정하여 캡처할 수 있는 다양한 이벤트가 발생합니다.

미디어 상태 정보를 가져오려면 재생 변경 및 CastSession.getMediaSession().media 변경 시 트리거되는 cast.framework.RemotePlayerEventType.MEDIA_INFO_CHANGED 이벤트를 사용합니다.

playerController.addEventListener(
  cast.framework.RemotePlayerEventType.MEDIA_INFO_CHANGED, function() {
    // Use the current session to get an up to date media status.
    let session = cast.framework.CastContext.getInstance().getCurrentSession();

    if (!session) {
        return;
    }

    // Contains information about the playing media including currentTime.
    let mediaStatus = session.getMediaSession();
    if (!mediaStatus) {
        return;
    }

    // mediaStatus also contains the mediaInfo containing metadata and other
    // information about the in progress content.
    let mediaInfo = mediaStatus.media;
  });

일시중지, 재생, 다시 시작, 탐색과 같은 이벤트가 발생하면 앱은 이러한 기기에서 작업을 수행하고 앱 자체와 Cast 기기의 웹 수신기 앱 간에 동기화해야 합니다. 자세한 내용은 상태 업데이트를 참고하세요.

세션 관리 작동 방식

Cast SDK는 Cast 세션이라는 개념을 도입했으며, 이 개념에는 기기 연결, 웹 수신기 앱 실행 (또는 참여), 앱 연결, 미디어 제어 채널 초기화 단계가 결합되어 있습니다. Cast 세션 및 웹 수신기 수명 주기에 관한 자세한 내용은 웹 수신기 애플리케이션 수명 주기 가이드를 참고하세요.

세션은 앱이 cast.framework.CastContext.getInstance()를 통해 검색할 수 있는 CastContext 클래스에서 관리됩니다. 개별 세션은 Session 클래스의 서브클래스로 표현됩니다. 예를 들어 CastSession는 Cast 기기의 세션을 나타냅니다. 앱은 CastContext.getCurrentSession()를 통해 현재 활성 상태인 Cast 세션에 액세스할 수 있습니다.

세션 상태를 모니터링하려면 CastContextEventType.SESSION_STATE_CHANGED 이벤트 유형의 CastContext에 리스너를 추가합니다.

var context = cast.framework.CastContext.getInstance();
context.addEventListener(
  cast.framework.CastContextEventType.SESSION_STATE_CHANGED,
  function(event) {
    switch (event.sessionState) {
      case cast.framework.SessionState.SESSION_STARTED:
      case cast.framework.SessionState.SESSION_RESUMED:
        break;
      case cast.framework.SessionState.SESSION_ENDED:
        console.log('CastContext: CastSession disconnected');
        // Update locally as necessary
        break;
    }
  })

연결 해제(예: 사용자가 전송 대화상자에서 '전송 중지' 버튼을 클릭하는 경우)의 경우 리스너에서 RemotePlayerEventType.IS_CONNECTED_CHANGED 이벤트 유형의 리스너를 추가할 수 있습니다. 리스너에서 RemotePlayer 연결이 해제되었는지 확인합니다. 이 경우 필요에 따라 로컬 플레이어 상태를 업데이트하세요. 예를 들면 다음과 같습니다.

playerController.addEventListener(
  cast.framework.RemotePlayerEventType.IS_CONNECTED_CHANGED, function() {
    if (!player.isConnected) {
      console.log('RemotePlayerController: Player disconnected');
      // Update local player to disconnected state
    }
  });

사용자는 프레임워크 전송 버튼을 통해 Cast 종료를 직접 제어할 수 있지만 발신자는 현재 CastSession 객체를 사용하여 전송을 중지할 수 있습니다.

function stopCasting() {
  var castSession = cast.framework.CastContext.getInstance().getCurrentSession();
  // End the session and pass 'true' to indicate
  // that Web Receiver app should be stopped.
  castSession.endSession(true);
}

스트림 이전

세션 상태 유지는 스트림 전송의 기초로, 사용자는 음성 명령, Google Home 앱 또는 스마트 디스플레이를 사용하여 기기 간에 기존 오디오 및 동영상 스트림을 이동할 수 있습니다. 미디어가 한 기기 (소스)에서 재생을 중지하고 다른 기기 (대상)에서 계속 재생됩니다. 최신 펌웨어가 있는 모든 Cast 기기는 스트림 전송에서 소스 또는 대상의 역할을 할 수 있습니다.

스트림 전송 중에 새 대상 기기를 가져오려면 cast.framework.SessionState.SESSION_RESUMED 이벤트가 호출될 때 CastSession#getCastDevice()를 호출합니다.

자세한 내용은 웹 수신기에서 스트림 전송을 참고하세요.