Интегрируйте Cast SDK в ваше приложение Web Sender

В этом руководстве для разработчиков описано, как добавить поддержку Google Cast в ваше веб-приложение Web Sender с помощью SDK Cast.

Терминология

Мобильное устройство или браузер выступает в роли отправителя , управляющего воспроизведением; устройство Google Cast является получателем , отображающим контент на экране для воспроизведения.

SDK Web Sender состоит из двух частей: API фреймворка ( cast.framework ) и базового API ( chrome.cast ). Как правило, вы обращаетесь к более простому, высокоуровневому API фреймворка, который затем обрабатывается низкоуровневым базовым API.

Фреймворк отправителя относится к API фреймворка, модулю и связанным ресурсам, которые предоставляют оболочку для низкоуровневой функциональности. Приложение отправителя или приложение Google Cast для Chrome — это веб-приложение (HTML/JavaScript), работающее в браузере Chrome на устройстве отправителя. Приложение веб-приемника — это приложение HTML/JavaScript, работающее на Chromecast или устройстве Google Cast.

В фреймворке отправителя используется асинхронная архитектура обратных вызовов для информирования приложения-отправителя о событиях и для перехода между различными состояниями жизненного цикла приложения Cast.

Загрузите библиотеку

Для того чтобы ваше приложение могло использовать функции Google Cast, ему необходимо знать расположение SDK Google Cast Web Sender, как показано ниже. Добавьте параметр запроса URL loadCastFramework для загрузки API Web Sender Framework. Все страницы вашего приложения должны ссылаться на библиотеку следующим образом:

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

Рамки

SDK Web Sender использует пространство имен cast.framework. *. Это пространство имен представляет собой следующее:

  • Методы или функции, которые вызывают операции с API.
  • Обработчики событий для функций-обработчиков в API

Данная структура состоит из следующих основных компонентов:

  • CastContext — это объект-одиночка, предоставляющий информацию о текущем состоянии Cast и запускающий события при изменении состояния Cast и состояния сессии Cast.
  • Объект CastSession управляет сессией — он предоставляет информацию о состоянии и запускает события, такие как изменение громкости устройства, состояния отключения звука и метаданных приложения.
  • Элемент кнопки Cast — это простой пользовательский HTML-элемент, расширяющий возможности стандартной HTML-кнопки. Если предоставленной кнопки Cast недостаточно, вы можете использовать состояние Cast для реализации кнопки Cast.
  • Компонент RemotePlayerController обеспечивает привязку данных для упрощения реализации удаленного проигрывателя.

Для получения полного описания пространства имен ознакомьтесь со справочником по API веб-отправителя Google Cast .

кнопка трансляции

Компонент кнопки Cast в вашем приложении полностью обрабатывается фреймворком. Это включает в себя управление видимостью, а также обработку событий клика.

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

В качестве альтернативы, вы можете создать кнопку программным способом:

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

При необходимости вы можете применить к элементу любые дополнительные стили, такие как размер или позиционирование. Используйте атрибут --connected-color , чтобы выбрать цвет для состояния подключенного веб-приемника, и --disconnected-color для состояния отключенного.

Инициализация

После загрузки API фреймворка приложение вызовет обработчик window.__onGCastApiAvailable . Необходимо убедиться, что приложение установило этот обработчик для window до загрузки библиотеки отправителя .

В этом обработчике вы инициализируете взаимодействие Cast, вызывая метод setOptions(options) класса CastContext .

Например:

<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 приложение может в любой момент получить текущую CastSession , используя getCurrentSession() .

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

CastSession можно использовать для загрузки медиафайлов на подключенное устройство Cast с помощью loadMedia(loadRequest) . Сначала создайте MediaInfo , используя contentId и contentType , а также любую другую информацию, связанную с контентом. Затем создайте на его основе объект LoadRequest , установив всю необходимую информацию для запроса. Наконец, вызовите loadMedia(loadRequest) для вашего CastSession .

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();
  • СТОП: playerController.stop();
  • ПОИСК: playerController.seek();

Компоненты RemotePlayer и RemotePlayerController можно использовать с фреймворками для привязки данных, такими как 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>

Статус СМИ

Во время воспроизведения мультимедиа происходят различные события, которые можно перехватить, установив обработчики событий для различных типов событий cast.framework.RemotePlayerEventType в объекте RemotePlayerController .

Для получения информации о состоянии медиафайлов используйте событие cast.framework.RemotePlayerEventType .MEDIA_INFO_CHANGED , которое срабатывает при изменении параметров воспроизведения и при изменении значения CastSession.getMediaSession().media .

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

При возникновении таких событий, как пауза, воспроизведение, возобновление или перемотка, приложению необходимо будет отреагировать на них и синхронизировать данные между собой и приложением Web Receiver на устройстве Cast. Дополнительную информацию см. в разделе «Обновления состояния» .

Как работает управление сессиями

SDK Cast представляет концепцию сессии Cast, установление которой объединяет шаги подключения к устройству, запуска (или присоединения) приложения Web Receiver, подключения к этому приложению и инициализации канала управления мультимедиа. Дополнительную информацию о сессиях Cast и жизненном цикле Web Receiver см. в руководстве по жизненному циклу приложения Web Receiver.

Управление сессиями осуществляется классом CastContext , который ваше приложение может получить с помощью cast.framework.CastContext.getInstance() . Отдельные сессии представлены подклассами класса 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;
    }
  })

Для случаев отключения, например, когда пользователь нажимает кнопку «Остановить трансляцию» в диалоговом окне трансляции, вы можете добавить в свой обработчик событий обработчик события типа 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

Дополнительную информацию см. в разделе «Передача потока в веб-приемнике» .