向 Web Sender 应用添加高级功能

广告插播时间点

Web Sender SDK 可为单个视频中的广告插播时间点和随播广告提供 指定媒体流。

请参阅 网络接收器广告插播概览,了解详情 以便详细了解广告插播时间点的运作方式

虽然可以为发送者和接收者指定广告插播时间点,但建议同时为发送者和接收者指定 在网络接收器中指定,然后 Android TV 接收器,以便保持一致 在不同平台上的行为

在网站上,使用以下代码在加载命令中指定广告插播时间点: BreakClipBreak

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)

使用 Tracks API

轨道可以是文本(副标题或字幕)对象,也可以是音频或视频流 对象。Tracks API 可让您在应用中使用这些对象。

一个 Track 对象 表示 SDK 中的轨道。您可以配置轨道并指定唯一 ID 如下所示:

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 是用于为媒体项建模的类。要将一组 Pod 相关联 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 中启用的轨道的 ID。请注意: 这两个参数都是可选的 您可以选择使用有效的曲目或风格 自行设置例如,这里展示了如何 激活法语字幕(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';

音量控制

您可以使用 RemotePlayerRemotePlayerController 来设置接收器音量。

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

发送器应用应遵循以下控制音量准则:

  • 发送者应用必须与接收者同步,以便 发送者界面始终按接收者报告音量。使用 RemotePlayerEventType.VOLUME_LEVEL_CHANGEDRemotePlayerEventType.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 当前的媒体更改,则所有已连接的发送者都会收到通知 以及当前媒体会话的相应属性,例如 的 activeTrackIdstextTrackStyle MediaInfo 字段将在回调中发送给发送者。在这种情况下,接收器 SDK 不会验证新样式是否与先前样式不同, 会通知所有连接的发件人。

进度指示器

在发送器上显示播放位置和进度指示器 这一要求Cast API 使用 Cast 媒体协议, 针对这种情况和其他场景优化了带宽消耗, 实现自己的状态同步。为了正确实现 有关使用 API 播放媒体的进度指示器的信息,请参阅 CastVideos-chrome 示例应用。

CORS 要求

对于自适应媒体流式传输,Google Cast 需要使用 CORS 标头, 但如果包含曲目,即使是简单的 mp4 媒体流也需要 CORS。如果您 要为任何媒体启用跟踪,您必须同时为两个轨道启用 CORS 和媒体流。因此,如果您没有 CORS 标头可用 然后在服务器上添加简单的 mp4 媒体 所以您必须先更新服务器,然后才能流式传输媒体内容 以包含相应的 CORS 标头。

您需要以下标头:Content-TypeAccept-EncodingRange。 请注意,最后两个标头 Accept-EncodingRange 是额外的标头, 之前可能不需要的标头。

通配符“*”不得用于 Access-Control-Allow-Origin 标头。如果 网页包含受保护的媒体内容,则必须使用域名,而不是 通配符。

在不重新加载网页的情况下恢复会话

如需恢复现有的 CastSession,请使用 requestSessionById(sessionId) 与您尝试加入的会话的 sessionId 相匹配。

您可以使用以下命令在活跃 CastSession 上找到 sessionIdgetSessionId() 调用之后 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 应用中添加的功能。 您现在可以针对其他平台构建发送者应用 (AndroidiOS),或者 构建接收器应用