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

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

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

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

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

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

ตัวอย่างด้านล่างแสดงวิธีลบล้างลักษณะการทำงานเริ่มต้นในการตรวจสอบว่าการเชื่อมต่อของผู้ส่งยังคงเชื่อมต่ออยู่หรือไม่ เมื่อเว็บรีซีฟเวอร์ไม่สามารถสื่อสารกับผู้ส่งเป็นเวลา 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 และประเมิน ณ เวลาที่สร้างโปรแกรมเล่น ระบบจะสร้างโปรแกรมเล่นทุกครั้ง เมื่อมีการส่งโหลดใหม่ไปยัง SDK ของ Web Receiver ระบบจะประเมินการแก้ไข PlaybackConfig หลังจากสร้างโปรแกรมเล่นวิดีโอในการโหลดเนื้อหาครั้งถัดไป SDK มีวิธีการแก้ไข PlaybackConfig ดังต่อไปนี้

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

ตัวอย่างด้านล่างแสดงวิธีตั้งค่า PlaybackConfig เมื่อเริ่มต้น CastReceiverContext การกำหนดค่าจะลบล้างคำขอขาออกสำหรับการรับไฟล์ Manifest ตัวแฮนเดิลระบุว่าควรสร้างคำขอควบคุมการเข้าถึง 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 เหตุการณ์

Web Receiver SDK ทำให้แอป 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 ที่ระบุประเภทของข้อความที่ควรสกัดกั้น

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

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

ผู้ใช้สามารถโต้ตอบกับแอปพลิเคชัน 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

คำสั่ง คำอธิบาย
เล่น เล่นหรือเล่นต่อจากสถานะหยุดชั่วคราว
หยุดชั่วคราว หยุดเนื้อหาที่เล่นอยู่ชั่วคราว
ก่อนหน้า ข้ามไปยังรายการสื่อก่อนหน้าในคิวสื่อ
ถัดไป ข้ามไปยังรายการสื่อถัดไปในคิวสื่อ
หยุด หยุดสื่อที่เล่นอยู่ในปัจจุบัน
ไม่เล่นซ้ำ ปิดใช้การทำซ้ำรายการสื่อในคิวเมื่อเล่นรายการสุดท้ายในคิวเสร็จแล้ว
เล่นซิงเกิลซ้ำ เล่นสื่อที่เล่นอยู่ซ้ำไปเรื่อยๆ ไม่สิ้นสุด
เล่นซ้ำทั้งหมด เล่นรายการทั้งหมดในคิวซ้ำเมื่อมีการเล่นรายการสุดท้ายในคิว
เล่นซ้ำทั้งหมดและสุ่มเพลง เมื่อเล่นรายการสุดท้ายในคิวเสร็จแล้ว ให้สับเปลี่ยนคิวและทำซ้ำรายการทั้งหมดในคิว
สุ่มเพลง สุ่มรายการสื่อในคิวสื่อ
เปิด / ปิดคำบรรยาย เปิด / ปิดคำบรรยายแทนเสียงสำหรับสื่อ ตัวเลือก "เปิดใช้ / ปิดใช้" มีให้ใช้งานตามภาษาด้วย
กรอไปยังเวลาสัมบูรณ์ ข้ามไปยังเวลาสัมบูรณ์ที่ระบุ
กรอไปยังเวลาที่เกี่ยวข้องกับเวลาปัจจุบัน ข้ามไปข้างหน้าหรือถอยหลังตามระยะเวลาที่ระบุซึ่งสัมพันธ์กับเวลาการเล่นปัจจุบัน
เล่นอีกครั้ง รีสตาร์ทสื่อที่เล่นอยู่ในปัจจุบัน หรือเล่นรายการสื่อที่เล่นล่าสุดหากไม่มีรายการใดเล่นอยู่
กำหนดอัตราการเล่น เปลี่ยนแปลงอัตราการเล่นสื่อ ซึ่งควรได้รับการจัดการโดยค่าเริ่มต้น คุณสามารถใช้เครื่องมือดักจับข้อความ 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 ไม่ทริกเกอร์การค้นหาในแอปพลิเคชันเว็บรีซีฟเวอร์ของคุณ

สำหรับคำสั่งสื่อที่แอปพลิเคชันไม่รองรับ ให้ส่งเหตุผลข้อผิดพลาดที่เหมาะสม เช่น 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. แอปพลิเคชัน Web Receiver ได้รับคำสั่งเพื่อบันทึกสถานะของสื่อปัจจุบัน
    3. แอปพลิเคชัน Web Receiver ถูกปิด
  2. ในอุปกรณ์ปลายทาง ให้ทำดังนี้
    1. โหลดแอปพลิเคชัน Web Receiver แล้ว
    2. แอปพลิเคชัน Web Receiver จะได้รับคำสั่งเพื่อคืนค่าสถานะสื่อที่บันทึกไว้
    3. สื่อเล่นต่อ

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

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

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

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

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

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

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 วินาทีก่อนที่รายการก่อนหน้าจะจบลง หากเวลาในการโหลดล่วงหน้าสูงกว่าเวลาที่เหลืออยู่ในรายการ Currents การโหลดล่วงหน้าจะเกิดขึ้นทันทีที่เป็นไปได้ ดังนั้น หากมีการระบุค่าการโหลดล่วงหน้าที่สูงมากใน identifierItem ค่าหนึ่งอาจมีผลทุกครั้งที่เรากำลังเล่นรายการปัจจุบันอยู่ เราก็โหลดรายการถัดไปไว้ล่วงหน้าแล้ว อย่างไรก็ตาม เราปล่อยการตั้งค่าและตัวเลือกนี้ให้กับนักพัฒนาซอฟต์แวร์เนื่องจากค่านี้อาจส่งผลต่อแบนด์วิดท์และประสิทธิภาพการสตรีมรายการที่เล่นอยู่

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

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

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

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

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

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