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

透過集合功能整理內容 你可以依據偏好儲存及分類內容。

此頁麵包含自訂 Web Receiver 應用程式提供的程式碼片段和功能說明。

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

應用程式設定和選項

CastReceiverContext 是開發人員最外層的類別,可管理基礎程式庫的載入作業,並處理 Web Receiver SDK 的初始化作業。

如果 Web Receiver API 偵測到傳送者已中斷連線,就會發出 SENDER_DISCONNECTED 事件。如果網路接收器無法按照我們所述 (如 maxInactivity 秒) 所述的方式來與傳送者通訊,也會發出 SENDER_DISCONNECTED 事件。在開發過程中,建議您將 maxInactivity 設為較高的值,這樣在使用 Chrome 遠端偵錯工具對應用程式進行偵錯時,Web 接收器應用程式不會關閉:

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

不過,對於 published Web Receiver 應用程式而言,最好不要設定 maxInactivity,而是改用預設值。請注意,應用程式中的接收器接收器選項只能設定一次。

另一個設定是 cast.framework.PlaybackConfig。設定方式如下:

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

此設定會影響每一個內容播放,而且基本上能夠提供覆寫行為。如需開發人員可覆寫的行為清單,請參閱 cast.framework.PlaybackConfig 的定義。如要變更內容之間的設定,可以使用 PlayerManager 取得其目前的 playbackConfig,修改或新增覆寫值並重設 playbackConfig,如下所示:

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

請注意,如果 PlaybackConfig 未被覆寫,getPlaybackConfig() 會傳回空值物件。且 PlaybackConfig that 中的任何屬性為 undefined 將使用預設值。

事件監聽器

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 是專為可播放的網址設計,且在可用後即可使用。

contentId 已淘汰,因為它們的值不明確,即媒體網址、實際 ID 或自訂查詢的鍵參數。

建議使用 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 方法會提供已連結 Cast 裝置以及已連結影片或音訊裝置的裝置資訊。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 裝置上的遙控器來與 Web Receiver 應用程式進行互動。Cast SDK 提供多種 API,可讓 Web Receiver 應用程式處理這些互動、透過使用者動作狀態更新應用程式 UI,並視需要傳送變更內容以更新任何後端服務。

支援的媒體指令

UI 控制狀態是由 MediaStatus.supportedMediaCommands 驅動,適用於 iOS 和 Android 寄件者擴展控制器、在觸控裝置上執行的接收器和遙控應用程式,以及 Android TV 裝置上的接收器應用程式。在屬性中啟用特定位元 Command 時,與該動作相關的按鈕已啟用。如未設定該值,則會停用按鈕。您可以透過下列方式在網路接收器中變更這些值:

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

接收器在準備更新的 MediaStatus 時,會在 supportedMediaCommands 屬性中加入變更。當狀態廣播時,已連結的寄件者應用程式會據此更新使用者介面中的按鈕。

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

管理使用者動作狀態

當使用者與使用者介面互動或傳送語音指令時,他們可以控制與播放項目相關的內容和屬性播放。控製播放的請求是由 SDK 自動處理。針對目前播放項目修改屬性的要求 (例如 LIKE 指令),要求接收器應用程式必須處理這些要求。SDK 提供一系列的 API,用於處理這些類型的要求。如要支援這些要求,您必須完成下列事項:

  • 攔截 USER_ACTION 訊息並決定要求的動作。
  • 更新 MediaInformation UserActionState 以更新 UI。

下方的程式碼片段會攔截 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 傳送者所擴充控制器的使用者介面。

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 中找到這些指令的預設實作方式。

指令 說明
開始 從暫停狀態播放或繼續播放。
暫停 暫停目前播放的內容。
返回 跳至媒體佇列中的上一個媒體項目。
繼續 跳到媒體佇列中的下一個媒體項目。
停止 停止目前播放的媒體。
重複播放「無」選項 停止重複播放佇列中的最後一個項目。
重複播放單曲 無限期播放目前正在播放的媒體內容。
重複播放所有項目 播放待播清單的最後一個項目時,請重複播放佇列中的所有項目。
重複播放所有歌曲及隨機播放 佇列中的最後一個項目播放完畢之後,請隨機播放佇列中的項目,然後重複播放佇列中的所有項目。
隨機播放 在您的媒體佇列中隨機播放媒體項目。
開啟 / 關閉隱藏式輔助字幕 啟用 / 停用媒體的隱藏式輔助字幕。「啟用 / 停用」亦提供特定語言版本。
跳轉絕對時間 跳到指定的絕對時間。
跳轉到目前時間所花費的時間 按照目前播放時間向前或向前快轉指定時間範圍。
再玩一次 如果目前未播放任何媒體,請重新啟動目前播放的媒體,或是播放上次播放的媒體項目。
設定播放速率 媒體播放速率不一。系統預設會處理上述資訊。您可以使用 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;
  });

語音活動的背景

如果投放平台因 Google 助理活動 (例如聽取使用者語音或反向回應) 而讓應用程式發出音效,當活動開始時,系統會將 NOT_IN_FOCUSFocusState 訊息傳送至 Web Receiver 應用程式。活動結束時,系統會傳送另一封含有 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 參數會指出使用者建議或明確要求相關聯的語言。

舉例來說,isSuggestedLanguage 的「Ok Google,打開字幕」指令會設為 true,因為系統會根據指令執行的語言來推斷語言。如果明確要求語言 (例如「Ok Google,開啟英文字幕」),isSuggestedLanguage 會設為 false

中繼資料和語音投放

根據預設,Web Receiver 會處理語音指令,但請務必確保內容的中繼資料完整且正確。這可確保 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 接收器的

如有需要,您可以在 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;
    });

內容預先載入

網頁接收器支援在媒體目前播放的項目之後預先載入媒體項目。

預先載入作業會預先下載即將推出的幾個項目。該規格是在 QueueItem 物件的 preloadTime 值上完成 (如未提供,則預設為 20 秒)。時間以秒為單位,相對於目前播放項目的結束。只有正值有效。例如,如果值為 10 秒,此項目會在前一項項目完成前 10 秒預先載入。如果預先載入時間高於目前項目所剩的時間,系統會盡快預先載入。因此,如果在 QueueItem 上指定極大的預先載入值,則當我們播放目前的項目時,可能會預先載入下一個項目的效果。不過,由於此設定可能會影響目前播放項目的頻寬和串流效能,因此我們會將這項設定的設定保留給開發人員。

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

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

自訂訊息

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

傳送者使用寄件者 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 應用程式也可以向寄件者傳送已連線的寄件者資料,進而讓傳送者瞭解網路接收器的狀態。Web 接收器應用程式可透過 CastReceiverContext 使用 sendCustomMessage(namespace, senderId, message) 傳送訊息。網路接收器可傳送訊息至個別寄件者,以回應收到的訊息或應用程式狀態變更。除了點對點訊息 (上限為 64 KB) 之外,Web Receiver 也會向所有連線的寄件者發送訊息。

投放音訊裝置

如需純音訊播放的支援資訊,請參閱 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 的 Cast 平台也可能以 1080p 的螢幕顯示網頁。確保您的接收器網頁在不同解析度下都能正常縮放。