Web Sender 앱에 Cast SDK 통합

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

용어

휴대기기 또는 브라우저는 재생을 제어하는 발신기이고, Google Cast 기기는 재생을 위해 화면에 콘텐츠를 표시하는 수신기입니다.

웹 송신기 SDK는 Framework API(cast.framework)와 Base API(chrome.cast)라는 두 부분으로 구성됩니다. 일반적으로 더 간단하고 상위 수준의 Framework API를 호출하면 이를 하위 수준의 Base API에서 처리합니다.

보내기 프레임워크는 하위 수준 기능을 둘러싸는 래퍼를 제공하는 Framework API, 모듈, 관련 리소스를 나타냅니다. 송신자 앱 또는 Google Cast Chrome 앱은 송신기 기기의 Chrome 브라우저 내에서 실행되는 웹 (HTML/JavaScript) 앱을 의미합니다. 웹 수신기 앱은 Chromecast 또는 Google Cast 기기에서 실행되는 HTML/JavaScript 앱을 의미합니다.

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

라이브러리 로드

앱이 Google Cast 기능을 구현하려면 아래와 같이 Google Cast 웹 전송기 SDK의 위치를 알아야 합니다. loadCastFramework URL 쿼리 매개변수를 추가하여 웹 송신기 프레임워크 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 메서드는 성공적인 결과를 위해 필요한 작업을 실행하는 데 사용할 수 있는 Promise를 반환합니다. Promise가 거부되면 함수 인수가 chrome.cast.ErrorCode이 됩니다.

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

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

RemotePlayerController는 앱에 로드된 미디어의 재생, 일시중지, 중지, 탐색에 대한 전체 미디어 제어 기능을 제공합니다.

  • 재생/일시중지: playerController.playOrPause();
  • STOP: playerController.stop();
  • SEEK: 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
    }
  });

사용자는 프레임워크 전송 버튼을 통해 전송 종료를 직접 제어할 수 있지만, 전송자 자체는 현재 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()를 호출합니다.

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