為自訂網路接收器新增核心功能

本頁提供自訂網路接收器應用程式功能的程式碼片段和說明。

  1. cast-media-player 元素,代表透過網路接收器提供的內建播放器 UI。
  2. 類似 CSS 的 cast-media-player 元素樣式,可用來設定 background-imagesplash-imagefont-family 等各種 UI 元素的樣式。
  3. 用於載入 Web Receiver 架構的指令碼元素。
  4. 用來攔截訊息及處理事件的 JavaScript 程式碼。
  5. 待自動播放的待播清單。
  6. 設定播放功能的選項。
  7. 設定網路接收端內容的選項。
  8. 設定 Web Receiver 應用程式支援的指令選項。
  9. 用於啟動 Web Receiver 應用程式的 JavaScript 呼叫。

應用程式設定和選項

設定應用程式

CastReceiverContext 是向開發人員公開的最外層類別,可管理基礎程式庫的載入作業,以及處理 Web Receiver SDK 的初始化作業。SDK 提供 API,可讓應用程式開發人員透過 CastReceiverOptions 設定 SDK。系統會在每次應用程式啟動時評估這些設定,並在對 start 呼叫中設定選用參數時,傳遞至 SDK。

以下範例說明如何覆寫預設行為,藉此偵測寄件者連線是否仍在主動連線。當 Web Receiver 無法在 maxInactivity 秒內與寄件者通訊時,系統會分派 SENDER_DISCONNECTED 事件。以下設定會覆寫這個逾時時間。這項功能在偵錯時相當實用,因為當 IDLE 狀態中沒有連結零的寄件者時,Web Receiver 應用程式不會關閉 Chrome 遠端偵錯工具工作階段。

const context = cast.framework.CastReceiverContext.getInstance();
const options = new cast.framework.CastReceiverOptions();
options.maxInactivity = 3600; // Development only
context.start(options);

設定播放器

載入內容時,Web Receiver SDK 可讓您使用 cast.framework.PlaybackConfig 設定播放變數,例如數位版權管理資訊、重試設定和要求處理常式。這項資訊會由 PlayerManager 處理,並在建立玩家時評估。每次將新的載入內容傳送至 Web Receiver SDK 時,系統就會建立播放器。如果是在玩家建立後對 PlaybackConfig 所做的修改,系統會在下一個內容載入作業中評估。SDK 提供下列修改 PlaybackConfig 的方法。

以下範例說明如何在初始化 CastReceiverContext 時設定 PlaybackConfig。這項設定會覆寫傳出要求以取得資訊清單。此處理常式指定 CORS Access-Control 要求應使用 Cookie 或授權標頭等憑證發出。

const playbackConfig = new cast.framework.PlaybackConfig();
playbackConfig.manifestRequestHandler = requestInfo => {
  requestInfo.withCredentials = true;
};
context.start({playbackConfig: playbackConfig});

以下範例說明如何使用 PlayerManager 中提供的 getter 和 setter 覆寫 PlaybackConfig。這項設定會調整讓播放器在載入 1 個片段後繼續播放內容。

const playerManager =
    cast.framework.CastReceiverContext.getInstance().getPlayerManager();
const playbackConfig = (Object.assign(
            new cast.framework.PlaybackConfig(), playerManager.getPlaybackConfig()));
playbackConfig.autoResumeNumberOfSegments = 1;
playerManager.setPlaybackConfig(playbackConfig);

以下範例說明如何使用媒體播放資訊處理常式,針對特定載入要求覆寫 PlaybackConfig。處理常式會呼叫應用程式實作的方法 getLicenseUrlForMedia,以從目前項目的 contentId 取得 licenseUrl

playerManager.setMediaPlaybackInfoHandler((loadRequestData, playbackConfig) => {
  const mediaInformation = loadRequestData.media;
  playbackConfig.licenseUrl = getLicenseUrlForMedia(mediaInformation.contentId);

  return playbackConfig;
});

事件監聽器

Web Receiver SDK 可讓 Web Receiver 應用程式處理播放器事件事件監聽器使用 cast.framework.events.EventType 參數 (或這些參數的陣列),用於指定應觸發事件監聽器的事件。cast.framework.events.category 中會顯示適用於偵錯的 cast.framework.events.EventType 預先設定陣列。事件參數會提供事件的額外資訊。

舉例來說,如果想知道系統何時會播送 mediaStatus 變更,可以使用以下邏輯處理事件:

const playerManager =
    cast.framework.CastReceiverContext.getInstance().getPlayerManager();
playerManager.addEventListener(
    cast.framework.events.EventType.MEDIA_STATUS, (event) => {
      // Write your own event handling code, for example
      // using the event.mediaStatus value
});

訊息攔截

Web Receiver SDK 可讓 Web Receiver 應用程式攔截訊息,並針對這些訊息執行自訂程式碼。訊息攔截器使用 cast.framework.messages.MessageType 參數,指定要攔截的訊息類型。

攔截器應傳回修改後的要求,或是以修改後要求值解析的 Promise。傳回 null 會導致無法呼叫預設訊息處理常式。詳情請參閱「載入媒體」。

舉例來說,若要變更載入要求資料,您可以利用以下邏輯攔截及修改:

const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD, loadRequestData => {
      const error = new cast.framework.messages.ErrorData(
                      cast.framework.messages.ErrorType.LOAD_FAILED);
      if (!loadRequestData.media) {
        error.reason = cast.framework.messages.ErrorReason.INVALID_PARAM;
        return error;
      }

      if (!loadRequestData.media.entity) {
        return loadRequestData;
      }

      return thirdparty.fetchAssetAndAuth(loadRequestData.media.entity,
                                          loadRequestData.credentials)
        .then(asset => {
          if (!asset) {
            throw cast.framework.messages.ErrorReason.INVALID_REQUEST;
          }

          loadRequestData.media.contentUrl = asset.url;
          loadRequestData.media.metadata = asset.metadata;
          loadRequestData.media.tracks = asset.tracks;
          return loadRequestData;
        }).catch(reason => {
          error.reason = reason; // cast.framework.messages.ErrorReason
          return error;
        });
    });

context.start();

處理錯誤

如果訊息攔截器發生錯誤,您的 Web Receiver 應用程式應傳回適當的 cast.framework.messages.ErrorTypecast.framework.messages.ErrorReason

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD, loadRequestData => {
      const error = new cast.framework.messages.ErrorData(
                      cast.framework.messages.ErrorType.LOAD_CANCELLED);
      if (!loadRequestData.media) {
        error.reason = cast.framework.messages.ErrorReason.INVALID_PARAM;
        return error;
      }

      ...

      return fetchAssetAndAuth(loadRequestData.media.entity,
                               loadRequestData.credentials)
        .then(asset => {
          ...
          return loadRequestData;
        }).catch(reason => {
          error.reason = reason; // cast.framework.messages.ErrorReason
          return error;
        });
    });

訊息攔截與事件監聽器

訊息攔截和事件監聽器的主要差異如下:

  • 事件監聽器無法讓您修改要求資料。
  • 事件監聽器最適合用來觸發數據分析或自訂函式。
playerManager.addEventListener(cast.framework.events.category.CORE,
    event => {
        console.log(event);
    });
  • 訊息攔截可讓您監聽訊息、攔截訊息,以及修改要求資料本身。
  • 訊息攔截最適合用於處理與要求資料相關的自訂邏輯。

正在載入媒體

MediaInformation 提供許多屬性,可在 cast.framework.messages.MessageType.LOAD 訊息中載入媒體,包括 entitycontentUrlcontentId

  • 在導入傳送器和接收端應用程式時,建議使用 entity 是建議屬性。此屬性可以是播放清單或媒體內容的深層連結網址。建議您讓應用程式剖析這個網址,並至少填入另外兩個欄位之一。
  • contentUrl 會對應至玩家用於載入內容的可播放網址。舉例來說,這個網址可以指向 DASH 資訊清單。
  • contentId 可以是可播放的內容網址 (類似 contentUrl 屬性),也可以是載入內容或播放清單的專屬 ID。如果使用這個屬性做為 ID,應用程式應在 contentUrl 中填入可播放網址。

建議使用 entity 儲存實際 ID 或鍵參數,並使用 contentUrl 做為媒體網址。如以下程式碼片段所示,其中 entity 存在於 LOAD 要求中,且擷取可播放的 contentUrl

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD, loadRequestData => {
      ...

      if (!loadRequestData.media.entity) {
        // Copy the value from contentId for legacy reasons if needed
        loadRequestData.media.entity = loadRequestData.media.contentId;
      }

      return thirdparty.fetchAssetAndAuth(loadRequestData.media.entity,
                                          loadRequestData.credentials)
        .then(asset => {
          loadRequestData.media.contentUrl = asset.url;
          ...
          return loadRequestData;
        });
    });

裝置功能

getDeviceCapabilities 方法會提供已連線投放裝置的裝置資訊,以及連接的影片或音訊裝置。getDeviceCapabilities 方法可為 Google 助理、藍牙,以及已連線的螢幕和音訊裝置提供支援資訊。

這個方法會傳回物件,您可以傳入其中一個指定的列舉,以取得該列舉的裝置功能。cast.framework.system.DeviceCapabilities 中定義列舉。

此範例會分別檢查 Web Receiver 裝置是否能使用 IS_HDR_SUPPORTEDIS_DV_SUPPORTED 鍵播放 HDR 和 DolbyVision (DV) 遊戲。

const context = cast.framework.CastReceiverContext.getInstance();
context.addEventListener(cast.framework.system.EventType.READY, () => {
  const deviceCapabilities = context.getDeviceCapabilities();
  if (deviceCapabilities &&
      deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_HDR_SUPPORTED]) {
    // Write your own event handling code, for example
    // using the deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_HDR_SUPPORTED] value
  }
  if (deviceCapabilities &&
      deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_DV_SUPPORTED]) {
    // Write your own event handling code, for example
    // using the deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_DV_SUPPORTED] value
  }
});
context.start();

處理使用者互動

使用者可以透過傳送者應用程式 (網頁、Android 和 iOS)、支援 Google 助理的裝置下達語音指令、智慧螢幕的觸控設定和 Android TV 裝置的遙控器,與您的網路接收器應用程式互動。Cast SDK 提供各種 API,可讓 Web Receiver 應用程式處理這些互動、透過使用者動作狀態更新應用程式 UI,並視需要傳送變更,更新任何後端服務。

支援的媒體指令

UI 控制項狀態取決於 MediaStatus.supportedMediaCommands (適用於 iOS 和 Android 傳送方擴充控制器、在觸控裝置上執行的接收器和遠端控制應用程式),以及 Android TV 裝置上的接收器應用程式。如果在屬性中啟用特定位元的 Command,則會啟用與該動作相關的按鈕。如未設定這個值,則該按鈕會停用。您可以在 Web Receiver 上變更這些值:

  1. 使用 PlayerManager.setSupportedMediaCommands 來設定特定的 Commands
  2. 使用 addSupportedMediaCommands 新增指令
  3. 使用 removeSupportedMediaCommands 移除現有指令。
playerManager.setSupportedMediaCommands(cast.framework.messages.Command.SEEK |
  cast.framework.messages.Command.PAUSE);

當接收器準備更新的 MediaStatus 時,會在 supportedMediaCommands 屬性中加入變更。狀態廣播時,已連結的傳送端應用程式會據此更新 UI 中的按鈕。

如要進一步瞭解支援的媒體指令和觸控裝置,請參閱 Accessing UI controls 指南。

管理使用者動作狀態

使用者與 UI 互動或傳送語音指令時,可以控制與播放項目相關的內容和屬性播放操作。SDK 會自動處理控製播放的要求。如要修改目前播放項目的屬性 (例如 LIKE 指令),要求者應用程式必須處理這些屬性。SDK 提供一系列 API,用於處理這些類型的要求。如要支援這些要求,必須完成下列步驟:

  • 在載入媒體項目時,依據使用者的偏好設定設定 MediaInformation userActionStates
  • 攔截 USER_ACTION 訊息並決定要求的動作。
  • 更新 MediaInformation UserActionState 以更新使用者介面。

下列程式碼片段會攔截 LOAD 要求,並填入 LoadRequestDataMediaInformation。在此情況下,使用者會喜歡載入的內容。

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD, (loadRequestData) => {
      const userActionLike = new cast.framework.messages.UserActionState(
          cast.framework.messages.UserAction.LIKE);
      loadRequestData.media.userActionStates = [userActionLike];

      return loadRequestData;
    });

下列程式碼片段會攔截 USER_ACTION 訊息,並處理要求變更的後端呼叫。然後呼叫在接收器上更新 UserActionState

playerManager.setMessageInterceptor(cast.framework.messages.MessageType.USER_ACTION,
  (userActionRequestData) => {
    // Obtain the media information of the current content to associate the action to.
    let mediaInfo = playerManager.getMediaInformation();

    // If there is no media info return an error and ignore the request.
    if (!mediaInfo) {
        console.error('Not playing media, user action is not supported');
        return new cast.framework.messages.ErrorData(messages.ErrorType.BAD_REQUEST);
    }

    // Reach out to backend services to store user action modifications. See sample below.
    return sendUserAction(userActionRequestData, mediaInfo)

    // Upon response from the backend, update the client's UserActionState.
    .then(backendResponse => updateUserActionStates(backendResponse))

    // If any errors occurred in the backend return them to the cast receiver.
    .catch((error) => {
      console.error(error);
      return error;
    });
});

下列程式碼片段會模擬對後端服務的呼叫。函式會檢查 UserActionRequestData 以瞭解使用者要求的變更類型,而且只有在後端支援動作時,才會發出網路呼叫。

function sendUserAction(userActionRequestData, mediaInfo) {
  return new Promise((resolve, reject) => {
    switch (userActionRequestData.userAction) {
      // Handle user action changes supported by the backend.
      case cast.framework.messages.UserAction.LIKE:
      case cast.framework.messages.UserAction.DISLIKE:
      case cast.framework.messages.UserAction.FOLLOW:
      case cast.framework.messages.UserAction.UNFOLLOW:
      case cast.framework.messages.UserAction.FLAG:
      case cast.framework.messages.UserAction.SKIP_AD:
        let backendResponse = {userActionRequestData: userActionRequestData, mediaInfo: mediaInfo};
        setTimeout(() => {resolve(backendResponse)}, 1000);
        break;
      // Reject all other user action changes.
      default:
        reject(
          new cast.framework.messages.ErrorData(cast.framework.messages.ErrorType.INVALID_REQUEST));
    }
  });
}

下列程式碼片段使用 UserActionRequestData,並從 MediaInformation 中新增或移除 UserActionState。更新 MediaInformationUserActionState 會變更與要求動作相關聯的按鈕狀態。這項變更會反映在智慧螢幕控制項 UI、遙控器應用程式和 Android TV UI 中。此設定也會透過傳出的 MediaStatus 訊息播送,以更新 iOS 和 Android 傳送端的已展開控制器 UI。

function updateUserActionStates(backendResponse) {
  // Unwrap the backend response.
  let mediaInfo = backendResponse.mediaInfo;
  let userActionRequestData = backendResponse.userActionRequestData;

  // If the current item playing has changed, don't update the UserActionState for the current item.
  if (playerManager.getMediaInformation().entity !== mediaInfo.entity) {
    return;
  }

  // Check for existing userActionStates in the MediaInformation.
  // If none, initialize a new array to populate states with.
  let userActionStates = mediaInfo.userActionStates || [];

  // Locate the index of the UserActionState that will be updated in the userActionStates array.
  let index = userActionStates.findIndex((currUserActionState) => {
    return currUserActionState.userAction == userActionRequestData.userAction;
  });

  if (userActionRequestData.clear) {
    // Remove the user action state from the array if cleared.
    if (index >= 0) {
      userActionStates.splice(index, 1);
    }
    else {
      console.warn("Could not find UserActionState to remove in MediaInformation");
    }
  } else {
    // Add the UserActionState to the array if enabled.
    userActionStates.push(
      new cast.framework.messages.UserActionState(userActionRequestData.userAction));
  }

  // Update the UserActionState array and set the new MediaInformation
  mediaInfo.userActionStates = userActionStates;
  playerManager.setMediaInformation(mediaInfo, true);
  return;
}

語音指令

支援 Google 助理的裝置專用的 Web Receiver SDK 目前支援以下媒體指令。您可以在 cast.framework.PlayerManager 中找到這些指令的預設實作方式。

指令 說明
開始 從暫停狀態播放或繼續播放。
暫停 暫停目前正在播放的內容。
返回 跳到媒體待播清單的上一個媒體項目。
繼續 跳到媒體待播清單的下一個媒體項目。
停止 停止目前正在播放的媒體。
Repeat None 待佇列中的最後一個項目播放完畢後,停止在佇列中重複播放媒體項目。
重複播放單曲 無限期重複播放目前播放的媒體內容。
重複播放所有項目 待佇列中的最後一個項目播放後,重複佇列中的所有項目。
重複播放所有歌曲和隨機播放 待佇列中的最後一個項目播放完畢後,請隨機排序佇列,並重複執行佇列中的所有項目。
隨機播放 隨機播放媒體待播清單中的媒體項目。
開啟 / 關閉隱藏式輔助字幕 為媒體啟用 / 停用隱藏式輔助字幕。啟用 / 停用功能也支援語言。
跳轉絕對時間 跳到指定的絕對時間。
跳轉相對於目前時間的時間 依據目前的播放時間,向前或向後跳轉指定時間範圍。
再玩一次 如果目前未播放任何媒體,則重新啟動目前播放的媒體,或播放上次播放的媒體項目。
設定播放速率 更動媒體播放速率。根據預設,請處理這個問題。您可以使用 SET_PLAYBACK_RATE 訊息攔截器覆寫傳入的頻率要求。

支援的媒體指令和語音指令

如要避免語音指令在支援 Google 助理的裝置上觸發媒體指令,您必須先設定要支援的支援的媒體指令。接著,您必須啟用 CastReceiverOptions.enforceSupportedCommands 屬性,以強制執行這些指令。Cast SDK 寄件者和支援觸控裝置上的 UI 會變更以反映這些設定。如未啟用此標記,傳入的語音指令將會執行。

舉例來說,如果您允許來自傳送者應用程式的 PAUSE 和支援觸控功能的裝置,您必須一併設定接收器來反映這些設定。設定後,如果支援的指令清單中未包含任何傳入的語音指令,系統就會捨棄該指令。

在以下範例中,我們在啟動 CastReceiverContext 時提供 CastReceiverOptions。我們開始支援 PAUSE 指令,並強制玩家僅支援該指令。現在,如果語音指令要求執行其他作業 (例如 SEEK),系統會拒絕要求。系統會通知使用者,說明目前尚不支援指令。

const context = cast.framework.CastReceiverContext.getInstance();

context.start({
  enforceSupportedCommands: true,
  supportedCommands: cast.framework.messages.Command.PAUSE
});

您可以為要限制的每個指令套用不同的邏輯。請移除 enforceSupportedCommands 標記,並且針對要限制您可以攔截傳入訊息的每個指令。這裡會攔截 SDK 提供的要求,讓支援 Google 助理的裝置發出 SEEK 指令不會在 Web Receiver 應用程式中觸發搜尋作業。

針對應用程式不支援的媒體指令,請傳回適當的錯誤原因,例如 NOT_SUPPORTED

playerManager.setMessageInterceptor(cast.framework.messages.MessageType.SEEK,
  seekData => {
    // Block seeking if the SEEK supported media command is disabled
    if (!(playerManager.getSupportedMediaCommands() & cast.framework.messages.Command.SEEK)) {
      let e = new cast.framework.messages.ErrorData(cast.framework.messages.ErrorType
      .INVALID_REQUEST);
      e.reason = cast.framework.messages.ErrorReason.NOT_SUPPORTED;
      return e;
    }

    return seekData;
  });

背景透過語音活動進行背景

如果 Cast 平台是因為 Google 助理活動 (例如監聽使用者語音或回應) 而在背景執行應用程式音效,系統會在活動開始時,將 NOT_IN_FOCUSFocusState 訊息傳送至網路接收器應用程式。活動結束時,系統會傳送另一則含有 IN_FOCUS 的訊息。視應用程式和播放的媒體而定,您可能需要攔截訊息類型 FOCUS_STATE,藉此在 FocusStateNOT_IN_FOCUS 時暫停媒體。

舉例來說,如果 Google 助理回應使用者查詢,就很適合暫停播放有聲書。

playerManager.setMessageInterceptor(cast.framework.messages.MessageType.FOCUS_STATE,
  focusStateRequestData => {
    // Pause content when the app is out of focus. Resume when focus is restored.
    if (focusStateRequestData.state == cast.framework.messages.FocusState.NOT_IN_FOCUS) {
      playerManager.pause();
    } else {
      playerManager.play();
    }

    return focusStateRequestData;
  });

語音指定的字幕語言

如果使用者未明確指定字幕語言,字幕語言就會與指令使用的語言相同。在這些情況下,傳入訊息的 isSuggestedLanguage 參數會指出相關語言是否由使用者建議或明確要求。

舉例來說,將「Ok Google,開啟字幕」指令的 isSuggestedLanguage 設為 true,因為該指令是以該指令使用的語言推斷出來。如果語言是明確要求 (例如「Ok Google,開啟英文字幕」),isSuggestedLanguage 會設為 false

中繼資料和語音投放

根據預設,雖然網路接收器會處理語音指令,但建議您確保內容的中繼資料完整且正確。這可確保 Google 助理能正確處理語音指令,並在新類型的介面 (例如 Google Home 應用程式和 Google Home Hub) 中正確顯示中繼資料。

變更串流裝置

保留工作階段狀態是串流傳輸的基礎,可讓使用者透過語音指令、Google Home 應用程式或智慧螢幕,在不同裝置上移動現有的音訊和影片串流。媒體會在某部裝置 (來源) 上停止播放,然後在另一部 (目的地) 上繼續播放。任何安裝最新韌體的 Cast 裝置都可以做為串流傳輸的來源或目的地。

變更串流的事件流程如下:

  1. 在來源裝置上:
    1. 停止播放媒體。
    2. Web Receiver 應用程式收到用來儲存目前媒體狀態的指令。
    3. Web Receiver 應用程式已關閉。
  2. 在目標裝置上:
    1. 已載入 Web Receiver 應用程式。
    2. Web Receiver 應用程式接收指令可還原已儲存的媒體狀態。
    3. 繼續播放媒體。

媒體狀態的元素包括:

  • 歌曲、影片或媒體項目的特定位置或時間戳記。
  • 會排在較寬廣的待播清單中 (例如播放清單或藝人電台)。
  • 已驗證使用者。
  • 播放狀態 (例如播放或暫停)。

啟用串流轉移功能

如要執行網路接收器串流傳輸:

  1. 使用 STREAM_TRANSFER 指令更新 supportedMediaCommands
    playerManager.addSupportedMediaCommands(
    cast.framework.messages.Command.STREAM_TRANSFER, true);
  2. 您可以選擇覆寫 SESSION_STATERESUME_SESSION 訊息攔截器,如保留工作階段狀態所述。只有在需要將自訂資料儲存為工作階段快照時,才覆寫這些資料。否則,保留工作階段狀態的預設實作方式將支援串流傳輸。

保留工作階段狀態

Web Receiver SDK 會提供網路接收器應用程式的預設實作方式,透過拍攝目前媒體狀態的快照、將狀態轉換為載入要求,以及透過載入要求恢復工作階段,以保留工作階段狀態。

如有需要,您可以在 SESSION_STATE 訊息攔截器中覆寫 Web Receiver 產生的載入要求。如要在載入要求中加入自訂資料,建議您將其放入 loadRequestData.customData

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.SESSION_STATE,
    function (sessionState) {
        // Override sessionState.loadRequestData if needed.
        const newCredentials = updateCredentials_(sessionState.loadRequestData.credentials);
        sessionState.loadRequestData.credentials = newCredentials;

        // Add custom data if needed.
        sessionState.loadRequestData.customData = {
            'membership': 'PREMIUM'
        };

        return sessionState;
    });

您可以從 RESUME_SESSION 訊息攔截器中的 loadRequestData.customData 擷取自訂資料。

let cred_ = null;
let membership_ = null;

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.RESUME_SESSION,
    function (resumeSessionRequest) {
        let sessionState = resumeSessionRequest.sessionState;

        // Modify sessionState.loadRequestData if needed.
        cred_ = sessionState.loadRequestData.credentials;

        // Retrieve custom data.
        membership_ = sessionState.loadRequestData.customData.membership;

        return resumeSessionRequest;
    });

預先載入內容

Web Receiver 支援在佇列中的目前播放項目之後預先載入媒體項目。

預先載入作業會預先下載後續項目的多個區段。規格是根據 QueueItem 物件中的 preloadTime 值完成 (如未提供,則預設為 20 秒)。時間以秒為單位,相對於目前播放項目的結尾。只有正值有效。例如,如果值為 10 秒,則會在前一個項目結束的 10 秒前預先載入此項目。如果預先載入的時間比當前 Item 的剩餘時間長,系統就會盡快執行預先載入作業。因此,如果在 queueItem 上指定非常大的預先載入值,每當我們播放目前的項目已經預先載入目前項目時,就可能產生效果。不過,我們保留這項設定和選擇權,開發人員將會影響目前播放項目的頻寬和串流效能。

預先載入功能預設適用於 HLS、DASH 和流暢的串流內容。

系統不會預先載入一般 MP4 影片和音訊檔案 (例如 MP3),因為投放裝置僅支援單一媒體元素,而且無法在現有內容項目播放時用來預先載入。

自訂訊息

訊息交換是網路接收器應用程式的主要互動方法。

傳送者使用傳送者執行平台 (Android、iOS、網頁) 的寄件端 API 向網路接收器傳送訊息。傳遞至事件監聽器的事件物件 (訊息資訊清單) 具有資料元素 (event.data),其中資料會採用特定事件類型的屬性。

Web Receiver 應用程式可能會選擇監聽指定命名空間中的訊息。因此,Web Receiver 應用程式被認為支援該命名空間通訊協定。隨後,所有已連線的寄件者都會在該命名空間進行通訊,以便使用適當的通訊協定。

所有命名空間都是由字串定義,且開頭須為「urn:x-cast:」,後面接著任何字串。例如:「urn:x-cast:com.example.cast.mynamespace」。

以下程式碼片段可讓網路接收器監聽已連線傳送者的自訂訊息:

const context = cast.framework.CastReceiverContext.getInstance();

const CUSTOM_CHANNEL = 'urn:x-cast:com.example.cast.mynamespace';
context.addCustomMessageListener(CUSTOM_CHANNEL, function(customEvent) {
  // handle customEvent.
});

context.start();

同樣地,網路接收器應用程式可傳送郵件給已連結的寄件者,讓寄件者隨時掌握網路接收器的狀態。Web Receiver 應用程式可以使用 CastReceiverContext 上的 sendCustomMessage(namespace, senderId, message) 傳送訊息。網路接收器可傳送訊息給個別寄件者,回應收到的訊息或應用程式狀態變更所致。除了點對點訊息 (上限為 64 KB) 以外,網路接收器也可能會向所有連線的寄件者廣播訊息。

Cast 適用於音訊裝置

如需支援純音訊播放的支援服務,請參閱 Google Cast 音訊裝置指南

Android TV

本節討論 Google Web Receiver 如何使用您的輸入內容做為播放內容,以及與 Android TV 的相容性。

將應用程式與遙控器整合

在 Android TV 裝置上執行的 Google Web Receiver,會將裝置控制輸入的輸入內容 (例如手持遙控器) 轉譯為為 urn:x-cast:com.google.cast.media 命名空間定義的媒體播放訊息,如「媒體播放訊息」所述。您的應用程式必須支援這些訊息,才能控制應用程式的媒體播放,以便讓 Android TV 控制項輸入提供基本的播放控制項。

Android TV 相容性規範

以下列舉幾個建議和避免常見錯誤,以確保您的應用程式與 Android TV 相容:

  • 請注意,使用者代理程式字串同時包含「Android」和「CrKey」;部分網站可能會因為偵測到「Android」標籤,而重新導向到行動版網站。請勿假設使用者代理程式字串中的「Android」一律代表行動裝置使用者。
  • Android 的媒體堆疊可能會使用透明的 GZIP 擷取資料。請確認您的媒體資料能回應 Accept-Encoding: gzip
  • Android TV HTML5 媒體事件的觸發時間可能與 Chromecast 不同,這可能透露 Chromecast 隱藏的問題。
  • 更新媒體時,請使用 <audio>/<video> 元素觸發的媒體相關事件,例如 timeupdatepausewaiting。請避免使用 progresssuspendstalled 等網路相關事件,因為這類事件通常依附於平台。如要進一步瞭解如何在接收器中處理媒體事件,請參閱媒體事件
  • 設定接收方網站的 HTTPS 憑證時,請務必加入中繼 CA 憑證。請參閱 Qualsys SSL 測試頁面進行驗證:如果您網站的信任憑證路徑包含標示為「額外下載」的 CA 憑證,則該憑證可能無法在 Android 平台上載入。
  • Chromecast 會在 720p 圖形平面上顯示接收器頁面,其他投放平台 (包括 Android TV) 則最高可以顯示 1080p 的頁面。請確保接收器頁面能以不同的解析度正常縮放。