Добавьте расширенные функции в ваше приложение Web Sender

Рекламные паузы

Web Sender SDK обеспечивает поддержку рекламных пауз и сопутствующей рекламы в заданном медиапотоке.

Дополнительную информацию о работе рекламных пауз см. в разделе Обзор рекламных пауз Web Receiver .

Хотя перерывы можно указывать как на стороне отправителя, так и на стороне получателя, рекомендуется указывать их на стороне веб-приемника и приемника Android TV, чтобы поддерживать единообразное поведение на разных платформах.

В Интернете укажите рекламные паузы в команде загрузки с помощью BreakClip и Break :

let breakClip1 = new BreakClip('bc0');
breakClip1.title = 'Clip title'
breakClip1.posterUrl = 'https://www.some.url';
breakClip1.duration = 60;
breakClip.whenSKippable = 5;

let breakClip2 = ...
let breakClip3 = ...

let break1 = new Break('b0', ['bc0', 'bc1', 'bc2'], 10);

let mediaInfo = new chrome.cast.media.MediaInfo(<contentId>, '<contentType');
...
mediaInfo.breakClips = [breakClip1, breakClip2, breakClip3];
mediaInfo.breaks = [break1];

let request = new chrome.cast.media.LoadRequest(mediaInfo);

cast.framework.CastContext.getInstance().getCurrentSession().loadMedia(request)

Использование API треков

Трек может быть текстовым объектом (субтитрами или надписями), а также объектом аудио- или видеопотока. API треков позволяют работать с этими объектами в вашем приложении.

Объект Track представляет трек в SDK. Вы можете настроить трек и назначить ему уникальный идентификатор следующим образом:

var englishSubtitle = new chrome.cast.media.Track(1, // track ID
  chrome.cast.media.TrackType.TEXT);
englishSubtitle.trackContentId = 'https://some-url/caption_en.vtt';
englishSubtitle.trackContentType = 'text/vtt';
englishSubtitle.subtype = chrome.cast.media.TextTrackType.SUBTITLES;
englishSubtitle.name = 'English Subtitles';
englishSubtitle.language = 'en-US';
englishSubtitle.customData = null;

var frenchSubtitle = new chrome.cast.media.Track(2, // track ID
  chrome.cast.media.TrackType.TEXT);
frenchSubtitle.trackContentId = 'https://some-url/caption_fr.vtt';
frenchSubtitle.trackContentType = 'text/vtt';
frenchSubtitle.subtype = chrome.cast.media.TextTrackType.SUBTITLES;
frenchSubtitle.name = 'French Subtitles';
frenchSubtitle.language = 'fr';
frenchSubtitle.customData = null;

var frenchAudio = new chrome.cast.media.Track(3, // track ID
  chrome.cast.media.TrackType.AUDIO);
frenchAudio.trackContentId = 'trk0001';
frenchAudio.trackContentType = 'audio/mp3';
frenchAudio.subtype = null;
frenchAudio.name = 'French Audio';
frenchAudio.language = 'fr';
frenchAudio.customData = null;

Медиафайл может иметь несколько дорожек; например, он может иметь несколько субтитров (каждый на своем языке) или несколько альтернативных аудиопотоков (для разных языков).

MediaInfo — это класс, моделирующий медиа-элемент. Чтобы связать коллекцию объектов Track с медиа-элементом, необходимо обновить его свойство tracks . Эту связь необходимо установить до загрузки медиа-файла в приёмник:

var tracks = [englishSubtitle, frenchSubtitle, frenchAudio];
var mediaInfo = new chrome.cast.media.MediaInfo(mediaURL);
mediaInfo.contentType = 'video/mp4';
mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata();
mediaInfo.customData = null;
mediaInfo.streamType = chrome.cast.media.StreamType.BUFFERED;
mediaInfo.textTrackStyle = new chrome.cast.media.TextTrackStyle();
mediaInfo.duration = null;
mediaInfo.tracks = tracks;

Активные треки можно задать в медиа-запросе activeTrackIds .

Вы также можете активировать одну или несколько дорожек, связанных с медиафайлом, после его загрузки, вызвав EditTracksInfoRequest(opt_activeTrackIds, opt_textTrackStyle) и передав идентификаторы дорожек, которые нужно активировать, в opt_activeTrackIds . Обратите внимание, что оба параметра необязательны, и вы можете выбрать, какие из них установить — активные дорожки или стили — по своему усмотрению. Например, вот как активировать французские субтитры ( 2 ) и французскую аудиодорожку ( 3 ):

var activeTrackIds = [2, 3];
var tracksInfoRequest = new chrome.cast.media.EditTracksInfoRequest(activeTrackIds);
media.editTracksInfo(tracksInfoRequest, successCallback, errorCallback);

Чтобы удалить все аудио- или видеодорожки из текущего носителя, просто установите mediaInfo.tracks=null (пустой массив) и перезагрузите носитель.

Чтобы удалить все текстовые дорожки с текущего носителя (например, отключить субтитры), выполните одно из следующих действий:

  • Обновите var activeTrackIds = [2, 3]; (показано ранее), чтобы она включала только [3], звуковую дорожку.
  • Установите mediaInfo.tracks=null . Обратите внимание, что для отключения текстовых субтитров ( track.hidden ) не требуется перезагружать медиафайл. Отправка массива activeTracksId , не содержащего ранее включённый trackId , отключает текстовую дорожку.

Стилизация текстовых дорожек

TextTrackStyle — это объект, инкапсулирующий информацию о стиле текстовой дорожки. После создания или обновления существующего объекта TextTrackStyle вы можете применить его к воспроизводимому в данный момент медиа-элементу, вызвав его метод editTrackInfo , например:

var textTrackStyle = new chrome.cast.media.TextTrackStyle();
var tracksInfoRequest = new chrome.cast.media.EditTracksInfoRequest(textTrackStyle);
media.editTracksInfo(tracksInfoRequest, successCallback, errorCallback);

Вы можете отслеживать статус запроса по результатам обратных вызовов (успешно или ошибка) и соответствующим образом обновлять исходного отправителя.

Приложения должны позволять пользователям обновлять стиль текстовых дорожек, используя настройки, предоставляемые системой или самим приложением.

Вы можете стилизовать следующие элементы стиля текстовой дорожки:

  • Цвет и непрозрачность переднего плана (текста)
  • Цвет фона и непрозрачность
  • Тип кромки
  • Цвет края
  • Масштаб шрифта
  • Семейство шрифтов
  • Стиль шрифта

Например, установите красный цвет текста с непрозрачностью 75% следующим образом:

var textTrackStyle = new chrome.cast.media.TextTrackStyle();
textTrackStyle.foregroundColor = '#80FF0000';

Регулятор громкости

Для настройки громкости ресивера можно использовать RemotePlayer и RemotePlayerController .

function changeVolume(newVolume) {
  player.volumeLevel = newVolume;
  playerController.setVolumeLevel();
  // Update sender UI to reflect change
}

Приложение-отправитель должно придерживаться следующих правил контроля громкости:

  • Приложение-отправитель должно синхронизироваться с приёмником, чтобы пользовательский интерфейс отправителя всегда сообщал громкость для приёмника. Используйте обратные вызовы RemotePlayerEventType.VOLUME_LEVEL_CHANGED и RemotePlayerEventType.IS_MUTED_CHANGED для поддержания громкости на отправителе. Подробнее см. в разделе «Обновления статуса» .
  • Приложения-отправители не должны устанавливать уровень громкости на определенном, предопределенном уровне или устанавливать уровень громкости на уровне громкости звонка/мультимедиа устройства-отправителя при загрузке приложения на устройстве-получателе.

См. раздел «Регуляторы громкости отправителя» в контрольном списке проектирования .

Отправка медиа-сообщений получателю

Media Messages могут отправляться от отправителя к получателю. Например, чтобы отправить получателю сообщение SKIP_AD :

// Get a handle to the skip button element
const skipButton = document.getElementById('skip');
skipButton.addEventListener("click", function() {
  if (castSession) {
    const media = castSession.getMediaSession();
    castSession.sendMessage('urn:x-cast:com.google.cast.media', {
      type: 'SKIP_AD',
      requestId: 1,
      mediaSessionId: media.mediaSessionId
    });
  }
});

Обновления статуса

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

Для этого ваше приложение должно зарегистрировать все необходимые прослушиватели на RemotePlayerController . Если стиль TextTrackStyle текущего медиа-контента изменится, все подключённые отправители будут уведомлены об этом, и соответствующие свойства текущего медиа-сеанса, такие как activeTrackIds и textTrackStyle поля MediaInfo , будут отправлены отправителям в обратных вызовах. В этом случае SDK приёмника не проверяет, отличается ли новый стиль от предыдущего, и всё равно уведомляет всех подключённых отправителей.

Индикатор прогресса

Отображение места воспроизведения с индикатором прогресса на устройстве-отправителе является обязательным требованием для большинства приложений. API Cast используют протокол Cast Media, который оптимизирует потребление полосы пропускания в этом и других сценариях, поэтому вам не нужно реализовывать собственную синхронизацию статуса. Для корректной реализации индикатора прогресса для воспроизведения медиафайлов с использованием API см. пример приложения CastVideos-chrome .

Требования CORS

Для адаптивной потоковой передачи медиаданных Google Cast требуется наличие заголовков CORS, но даже для простых потоков медиаданных MP4 требуются заголовки CORS, если они содержат дорожки. Если вы хотите включить дорожки для любого медиаданных, необходимо включить CORS как для потоков треков, так и для потоков медиаданных. Таким образом, если на вашем сервере нет заголовков CORS для простых медиаданных MP4, а затем вы добавляете простую дорожку субтитров, вы не сможете транслировать медиаданные, пока не обновите сервер, включив соответствующие заголовки CORS.

Вам понадобятся следующие заголовки: Content-Type , Accept-Encoding и Range . Обратите внимание, что последние два заголовка, Accept-Encoding и Range , — это дополнительные заголовки, которые, возможно, ранее вам не понадобились.

Подстановочные знаки «*» нельзя использовать в заголовке Access-Control-Allow-Origin . Если на странице есть защищённый медиаконтент, вместо подстановочных знаков необходимо использовать домен.

Возобновление сеанса без перезагрузки веб-страницы

Чтобы возобновить существующий CastSession , используйте requestSessionById(sessionId) с sessionId сеанса, к которому вы пытаетесь присоединиться.

sessionId можно найти в активном CastSession с помощью getSessionId() после вызова loadMedia() .

Рекомендуемый подход заключается в следующем:

  1. Вызовите loadMedia() , чтобы начать сеанс.
  2. Сохраните sessionId локально
  3. При необходимости повторно присоединитесь к сеансу, используя requestSessionById(sessionId)
let sessionId;

function rejoinCastSession() {
  chrome.cast.requestSessionById(sessionId);

  // Add any business logic to load new content or only resume the session
}

document.getElementById('play-button').addEventListener(("click"), function() {
  if (sessionId == null) {
    let castSession = cast.framework.CastContext.getInstance().getCurrentSession();
    if (castSession) {
      let mediaInfo = createMediaInfo();
      let request = new chrome.cast.media.LoadRequest(mediaInfo);
      castSession.loadMedia(request)

      sessionId = CastSession.getSessionId();
    } else {
      console.log("Error: Attempting to play media without a Cast Session");
    }
  } else {
    rejoinCastSession();
  }
});

Следующие шаги

На этом мы завершаем список функций, которые вы можете добавить в приложение Web Sender. Теперь вы можете создать приложение-отправитель для другой платформы ( Android или iOS ) или приложение-получатель .