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

หน้านี้มีข้อมูลโค้ดและคำอธิบายฟีเจอร์ที่ใช้ได้กับแอปตัวรับเว็บที่กำหนดเอง

  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 การกําหนดค่าด้านล่างจะลบล้างระยะหมดเวลานี้ ซึ่งจะมีประโยชน์เมื่อพบปัญหาการแก้ไขข้อบกพร่อง เนื่องจากจะป้องกันไม่ให้แอปตัวรับเว็บปิดเซสชันเครื่องมือแก้ไขข้อบกพร่องระยะไกลของ 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 แฮนเดิลระบุว่าคําขอ CORS Access-Control ควรสร้างขึ้นโดยใช้ข้อมูลเข้าสู่ระบบ เช่น คุกกี้หรือส่วนหัวการให้สิทธิ์

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 เหตุการณ์

Web Receiver SDK ช่วยให้แอป Web Receiver จัดการเหตุการณ์ของโปรแกรมเล่นได้ โปรแกรมรับฟังเหตุการณ์ใช้พารามิเตอร์ cast.framework.events.EventType (หรืออาร์เรย์ของพารามิเตอร์เหล่านี้) ซึ่งระบุเหตุการณ์ที่ควรทริกเกอร์โปรแกรมรับฟัง อาร์เรย์ของ 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 ที่ระบุประเภทข้อความที่ควรสกัดกั้น

Interceptor ควรแสดงผลคำขอที่แก้ไขแล้วหรือ 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 เหตุการณ์เหมาะสําหรับเรียกใช้ข้อมูลวิเคราะห์หรือฟังก์ชันที่กําหนดเอง
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 นี้และป้อนข้อมูลในช่องอีก 2 ช่องที่เหลืออย่างน้อย 1 ช่อง
  • contentUrl สอดคล้องกับ URL ที่เล่นได้ซึ่งโปรแกรมเล่นจะใช้เพื่อโหลดเนื้อหา เช่น URL นี้อาจชี้ไปยังไฟล์ Manifest ของ DASH
  • contentId อาจเป็น URL ของเนื้อหาที่เล่นได้ (คล้ายกับของพร็อพเพอร์ตี้ contentUrl) หรือตัวระบุที่ไม่ซ้ำกันสำหรับเนื้อหาหรือเพลย์ลิสต์ที่โหลด หากใช้พร็อพเพอร์ตี้นี้เป็นตัวระบุ แอปพลิเคชันควรป้อน URL ที่เล่นได้ใน contentUrl

เราขอแนะนำให้ใช้ entity เพื่อจัดเก็บรหัสจริงหรือพารามิเตอร์คีย์ และ ใช้ 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

ตัวอย่างนี้จะตรวจสอบว่าอุปกรณ์ Web Receiver สามารถเล่น 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();

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

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

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

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

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

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

คำสั่งเสียง

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

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

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

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

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

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

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

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

คุณใช้ตรรกะแยกกันสำหรับแต่ละคำสั่งที่ต้องการจํากัดได้ นำ Flag 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 เช่น การฟังเสียงพูดของผู้ใช้หรือการพูดโต้ตอบ ระบบจะส่งข้อความ NOT_IN_FOCUS FocusState ไปยังแอปพลิเคชัน 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

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

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

การโอนสตรีม

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

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

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

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

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

การเปิดใช้การโอนสตรีม

วิธีใช้การโอนสตรีมสำหรับตัวรับเว็บ

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

การเก็บรักษาสถานะเซสชัน

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

คุณลบล้างคำขอโหลดที่ Web Receiver สร้างขึ้นได้ใน SESSION_STATEMessage Interceptor หากจําเป็น หากต้องการเพิ่มข้อมูลที่กำหนดเองลงในคำขอโหลด เราขอแนะนำให้ใส่ข้อมูลดังกล่าวใน 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;
    });

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

Web Receiver รองรับการโหลดรายการสื่อล่วงหน้าหลังจากรายการที่เล่นอยู่ในคิว

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

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

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

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

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

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

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

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

ดูการรองรับการเล่นเสียงเท่านั้นได้ที่คู่มือ 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 ระดับกลาง ดูหน้าทดสอบ SSL ของ Qualsys เพื่อตรวจสอบว่าเส้นทางการรับรองที่เชื่อถือได้ของเว็บไซต์มีใบรับรอง CA ที่มีป้ายกำกับว่า "การดาวน์โหลดเพิ่มเติม" หรือไม่ หากมี เว็บไซต์อาจไม่โหลดในแพลตฟอร์มที่ใช้ Android
  • แม้ว่า Chromecast จะแสดงหน้าผู้รับในระนาบกราฟิก 720p แต่แพลตฟอร์มแคสต์อื่นๆ รวมถึง Android TV อาจแสดงหน้าเว็บได้สูงสุด 1080p ตรวจสอบว่าหน้าผู้รับปรับขนาดได้อย่างราบรื่นที่ความละเอียดต่างๆ