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

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

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

應用程式設定與選項

設定應用程式

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

以下範例說明如何覆寫預設行為,以便偵測寄件者連線是否仍在主動連線。如果網路接收器無法在 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);

設定播放器

載入內容時,網路接收器 SDK 可讓您使用 cast.framework.PlaybackConfig 設定播放變數,例如 DRM 資訊、重試設定和要求處理常式。這項資訊會由 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 接收器應用程式應傳回適當的 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 中定義。

這個範例會檢查網路接收器裝置是否能分別使用 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 控制項狀態是由 iOS 和 Android 傳送者展開控制器、在觸控裝置上執行的接收器和遠端控制應用程式,以及 Android TV 裝置上的接收器應用程式所驅動的 MediaStatus.supportedMediaCommands 所驅動。在屬性中啟用特定的位元 Command 時,系統會啟用與該動作相關的按鈕。如未設定此值,系統會停用該按鈕。您可以在網路接收端變更這些值,方法如下:

  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 助理的裝置網路接收器 SDK 目前支援下列媒體指令。您可以在 cast.framework.PlayerManager 中找到這些指令的預設實作方式。

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

支援的語音指令媒體指令

為防止語音指令在支援 Google 助理的裝置上觸發媒體指令,您必須先設定支援的媒體指令,以支援 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 的訊息。視應用程式和正在播放的媒體而定,您可能需要在 FocusStateNOT_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

中繼資料和語音投放

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

變更串流裝置

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

串流轉移事件流程如下:

  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 訊息攔截器覆寫網路接收端產生的載入要求。如要將自訂資料加入載入要求中,建議您將自訂資料放入 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 上指定極大量的預先載入值,其中一種就能在播放目前項目已預先載入下一個項目時達到效果。不過,我們保留設定和選項,因為這個值可能會影響目前播放項目的頻寬和串流效能。

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

由於投放裝置僅支援一個媒體元素,因此在現有內容項目仍在播放期間,無法預先載入一般 MP4 影片和音訊檔案 (例如 MP3)。

自訂訊息

訊息交換是 Web Receiver 應用程式的主要互動方法。

傳送者使用傳送者所執行平台的傳送者 API (Android、iOS、網頁),向網路接收器發送訊息。傳遞至事件監聽器的事件物件 (也就是訊息的資訊清單) 具有資料元素 (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 網路接收器會將裝置控制輸入來源 (即手持遙控器) 的輸入內容,轉換為針對 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 隱藏的問題。
  • 更新媒體時,請使用 timeupdatepausewaiting<audio>/<video> 元素觸發的媒體相關事件。請避免使用 progresssuspendstalled 等網路相關事件,因為這些事件往往依平台而異。如要進一步瞭解如何在接收器中處理媒體事件,請參閱「媒體事件」。
  • 設定接收端網站的 HTTPS 憑證時,請務必加入中繼 CA 憑證。請參閱 Qualsys SSL 測試頁面確認:如果網站的信任憑證路徑包含標示為「額外下載」的 CA 憑證,就無法在 Android 平台上載入。
  • 雖然 Chromecast 在 720p 圖形平面上顯示接收器頁面,但其他 Cast 平台 (包括 Android TV) 也可能會顯示最高 1080p 的網頁。請確保接收方頁面能以不同的解析度正常縮放。