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

本頁面包含自訂 Web 接收器應用程式可用功能的程式碼片段和說明。

  1. 代表 Web 接收端內建播放器 UI 的 cast-media-player 元素。
  2. cast-media-player 元素的自訂 CSS 樣式,可用於設定各種 UI 元素的樣式,例如 background-image、splash-image 和 font-family。
  3. 載入 Web 接收端架構的指令碼元素。
  4. 用於攔截訊息和處理事件的 JavaScript 程式碼。
  5. 排入自動播放佇列。
  6. 設定播放的選項。
  7. 設定 Web 接收端內容的選項。
  8. 設定網路接收端應用程式支援指令的選項。
  9. 啟動 Web 接收端應用程式的 JavaScript 呼叫。

應用程式設定和選項

設定應用程式

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

以下範例說明如何覆寫預設行為,偵測傳送端連線是否仍處於連線狀態。如果網路接收端無法與傳送端通訊達 maxInactivity 秒,系統會調度 SENDER_DISCONNECTED 事件。以下設定會覆寫這項逾時設定。這項功能在偵錯時非常實用,因為當沒有連線的傳送端處於 IDLE 狀態時,Web 接收端應用程式不會關閉 Chrome 遠端偵錯工具工作階段。

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

設定播放器

載入內容時,Web 接收端 SDK 可讓您使用 cast.framework.PlaybackConfig 設定播放變數,例如 DRM 資訊、重試設定和要求處理常式。這項資訊由 PlayerManager 處理,並在建立播放器時進行評估。每次將新的載入作業傳遞至 Web Receiver SDK 時,系統都會建立播放器。播放器建立後,系統會在下次載入內容時評估對 PlaybackConfig 的修改。SDK 提供下列方法來修改 PlaybackConfig。

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

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 接收端 SDK 可讓 Web 接收端應用程式處理播放器事件。事件監聽器會採用 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 接收端 SDK 可讓 Web 接收端應用程式攔截訊息,並對這些訊息執行自訂程式碼。訊息攔截器會採用 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 接收端應用程式應傳回適當的 cast.framework.messages.ErrorType 和 cast.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 訊息中載入媒體,包括 entity、contentUrl 和 contentId。

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

建議使用 entity 儲存真實 ID 或金鑰參數,並使用 contentUrl 儲存媒體網址。以下程式碼片段範例顯示,LOAD 要求中包含 entity,並擷取可播放的 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 方法會提供已連線 Cast 裝置,以及與其連結的視訊或音訊裝置的裝置資訊。getDeviceCapabilities 方法會提供 Google 助理、藍牙,以及已連結螢幕和音訊裝置的支援資訊。

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

這個範例會分別使用 IS_HDR_SUPPORTED 和 IS_DV_SUPPORTED 鍵,檢查 Web 接收器裝置是否能播放 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 裝置上的遙控器,與 Web 接收端應用程式互動。Cast SDK 提供多種 API,可讓 Web 接收端應用程式處理這些互動、透過使用者動作狀態更新應用程式 UI,並視需要傳送變更來更新任何後端服務。

支援的媒體指令

UI 控制項狀態是由 MediaStatus.supportedMediaCommands 驅動,適用於 iOS 和 Android 傳送端展開控制器、在觸控裝置上執行的接收端和遙控器應用程式,以及 Android TV 裝置上的接收端應用程式。在屬性中啟用特定位元 Command 時,與該動作相關的按鈕就會啟用。如未設定值,按鈕會停用。您可以在 Web 接收端上變更這些值,方法如下:

  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,以更新 UI。

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

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。更新 MediaInformation 的 UserActionState 會變更與所要求動作相關聯的按鈕狀態。這項異動會反映在智慧螢幕控制項 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 接收端 SDK 目前支援下列媒體指令。這些指令的預設實作位於 cast.framework.PlayerManager。

指令 說明
播放 播放或從暫停狀態繼續播放。
暫停 暫停目前播放的內容。
返回 跳至媒體佇列中的上一個媒體項目。
繼續 跳到媒體佇列中的下一個媒體項目。
停止 停止播放目前媒體。
不重複 待播清單中的最後一個項目播放完畢後,停用清單中媒體項目的重複播放功能。
重複播放單曲 無限次重複播放目前的媒體。
全部重複 待播清單中的最後一個項目播放完畢後,重複播放清單中的所有項目。
全部重複播放和隨機播放 待播清單中的最後一個項目播放完畢後,隨機播放待播清單,並重複播放待播清單中的所有項目。
隨機播放 隨機播放媒體佇列中的媒體項目。
開啟/關閉隱藏式輔助字幕 啟用/停用媒體的隱藏式輔助字幕。您也可以依語言啟用/停用。
跳轉至絕對時間 跳至指定的絕對時間。
跳轉至相對於目前時間的時間 相對於目前播放時間,向前或向後跳轉指定的時間範圍。
再玩一次 重新播放目前播放的媒體,或播放上次播放的媒體項目 (如果目前未播放任何內容)。
設定播放速率 調整媒體播放速率。這項作業預設會自動處理。您可以使用 SET_PLAYBACK_RATE 訊息攔截器覆寫傳入的費率要求。

支援的語音媒體指令

如要避免語音指令在支援 Google 助理的裝置上觸發媒體指令,請先設定您打算支援的媒體指令。接著,您必須啟用 CastReceiverOptions.enforceSupportedCommands 屬性,強制執行這些指令。Cast SDK 傳送端和觸控裝置上的使用者介面會隨之變更,反映這些設定。如果未啟用旗標,系統會執行傳入的語音指令。

舉例來說,如果您允許從傳送端應用程式和觸控裝置進行 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 接收器應用程式中的跳轉。

如果應用程式不支援媒體指令,請傳回適當的錯誤原因,例如 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_FOCUS 的 FocusState 訊息傳送至 Web 接收端應用程式。活動結束時,系統會傳送另一則包含 IN_FOCUS 的訊息。視應用程式和播放的媒體而定,您可能需要在 FocusState 為 NOT_IN_FOCUS 時,透過攔截 FOCUS_STATE 訊息類型來暫停媒體。

舉例來說,如果 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。

中繼資料和語音投放

雖然語音指令預設由 Web 接收端處理,但您應確保內容的中繼資料完整且正確。這可確保 Google 助理能正確處理語音指令,並在 Google Home 應用程式和 Google Home Hub 等智慧螢幕等新型介面上正確顯示中繼資料。

變更串流裝置

保留工作階段狀態是變更串流裝置的基礎,使用者可以透過語音指令、Google Home 應用程式或智慧螢幕,在裝置之間移動現有的音訊和視訊串流。媒體會在來源裝置上停止播放,並在目標裝置上繼續播放。任何搭載最新韌體的 Cast 裝置,都可做為變更串流裝置的來源或目的地。

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

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

媒體狀態的元素包括:

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

啟用變更串流裝置功能

如要為 Web 接收端導入變更串流裝置功能,請按照下列步驟操作:

  1. 使用 STREAM_TRANSFER 指令更新 supportedMediaCommands:
    playerManager.addSupportedMediaCommands(
    cast.framework.messages.Command.STREAM_TRANSFER, true);
  2. 您可以視需要覆寫 SESSION_STATE 和 RESUME_SESSION 訊息攔截器,如「保留工作階段狀態」一節所述。只有在需要將自訂資料儲存為工作階段快照的一部分時,才應覆寫這些方法。否則,保留工作階段狀態的預設實作會支援變更串流裝置。

保留工作階段狀態

Web 接收端 SDK 提供 Web 接收端應用程式的預設實作,可擷取目前媒體狀態的快照、將狀態轉換為載入要求,並使用載入要求繼續工作階段,藉此保留工作階段狀態。

如有需要,可在 SESSION_STATE 訊息攔截器中覆寫網路接收端產生的載入要求。如要在載入要求中加入自訂資料,建議您將資料放入 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;
    });

內容預先載入

網路接收器支援預先載入佇列中目前播放項目之後的媒體項目。

預先載入作業會預先下載後續項目的多個片段。規格是根據 QueueItem 物件中的 preloadTime 值完成 (如未提供,則預設為 20 秒)。時間以秒為單位,相對於目前播放項目的結尾。只能使用正值。舉例來說,如果值為 10 秒,這個項目會在前一個項目結束前 10 秒預先載入。如果預先載入時間超過 currentItem 的剩餘時間,系統會盡快預先載入。因此,如果在 queueItem 上指定非常大的預先載入值,就能達到在播放目前項目時,就預先載入下一個項目的效果。不過,我們將這項設定和選擇留給開發人員,因為這個值可能會影響目前播放項目的頻寬和串流效能。

根據預設,預先載入功能適用於 HLS、DASH 和 Smooth 串流內容。

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

自訂訊息

訊息交換是 Web 接收端應用程式的主要互動方式。

傳送端會使用傳送端 API,向 Web 接收端發出訊息,具體取決於傳送端執行的平台 (Android、iOS、Web)。傳遞至事件監聽器的事件物件 (訊息的表現形式) 具有資料元素 (event.data),其中資料會採用特定事件類型的屬性。

網路接收端應用程式可以選擇監聽指定命名空間的訊息。這樣一來,網路接收端應用程式就能支援該命名空間通訊協定。接著,任何想在該命名空間上通訊的已連結傳送端,都必須使用適當的通訊協定。

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

以下是 Web 接收端監聽已連線傳送端自訂訊息的程式碼片段:

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 接收端應用程式可以傳送訊息給已連線的傳送端,讓傳送端掌握 Web 接收端的狀態。Web 接收端應用程式可以使用 CastReceiverContext 上的 sendCustomMessage(namespace, senderId, message) 傳送訊息。網路接收端可以傳送訊息給個別傳送端,以回應收到的訊息或應用程式狀態變更。除了點對點訊息 (上限為 64 KB) 之外,網路接收端也可以向所有連線的傳送端廣播訊息。

Cast for 音訊裝置

如需僅播放音訊的支援,請參閱 Google Cast 音訊裝置指南。

Android TV

本節說明 Google Web Receiver 如何將輸入內容做為播放內容,以及 Android TV 相容性。

將應用程式與遙控器整合

在 Android TV 裝置上執行的 Google Web 接收器會將裝置控制輸入 (即手持遙控器) 的輸入內容,轉譯為針對 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> 元素觸發的媒體相關事件,例如 timeupdate、pause 和 waiting。請避免使用 progress、suspend 和 stalled 等網路相關事件,因為這些事件通常與平台相關。如要進一步瞭解如何在接收端處理媒體事件,請參閱「媒體事件」。
  • 設定接收端網站的 HTTPS 憑證時,請務必加入中繼 CA 憑證。請參閱 Qualsys SSL 測試頁面,確認網站的信任憑證路徑是否包含標示為「額外下載」的 CA 憑證。如果是,則可能無法在 Android 平台上載入。
  • Chromecast 會在 720p 圖形平面上顯示接收端頁面,而 Android TV 等其他 Cast 平台則可顯示高達 1080p 的頁面。請確保接收端頁面在不同解析度下都能正常縮放。