Web Sender 앱에 Cast SDK 통합

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

용어

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

웹 전송기 SDK는 프레임워크 API (cast.framework) 와 기본 API (chrome.cast) 의 두 부분으로 구성됩니다. 일반적으로 더 간단한 상위 수준 프레임워크 API 를 호출하면 하위 수준 기본 API에서 이를 처리합니다.

전송기 프레임워크 는 하위 수준 기능을 래핑하는 프레임워크 API, 모듈, 관련 리소스를 나타냅니다. 전송기 앱 또는 Google Cast Chrome 앱 은 전송기 기기의 Chrome 브라우저 내에서 실행되는 웹 (HTML/자바스크립트) 앱을 나타냅니다. 웹 수신기 앱 은 Chromecast 또는 Google Cast 기기에서 실행되는 HTML/자바스크립트 앱을 나타냅니다.

전송기 프레임워크는 비동기 콜백 디자인을 사용하여 전송기 앱에 이벤트를 알리고 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 맞춤 요소인 전송 버튼 요소입니다. 제공된 전송 버튼이 충분하지 않은 경우 Cast 상태를 사용하여 전송 버튼을 구현할 수 있습니다.
  • RemotePlayerController 는 원격 플레이어의 구현을 간소화하기 위해 데이터 결합을 제공합니다.

네임스페이스에 관한 자세한 내용은 Google Cast 웹 전송기 API 참조를 검토하세요.

전송 버튼

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

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

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

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

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

초기화

프레임워크 API를 로드한 후 앱은 핸들러 window.__onGCastApiAvailable을 호출합니다. 전송기 라이브러리를 로드하기 전에 앱이 window에서 이 핸들러 를 설정해야 합니다.

이 핸들러 내에서 setOptions(options)CastContext메서드를 호출하여 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 객체 의 싱글톤 인스턴스를 가져옵니다. 그런 다음 setOptions(options) 을(를) 사용하여 CastOptions 객체 를 사용하여 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();

CastSession은 연결된 Cast 기기에 미디어를 로드하는 데 사용할 수 있습니다. loadMedia(loadRequest). 먼저 MediaInfo를 만들고 contentIdcontentType과 콘텐츠와 관련된 기타 정보를 사용합니다. 그런 다음 요청에 관한 모든 관련 정보를 설정하여 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 RemotePlayer와의 모든 상호작용(미디어 이벤트 콜백 및 명령어 포함)은 RemotePlayerController로 처리됩니다.

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

RemotePlayerController를 사용하면 앱에서 로드된 미디어의 재생, 일시중지, 중지, 탐색을 완전히 제어할 수 있습니다.

  • 재생/일시중지: 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 기기가 있는 세션을 나타냅니다. 앱은 현재 활성 Cast 세션에 CastContext.getCurrentSession() 액세스할 수 있습니다.

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

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

사용자가 Cast 대화상자에서 '전송 중지' 버튼을 클릭하는 경우와 같은 연결 해제의 경우 리스너에서 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 버튼을 통해 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 기기는 스트림 이전에서 소스 또는 대상으로 사용할 수 있습니다.

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

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