将 Cast SDK 集成到您的 Web 发送器应用中

本开发者指南介绍了如何使用 Cast SDK 为您的 Web 发送器应用添加 Google Cast 支持。

术语

移动设备或浏览器是控制播放的发送方;Google Cast 设备是接收方,在屏幕上显示内容以进行播放。

Web Sender SDK 由两部分组成:Framework API (cast.framework) 和 Base API (chrome.cast)。一般而言,你可以在更简单的较高级别的 Framework API 上进行调用,然后由较低级别的 Base API 处理这些 API。

“发送方框架”是指为较低级别功能提供封装容器的 Framework API、模块和关联资源。发送方应用Google Cast Chrome 应用是指在发送端设备上的 Chrome 浏览器中运行的网页 (HTML/JavaScript) 应用。Web 接收器应用是指在 Chromecast 或 Google Cast 设备上运行的 HTML/JavaScript 应用。

发送器框架采用异步回调设计来将事件告知给发送器应用,并在 Cast 应用生命周期的各种状态之间转换。

加载库

为了让应用实现 Google Cast 的功能,应用需要知道 Google Cast Web Sender SDK 的位置,如下所示。添加 loadCastFramework 网址查询参数,以同时加载 Web Sender Framework API。应用的所有页面都必须按如下方式引用该库:

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

框架

Web Sender 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 属性为已连接的 Web 接收器状态选择颜色,使用 --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 对象的单例实例。然后,它会使用 setOptions(options)CastOptions 对象来设置 applicationID

如果您使用的是不需要注册的默认媒体接收器,请使用 Web Sender SDK 预定义的常量(如下所示),而不是 applicationID

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 可用于使用 loadMedia(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 可让应用完全控制已加载媒体的 PLAY、PAUSE、STOP 和 SEEK。

  • 播放/暂停: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 事件设置监听器来捕获这些事件。

如需获取媒体状态信息,请使用 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;
  });

当发生暂停、播放、继续或跳转等事件时,应用需要对这些事件执行操作,并在自身与 Cast 设备上的网络接收器应用之间同步。如需了解详情,请参阅状态更新

会话管理的运作方式

Cast SDK 引入了 Cast 会话的概念,建立 Cast 会话包括连接到设备、启动(或加入)Web 接收器应用、连接到该应用以及初始化媒体控制渠道的步骤。如需详细了解 Cast 会话和 Web 接收器生命周期,请参阅网络接收器应用生命周期指南

会话由 CastContext 类管理,您的应用可通过 cast.framework.CastContext.getInstance() 检索该类。各个会话由 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;
    }
  })

对于断开连接(例如,当用户点击 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 设备都可以用作数据流传输中的来源或目标。

如需在数据流传输期间获取新的目标设备,请在调用 cast.framework.SessionState.SESSION_RESUMED 事件时调用 CastSession#getCastDevice()

如需了解详情,请参阅在 Web 接收器上传输流