เพิ่มฟีเจอร์หลักลงในตัวรับสัญญาณเว็บที่กำหนดเอง

หน้านี้มีข้อมูลโค้ดและคำอธิบายฟีเจอร์ที่พร้อมใช้งานสำหรับแอป Custom Web Receiver

  1. องค์ประกอบ cast-media-player ที่แสดงถึง UI ของเพลเยอร์ในตัวที่มาพร้อมกับ Web Receiver
  2. การจัดรูปแบบที่คล้ายกับ CSS ที่กำหนดเองสำหรับองค์ประกอบ cast-media-player เพื่อจัดรูปแบบองค์ประกอบ UI ต่างๆ เช่น background-image, splash-image และ font-family
  3. องค์ประกอบสคริปต์เพื่อโหลดเฟรมเวิร์ก Web Receiver
  4. โค้ด JavaScript เพื่อสกัดกั้นข้อความและจัดการเหตุการณ์
  5. คิวสำหรับการเล่นอัตโนมัติ
  6. ตัวเลือกในการกำหนดค่าการเล่น
  7. ตัวเลือกในการตั้งค่าบริบทของ Web Receiver
  8. ตัวเลือกในการตั้งค่าคำสั่งที่แอปรับบนเว็บรองรับ
  9. การเรียกใช้ JavaScript เพื่อเริ่มแอปพลิเคชัน Web Receiver

การกำหนดค่าและตัวเลือกของแอปพลิเคชัน

กำหนดค่าแอปพลิเคชัน

CastReceiverContext เป็นคลาสชั้นนอกสุดที่แสดงต่อนักพัฒนาซอฟต์แวร์ และจัดการการโหลดไลบรารีที่เกี่ยวข้อง รวมถึงจัดการการเริ่มต้น Web Receiver SDK SDK มี API ที่ช่วยให้นักพัฒนาแอปพลิเคชันกำหนดค่า SDK ผ่าน CastReceiverOptions ได้ ระบบจะประเมินการกำหนดค่าเหล่านี้ 1 ครั้งต่อการเปิดแอปพลิเคชัน และส่งไปยัง SDK เมื่อตั้งค่าพารามิเตอร์ที่ไม่บังคับในการเรียกใช้ start

ตัวอย่างด้านล่างแสดงวิธีลบล้างลักษณะการทำงานเริ่มต้นสำหรับการตรวจหาว่าการเชื่อมต่อของผู้ส่งยังคงเชื่อมต่ออยู่หรือไม่ เมื่อ Web Receiver ไม่สามารถสื่อสารกับผู้ส่งได้เป็นเวลา maxInactivity วินาที ระบบจะส่งเหตุการณ์ SENDER_DISCONNECTED การกำหนดค่าด้านล่างจะลบล้างระยะหมดเวลานี้ ซึ่งจะเป็นประโยชน์เมื่อแก้ไขข้อบกพร่อง เนื่องจากจะป้องกันไม่ให้แอป Web Receiver ปิดเซสชันโปรแกรมแก้ไขข้อบกพร่องระยะไกลของ Chrome เมื่อไม่มีผู้ส่งที่เชื่อมต่อในสถานะ IDLE

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

กำหนดค่าเพลเยอร์

เมื่อโหลดเนื้อหา Web Receiver SDK จะมีวิธีในการกำหนดค่าตัวแปรการเล่น เช่น ข้อมูล DRM, การกำหนดค่าการลองใหม่ และตัวแฮนเดิลคำขอโดยใช้ cast.framework.PlaybackConfig ข้อมูลนี้จะได้รับการจัดการโดย PlayerManager และจะได้รับการประเมินเมื่อสร้างเพลเยอร์ ระบบจะสร้างเพลเยอร์ทุกครั้งที่มีการส่งการโหลดใหม่ไปยัง Web Receiver SDK การแก้ไข PlaybackConfig หลังจากสร้างเพลเยอร์แล้วจะได้รับการประเมินในการโหลดเนื้อหาครั้งถัดไป SDK มีเมธอดต่อไปนี้สำหรับการแก้ไข PlaybackConfig

  • CastReceiverOptions.playbackConfig เพื่อลบล้างตัวเลือกการกำหนดค่าเริ่มต้นเมื่อเริ่มต้นใช้งาน CastReceiverContext
  • PlayerManager.getPlaybackConfig() เพื่อดูการกำหนดค่าปัจจุบัน
  • PlayerManager.setPlaybackConfig() เพื่อลบล้างการกำหนดค่าปัจจุบัน การตั้งค่านี้จะมีผลกับการโหลดครั้งต่อๆ ไปทั้งหมดหรือจนกว่าจะมีการลบล้างอีกครั้ง
  • PlayerManager.setMediaPlaybackInfoHandler() เพื่อใช้การกำหนดค่าเพิ่มเติมสำหรับรายการสื่อที่โหลดไว้ด้านบนของการกำหนดค่าปัจจุบันเท่านั้น ระบบจะเรียกใช้แฮนเดิลก่อนสร้างเพลเยอร์ การเปลี่ยนแปลงที่ทำที่นี่ไม่ใช่การเปลี่ยนแปลงถาวรและจะไม่รวมอยู่ในการค้นหาไปยัง getPlaybackConfig() เมื่อโหลดรายการสื่อถัดไป ระบบจะเรียกใช้แฮนเดิลนี้อีกครั้ง

ตัวอย่างด้านล่างแสดงวิธีตั้งค่า PlaybackConfig เมื่อเริ่มต้น CastReceiverContext การกำหนดค่าจะลบล้างคำขอขาออกเพื่อรับไฟล์ Manifest เครื่องมือจัดการระบุว่าควรส่งคำขอ Access-Control ของ CORS โดยใช้ข้อมูลเข้าสู่ระบบ เช่น คุกกี้หรือส่วนหัวการให้สิทธิ์

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

ตัวอย่างด้านล่างแสดงวิธีลบล้าง PlaybackConfig โดยใช้ Getter และ Setter ที่ระบุไว้ใน PlayerManager การตั้งค่านี้จะกำหนดค่าเพลเยอร์ให้เล่นเนื้อหาต่อหลังจากโหลดกลุ่มเนื้อหา 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 ที่แอปพลิเคชันใช้เพื่อรับ licenseUrl จาก contentId ของรายการปัจจุบัน

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

  return playbackConfig;
});

Listener เหตุการณ์

SDK ของ Web Receiver ช่วยให้แอป Web Receiver จัดการเหตุการณ์ของเพลเยอร์ได้ Listener เหตุการณ์จะใช้พารามิเตอร์ cast.framework.events.EventType (หรืออาร์เรย์ของพารามิเตอร์เหล่านี้) ที่ระบุเหตุการณ์ที่ควรทริกเกอร์ Listener อาร์เรย์ที่กำหนดค่าไว้ล่วงหน้าของ cast.framework.events.EventType ซึ่งมีประโยชน์สำหรับการแก้ไขข้อบกพร่องจะอยู่ใน cast.framework.events.category พารามิเตอร์เหตุการณ์จะให้ข้อมูลเพิ่มเติมเกี่ยวกับเหตุการณ์

ตัวอย่างเช่น หากต้องการทราบว่ามีการประกาศการเปลี่ยนแปลง 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.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;
        });
    });

การสกัดกั้นข้อความเทียบกับ Listener เหตุการณ์

ความแตกต่างที่สำคัญบางประการระหว่างการสกัดกั้นข้อความกับ Listener เหตุการณ์มีดังนี้

  • Listener เหตุการณ์จะไม่อนุญาตให้คุณแก้ไขข้อมูลคำขอ
  • คุณควรใช้ Listener เหตุการณ์เพื่อทริกเกอร์ Analytics หรือฟังก์ชันที่กำหนดเอง
playerManager.addEventListener(cast.framework.events.category.CORE,
    event => {
        console.log(event);
    });
  • การสกัดกั้นข้อความช่วยให้คุณฟังข้อความ สกัดกั้น และแก้ไขข้อมูลคำขอได้
  • การสกัดกั้นข้อความเหมาะที่สุดสำหรับการจัดการตรรกะที่กำหนดเองเกี่ยวกับข้อมูลคำขอ

กำลังโหลดสื่อ

MediaInformation มีพร็อพเพอร์ตี้มากมายสำหรับโหลดสื่อในข้อความ cast.framework.messages.MessageType.LOAD ซึ่งรวมถึง entity, contentUrl และ contentId

  • entity เป็นพร็อพเพอร์ตี้ที่แนะนำให้ใช้ในการติดตั้งใช้งานสำหรับทั้งแอปผู้ส่งและแอปผู้รับ พร็อพเพอร์ตี้คือ URL ของ Deep Link ซึ่งอาจเป็นเพลย์ลิสต์หรือเนื้อหาสื่อก็ได้ แอปพลิเคชันของคุณควรแยกวิเคราะห์ URL นี้และป้อนข้อมูลในช่องอื่นๆ อย่างน้อย 1 ช่องจาก 2 ช่อง
  • contentUrl สอดคล้องกับ URL ที่เล่นได้ซึ่งโปรแกรมเล่นจะใช้เพื่อโหลดเนื้อหา เช่น URL นี้อาจชี้ไปยังไฟล์ Manifest ของ DASH
  • contentId อาจเป็น URL ของเนื้อหาที่เล่นได้ (คล้ายกับพร็อพเพอร์ตี้ contentUrl) หรือตัวระบุที่ไม่ซ้ำกันสำหรับเนื้อหาหรือเพลย์ลิสต์ที่โหลดอยู่ หากใช้พร็อพเพอร์ตี้นี้เป็นตัวระบุ แอปพลิเคชันของคุณควรป้อน URL ที่เล่นได้ใน contentUrl

เราขอแนะนำให้ใช้ entity เพื่อจัดเก็บ REAL ID หรือพารามิเตอร์คีย์ และใช้ contentUrl สำหรับ URL ของสื่อ ตัวอย่างของกรณีนี้แสดงอยู่ในข้อมูลโค้ดต่อไปนี้ซึ่งมี 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 Assistant, บลูทูธ รวมถึงจอแสดงผลและอุปกรณ์เสียงที่เชื่อมต่อ

เมธอดนี้จะแสดงผลออบเจ็กต์ที่คุณค้นหาได้โดยส่งผ่าน Enum ที่ระบุรายการใดรายการหนึ่งเพื่อรับความสามารถของอุปกรณ์สำหรับ Enum นั้น โดยมีการกำหนด enum ไว้ใน cast.framework.system.DeviceCapabilities

ตัวอย่างนี้จะตรวจสอบว่าอุปกรณ์ตัวรับสัญญาณบนเว็บสามารถเล่น HDR และ DolbyVision (DV) ด้วยคีย์ IS_HDR_SUPPORTED และ IS_DV_SUPPORTED ตามลำดับได้หรือไม่

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();

การจัดการการโต้ตอบของผู้ใช้

ผู้ใช้สามารถโต้ตอบกับแอปพลิเคชัน Web Receiver ผ่านแอปพลิเคชันผู้ส่ง (เว็บ, Android และ iOS), คำสั่งเสียงในอุปกรณ์ที่พร้อมใช้งาน Assistant, การควบคุมด้วยการสัมผัสบนจออัจฉริยะ และรีโมตคอนโทรลในอุปกรณ์ Android TV 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 เมื่อมีการประกาศสถานะ แอปผู้ส่งที่เชื่อมต่อจะอัปเดตปุ่มใน UI ของตนตามนั้น

ดูข้อมูลเพิ่มเติมเกี่ยวกับคำสั่งสื่อและอุปกรณ์ระบบสัมผัสที่รองรับได้ที่คู่มือ Accessing UI controls

การจัดการสถานะการดำเนินการของผู้ใช้

เมื่อผู้ใช้โต้ตอบกับ UI หรือส่งคำสั่งเสียง ผู้ใช้จะควบคุมการเล่นเนื้อหาและพร็อพเพอร์ตี้ที่เกี่ยวข้องกับรายการที่เล่นได้ SDK จะจัดการคำขอที่ควบคุมการเล่นโดยอัตโนมัติ คำขอที่แก้ไขพร็อพเพอร์ตี้ของรายการที่กำลังเล่นอยู่ เช่น คำสั่ง LIKE กำหนดให้แอปพลิเคชันตัวรับต้องจัดการคำขอเหล่านั้น SDK มีชุด API เพื่อจัดการคำขอประเภทเหล่านี้ คุณต้องดำเนินการต่อไปนี้เพื่อรองรับคำขอเหล่านี้

  • ตั้งค่า MediaInformation userActionStates ตามค่ากำหนดของผู้ใช้เมื่อโหลดรายการสื่อ
  • สกัดกั้นข้อความ USER_ACTION และพิจารณาการดำเนินการที่ขอ
  • อัปเดต UserActionState MediaInformation เพื่ออัปเดต UI

ข้อมูลโค้ดต่อไปนี้จะสกัดกั้นคำขอ LOAD และป้อนข้อมูล MediaInformation ของ LoadRequestData ในกรณีนี้ ผู้ใช้ชอบเนื้อหาที่กำลังโหลด

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 และเพิ่มหรือนำ UserActionState ออกจาก MediaInformation การอัปเดต UserActionState ของ MediaInformation จะเปลี่ยนสถานะของปุ่มที่เชื่อมโยงกับการดำเนินการที่ขอ การเปลี่ยนแปลงนี้จะแสดงใน UI ของตัวควบคุมจออัจฉริยะ แอปรีโมตคอนโทรล และ UI ของ Android TV นอกจากนี้ยังมีการออกอากาศผ่านข้อความขาออก MediaStatus เพื่ออัปเดต UI ของตัวควบคุมแบบขยายสำหรับผู้ส่ง 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;
}

คำสั่งเสียง

ปัจจุบัน SDK ตัวรับสัญญาณบนเว็บรองรับคำสั่งสื่อต่อไปนี้สำหรับอุปกรณ์ที่พร้อมใช้งาน Assistant การใช้งานคำสั่งเหล่านี้โดยค่าเริ่มต้นจะอยู่ใน cast.framework.PlayerManager

คำสั่ง คำอธิบาย
Google Play เล่นหรือเล่นต่อจากสถานะหยุดชั่วคราว
หยุดชั่วคราว หยุดเนื้อหาที่เล่นอยู่ชั่วคราว
ก่อนหน้า ข้ามไปยังรายการสื่อก่อนหน้าในคิวสื่อ
ถัดไป ข้ามไปยังรายการสื่อถัดไปในคิวสื่อ
หยุด หยุดสื่อที่กำลังเล่นอยู่
ไม่เล่นซ้ำ ปิดใช้การเล่นซ้ำรายการสื่อในคิวเมื่อเล่นรายการสุดท้ายในคิวเสร็จแล้ว
เล่นซ้ำเพลงเดียว เล่นสื่อที่กำลังเล่นอยู่ซ้ำไปเรื่อยๆ
เล่นซ้ำทั้งหมด เล่นซ้ำทุกรายการในคิวเมื่อเล่นรายการสุดท้ายในคิวแล้ว
เล่นซ้ำทั้งหมดและสุ่ม เมื่อเล่นรายการสุดท้ายในคิวเสร็จแล้ว ให้สุ่มคิวและเล่นซ้ำรายการทั้งหมดในคิว
สุ่ม สุ่มรายการสื่อในคิวสื่อ
เปิด/ปิดคำบรรยายแทนเสียง เปิด/ปิดใช้คำบรรยายแทนเสียงสำหรับสื่อของคุณ นอกจากนี้ คุณยังเปิด/ปิดใช้ตามภาษาได้ด้วย
กรอไปที่เวลาสัมบูรณ์ ข้ามไปยังเวลาสัมบูรณ์ที่ระบุ
กรอไปยังเวลาที่สัมพันธ์กับเวลาปัจจุบัน ข้ามไปข้างหน้าหรือย้อนกลับตามระยะเวลาที่ระบุโดยสัมพันธ์กับเวลาที่เล่นอยู่
เล่นอีกครั้ง รีสตาร์ทสื่อที่กำลังเล่นอยู่ หรือเล่นรายการสื่อที่เล่นล่าสุดหากไม่มีสื่อใดเล่นอยู่
ตั้งค่าอัตราการเล่น ปรับเปลี่ยนอัตราการเล่นสื่อ ซึ่งควรได้รับการจัดการโดยค่าเริ่มต้น คุณสามารถใช้ตัวสกัดกั้นข้อความ SET_PLAYBACK_RATE เพื่อลบล้างคำขอราคาที่เข้ามาได้

คำสั่งเสียงสำหรับสื่อที่รองรับ

หากต้องการป้องกันไม่ให้คำสั่งเสียงเรียกใช้คำสั่งสื่อในอุปกรณ์ที่พร้อมใช้งาน Assistant คุณต้องตั้งค่าคำสั่งสื่อที่รองรับซึ่งคุณวางแผนจะรองรับก่อน จากนั้นคุณต้องบังคับใช้คำสั่งเหล่านั้นโดยเปิดใช้พร็อพเพอร์ตี้ CastReceiverOptions.enforceSupportedCommands UI ในอุปกรณ์ที่ส่งของ Cast SDK และอุปกรณ์ที่รองรับการสัมผัสจะเปลี่ยนไปตามการกำหนดค่าเหล่านี้ หากไม่ได้เปิดใช้แฟล็ก คำสั่งเสียงที่เข้ามาจะทำงาน

ตัวอย่างเช่น หากคุณอนุญาต PAUSE จากแอปพลิเคชันผู้ส่งและอุปกรณ์ที่รองรับการสัมผัส คุณต้องกำหนดค่าตัวรับสัญญาณให้สอดคล้องกับการตั้งค่าเหล่านั้นด้วย เมื่อกำหนดค่าแล้ว ระบบจะทิ้งคำสั่งเสียงที่เข้ามาหากไม่ได้รวมอยู่ในรายการคำสั่งที่รองรับ

ในตัวอย่างด้านล่าง เราจะระบุ CastReceiverOptions เมื่อเริ่ม CastReceiverContext เราได้เพิ่มการรองรับคำสั่ง PAUSE และบังคับให้เพลเยอร์รองรับเฉพาะคำสั่งดังกล่าว ตอนนี้หากคำสั่งเสียงขอให้ดำเนินการอื่น เช่น SEEK ระบบจะปฏิเสธ ผู้ใช้จะได้รับการแจ้งเตือนว่าระบบยังไม่รองรับคำสั่งดังกล่าว

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

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

คุณสามารถใช้ตรรกะแยกกันสำหรับแต่ละคำสั่งที่ต้องการจำกัดได้ นำแฟล็ก enforceSupportedCommands ออก และสำหรับแต่ละคำสั่งที่ต้องการจำกัด คุณสามารถสกัดกั้นข้อความขาเข้าได้ ในที่นี้เราจะสกัดกั้นคำขอที่ SDK ระบุไว้เพื่อให้คำสั่ง SEEK ที่ส่งไปยังอุปกรณ์ที่พร้อมใช้งาน Assistant ไม่เรียกใช้การกรอในแอปพลิเคชัน 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 ลดระดับเสียงของแอปพลิเคชันลงเนื่องจากกิจกรรมของ Assistant เช่น การฟังเสียงพูดของผู้ใช้หรือการพูดโต้ตอบ ระบบจะส่งข้อความ FocusState ของ NOT_IN_FOCUS ไปยังแอปพลิเคชัน Web Receiver เมื่อกิจกรรมเริ่มต้นขึ้น ระบบจะส่งข้อความอีกฉบับพร้อม IN_FOCUS เมื่อกิจกรรมสิ้นสุดลง คุณอาจต้องการหยุดสื่อชั่วคราวเมื่อ FocusState เป็น NOT_IN_FOCUS โดยการสกัดกั้นข้อความประเภท FOCUS_STATE ทั้งนี้ขึ้นอยู่กับแอปพลิเคชันและสื่อที่เล่น

ตัวอย่างเช่น การหยุดเล่นหนังสือเสียงชั่วคราวเมื่อ Assistant ตอบคำถามของผู้ใช้จะช่วยมอบประสบการณ์ที่ดีแก่ผู้ใช้

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 ตั้งค่าเป็น true สำหรับคำสั่ง "Ok Google เปิดคำบรรยายแทนเสียง" เนื่องจากระบบอนุมานภาษาจากภาษาที่ใช้พูดคำสั่ง หากมีการขอภาษาอย่างชัดเจน เช่น "Ok Google เปิดคำบรรยายภาษาอังกฤษ" ระบบจะตั้งค่า isSuggestedLanguage เป็น false

ข้อมูลเมตาและการแคสต์เสียง

แม้ว่าตัวรับสัญญาณบนเว็บจะจัดการคำสั่งเสียงโดยค่าเริ่มต้น แต่คุณควรตรวจสอบว่าข้อมูลเมตาของเนื้อหาสมบูรณ์และถูกต้อง ซึ่งจะช่วยให้ Assistant จัดการคำสั่งเสียงได้อย่างถูกต้อง และข้อมูลเมตาจะแสดงอย่างถูกต้องในอินเทอร์เฟซประเภทใหม่ๆ เช่น แอป Google Home และจออัจฉริยะอย่าง Google Home Hub

การถ่ายโอนสตรีม

การคงสถานะเซสชันเป็นพื้นฐานของการถ่ายโอนสตรีม ซึ่งผู้ใช้สามารถย้ายสตรีมเสียงและวิดีโอที่มีอยู่ไปยังอุปกรณ์ต่างๆ โดยใช้คำสั่งเสียง, แอป Google Home หรือจออัจฉริยะ สื่อจะหยุดเล่นในอุปกรณ์เครื่องหนึ่ง (ต้นทาง) และเล่นต่อในอุปกรณ์อีกเครื่องหนึ่ง (ปลายทาง) อุปกรณ์แคสต์ที่มีเฟิร์มแวร์เวอร์ชันล่าสุดสามารถทำหน้าที่เป็นต้นทางหรือปลายทางในการถ่ายโอนสตรีมได้

ขั้นตอนของเหตุการณ์สำหรับการถ่ายโอนสตรีมมีดังนี้

  1. ในอุปกรณ์ต้นทาง ให้ทำดังนี้
    1. สื่อหยุดเล่น
    2. แอปพลิเคชันตัวรับสัญญาณบนเว็บจะได้รับคำสั่งให้บันทึกสถานะสื่อปัจจุบัน
    3. แอปพลิเคชัน Web Receiver ปิดอยู่
  2. ในอุปกรณ์ปลายทาง ให้ทำดังนี้
    1. โหลดแอปพลิเคชัน Web Receiver แล้ว
    2. แอปพลิเคชันตัวรับสัญญาณบนเว็บจะได้รับคำสั่งให้คืนค่าสถานะสื่อที่บันทึกไว้
    3. สื่อจะเล่นต่อ

องค์ประกอบของสถานะสื่อมีดังนี้

  • ตำแหน่งหรือการประทับเวลาที่เฉพาะเจาะจงของเพลง วิดีโอ หรือรายการสื่อ
  • ตำแหน่งของเพลงในคิวที่กว้างขึ้น (เช่น เพลย์ลิสต์หรือวิทยุศิลปิน)
  • ผู้ใช้ที่ผ่านการตรวจสอบสิทธิ์
  • สถานะการเล่น (เช่น กำลังเล่นหรือหยุดชั่วคราว)

กำลังเปิดใช้การถ่ายโอนสตรีม

วิธีใช้การถ่ายโอนสตรีมสำหรับ Web Receiver

  1. อัปเดต supportedMediaCommands ด้วยคำสั่ง STREAM_TRANSFER ดังนี้
    playerManager.addSupportedMediaCommands(
    cast.framework.messages.Command.STREAM_TRANSFER, true);
  2. ลบล้างตัวสกัดกั้นข้อความ SESSION_STATE และ RESUME_SESSION (ไม่บังคับ) ตามที่อธิบายไว้ในการคงสถานะเซสชัน ลบล้างค่าเหล่านี้เฉพาะในกรณีที่จำเป็นต้องจัดเก็บข้อมูลที่กำหนดเองเป็นส่วนหนึ่งของสแนปชอตเซสชัน ไม่เช่นนั้น การติดตั้งใช้งานเริ่มต้นสำหรับการคงสถานะเซสชันจะรองรับการถ่ายโอนสตรีม

การคงสถานะเซสชัน

Web Receiver SDK มีการติดตั้งใช้งานเริ่มต้นสำหรับแอป Web Receiver เพื่อรักษาสถานะเซสชันโดยการถ่ายภาพสถานะสื่อปัจจุบัน แปลงสถานะเป็นคำขอโหลด และกลับมาทำงานต่อในเซสชันด้วยคำขอโหลด

คำขอโหลดที่สร้างโดยตัวรับสัญญาณบนเว็บสามารถลบล้างได้ในตัวสกัดกั้นข้อความ 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;
    });

คุณสามารถดึงข้อมูลที่กำหนดเองได้จาก loadRequestData.customData ในตัวสกัดกั้นข้อความ RESUME_SESSION

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;
    });

การโหลดเนื้อหาล่วงหน้า

ตัวรับสัญญาณบนเว็บรองรับการโหลดรายการสื่อล่วงหน้าหลังจากรายการที่เล่นอยู่ปัจจุบันในคิว

การดำเนินการโหลดล่วงหน้าจะดาวน์โหลดรายการที่กำลังจะเล่นหลายๆ ส่วนไว้ล่วงหน้า ข้อกำหนดจะดำเนินการกับค่า preloadTime ในออบเจ็กต์ QueueItem (ค่าเริ่มต้นคือ 20 วินาทีหากไม่ได้ระบุ) เวลาจะแสดงเป็นวินาที โดยสัมพันธ์กับจุดสิ้นสุดของรายการที่กำลังเล่นอยู่ ค่าที่ถูกต้องคือค่าบวกเท่านั้น เช่น หากค่าเป็น 10 วินาที ระบบจะโหลดรายการนี้ล่วงหน้า 10 วินาทีก่อนที่รายการก่อนหน้าจะเล่นจบ หากเวลาในการโหลดล่วงหน้าสูงกว่าเวลาที่เหลือใน currentItem การโหลดล่วงหน้าจะเกิดขึ้นโดยเร็วที่สุด ดังนั้น หากมีการระบุค่าการโหลดล่วงหน้าที่มีขนาดใหญ่มากใน queueItem คุณจะได้รับผลลัพธ์ที่ว่าเมื่อใดก็ตามที่เราเล่นรายการปัจจุบัน เราจะโหลดรายการถัดไปล่วงหน้าอยู่แล้ว อย่างไรก็ตาม เราปล่อยให้การตั้งค่าและตัวเลือกนี้เป็นของนักพัฒนาแอป เนื่องจากค่านี้อาจส่งผลต่อแบนด์วิดท์และประสิทธิภาพการสตรีมของรายการที่กำลังเล่นอยู่

การโหลดล่วงหน้าจะใช้ได้กับเนื้อหาสตรีมมิง HLS, DASH และ Smooth โดยค่าเริ่มต้น

ระบบจะไม่โหลดไฟล์วิดีโอ MP4 และไฟล์เสียงปกติ เช่น MP3 ไว้ล่วงหน้า เนื่องจากอุปกรณ์แคสต์รองรับองค์ประกอบสื่อเพียงรายการเดียว และไม่สามารถใช้เพื่อโหลดล่วงหน้าขณะที่เนื้อหาที่มีอยู่ยังคงเล่นอยู่

ข้อความที่กำหนดเอง

การแลกเปลี่ยนข้อความเป็นวิธีการโต้ตอบหลักสำหรับแอปพลิเคชันตัวรับสัญญาณบนเว็บ

ผู้ส่งจะส่งข้อความไปยังตัวรับสัญญาณบนเว็บโดยใช้ API ของผู้ส่งสำหรับแพลตฟอร์มที่ผู้ส่งใช้อยู่ (Android, iOS, เว็บ) ออบเจ็กต์เหตุการณ์ (ซึ่งเป็นการแสดงข้อความ) ที่ส่งไปยัง Listener เหตุการณ์มีองค์ประกอบข้อมูล (event.data) โดยที่ข้อมูลจะใช้พร็อพเพอร์ตี้ของประเภทเหตุการณ์ที่เฉพาะเจาะจง

แอปพลิเคชัน Web Receiver อาจเลือกฟังข้อความในเนมสเปซที่ระบุ ด้วยเหตุนี้ แอปพลิเคชันตัวรับสัญญาณบนเว็บจึงรองรับโปรโตคอลเนมสเปซดังกล่าว จากนั้นผู้ส่งที่เชื่อมต่อซึ่งต้องการสื่อสารในเนมสเปซนั้นจะต้องใช้โปรโตคอลที่เหมาะสม

เนมสเปซทั้งหมดกำหนดโดยสตริงและต้องขึ้นต้นด้วย "urn:x-cast:" ตามด้วยสตริงใดก็ได้ เช่น "urn:x-cast:com.example.cast.mynamespace"

ต่อไปนี้เป็นข้อมูลโค้ดสำหรับ Web Receiver เพื่อฟังข้อความที่กำหนดเองจากผู้ส่งที่เชื่อมต่อ

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 สามารถส่งข้อความโดยใช้ sendCustomMessage(namespace, senderId, message) ใน CastReceiverContext Web Receiver สามารถส่งข้อความไปยังผู้ส่งแต่ละราย ไม่ว่าจะเป็นการตอบกลับข้อความที่ได้รับหรือเนื่องจากการเปลี่ยนแปลงสถานะของแอปพลิเคชัน นอกเหนือจากการรับส่งข้อความแบบจุดต่อจุด (จำกัดที่ 64 KB) แล้ว ตัวรับสัญญาณบนเว็บยังสามารถประกาศข้อความไปยังผู้ส่งที่เชื่อมต่อทั้งหมดได้ด้วย

Cast สำหรับอุปกรณ์เสียง

ดูคู่มือ Google Cast สำหรับอุปกรณ์เสียงเพื่อรับการสนับสนุนเกี่ยวกับการเล่นเสียงเท่านั้น

Android TV

ส่วนนี้จะอธิบายวิธีที่ Google Web Receiver ใช้ข้อมูลที่คุณป้อนเป็นการเล่น และความเข้ากันได้กับ Android TV

การผสานรวมแอปพลิเคชันกับรีโมตคอนโทรล

Google Web Receiver ที่ทำงานบนอุปกรณ์ Android TV จะแปลอินพุตจากอินพุตการควบคุมของอุปกรณ์ (เช่น รีโมตคอนโทรลแบบพกพา) เป็นข้อความการเล่นสื่อที่กำหนดไว้สำหรับเนมสเปซ urn:x-cast:com.google.cast.media ตามที่อธิบายไว้ในข้อความการเล่นสื่อ แอปพลิเคชันของคุณต้องรองรับข้อความเหล่านี้เพื่อควบคุมการเล่นสื่อของแอปพลิเคชัน เพื่อให้สามารถควบคุมการเล่นพื้นฐานจากอินพุตการควบคุมของ Android TV ได้

หลักเกณฑ์เกี่ยวกับความเข้ากันได้กับ Android TV

ต่อไปนี้คือคำแนะนำและข้อผิดพลาดที่พบบ่อยซึ่งควรหลีกเลี่ยงเพื่อให้มั่นใจว่าแอปพลิเคชันของคุณเข้ากันได้กับ Android TV

  • โปรดทราบว่าสตริง User Agent มีทั้ง "Android" และ "CrKey" บางเว็บไซต์อาจเปลี่ยนเส้นทางไปยังเว็บไซต์สำหรับอุปกรณ์เคลื่อนที่เท่านั้นเนื่องจากตรวจพบป้ายกำกับ "Android" อย่าคิดว่า "Android" ในสตริง User Agent จะระบุผู้ใช้มือถือเสมอไป
  • สแต็กสื่อของ Android อาจใช้ GZIP แบบโปร่งใสเพื่อดึงข้อมูล ตรวจสอบว่าข้อมูลสื่อของคุณตอบสนองต่อ Accept-Encoding: gzip ได้
  • เหตุการณ์สื่อ HTML5 ของ Android TV อาจทริกเกอร์ในเวลาที่ต่างจาก Chromecast ซึ่งอาจเผยให้เห็นปัญหาที่ซ่อนอยู่ใน Chromecast
  • เมื่ออัปเดตสื่อ ให้ใช้เหตุการณ์ที่เกี่ยวข้องกับสื่อซึ่งเริ่มทำงานโดยองค์ประกอบ <audio>/<video> เช่น timeupdate, pause และ waiting หลีกเลี่ยงการใช้เหตุการณ์ที่เกี่ยวข้องกับเครือข่าย เช่น progress, suspend และ stalled เนื่องจากเหตุการณ์เหล่านี้มักขึ้นอยู่กับแพลตฟอร์ม ดูข้อมูลเพิ่มเติมเกี่ยวกับการจัดการเหตุการณ์สื่อในตัวรับสัญญาณได้ที่เหตุการณ์สื่อ
  • เมื่อกำหนดค่าใบรับรอง HTTPS ของเว็บไซต์ตัวรับสัญญาณ ให้ตรวจสอบว่าได้รวมใบรับรอง CA ระดับกลางไว้ด้วย ดูหน้าทดสอบ Qualsys SSL เพื่อยืนยันว่าหากเส้นทางการรับรองที่เชื่อถือได้สำหรับเว็บไซต์ของคุณมีใบรับรอง CA ที่มีป้ายกำกับว่า "ดาวน์โหลดเพิ่มเติม" ใบรับรองดังกล่าวอาจไม่โหลดในแพลตฟอร์มที่ใช้ Android
  • แม้ว่า Chromecast จะแสดงหน้าตัวรับสัญญาณบนระนาบกราฟิก 720p แต่แพลตฟอร์ม Cast อื่นๆ รวมถึง Android TV อาจแสดงหน้าเว็บได้สูงสุด 1080p ตรวจสอบว่าหน้าตัวรับสัญญาณปรับขนาดได้อย่างเหมาะสมที่ความละเอียดต่างๆ