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

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

  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. ตัวเลือกในการตั้งค่าบริบทของผู้รับเว็บ
  8. ตัวเลือกสําหรับตั้งค่าคําสั่งที่แอปตัวรับสัญญาณรองรับ
  9. การเรียก JavaScript สําหรับเริ่มต้นแอปพลิเคชันตัวรับเว็บ

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

CastReceiverContext เป็นคลาสชั้นนอกที่เปิดเผยต่อนักพัฒนาซอฟต์แวร์ และจะจัดการการโหลดไลบรารีที่จําเป็นและจัดการการเริ่มต้นของ SDK ตัวรับเว็บ

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

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

อย่างไรก็ตาม สําหรับแอปพลิเคชัน Web Receiver ที่เผยแพร่ การตั้งค่า maxInactivity จะดีกว่าและใช้ค่าเริ่มต้นแทน โปรดทราบว่าตัวเลือก Web Receiver จะกําหนดเพียงครั้งเดียวในแอปพลิเคชัน

การกําหนดค่าอีกแบบคือ cast.framework.PlaybackConfig ตั้งค่าได้ดังนี้

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

การกําหนดค่านี้จะส่งผลต่อการเล่นเนื้อหาแต่ละครั้งและทําหน้าที่ ลบล้างรูปแบบ ดูรายการลักษณะการทํางานที่นักพัฒนาซอฟต์แวร์ลบล้างได้ โปรดดูคําจํากัดความของ cast.framework.PlaybackConfig หากต้องการเปลี่ยนการกําหนดค่าระหว่างเนื้อหา ผู้ใช้สามารถใช้ PlayerManager เพื่อรับ playbackConfig ปัจจุบัน แก้ไขหรือเพิ่มการลบล้าง และรีเซ็ต playbackConfig ดังนี้

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

โปรดทราบว่าหากไม่ได้ลบล้าง PlaybackConfig getPlaybackConfig() จะแสดงผลค่า Null และพร็อพเพอร์ตี้บน PlaybackConfig that จะใช้ undefined โดยค่าเริ่มต้น

Listener เหตุการณ์

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

การสกัดกั้นข้อความ

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

กําลังโหลดสื่อ

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

entity เป็นพร็อพเพอร์ตี้ที่แนะนําสําหรับใช้ในการใช้งานทั้งแอปของผู้ส่งและแอปผู้รับ พร็อพเพอร์ตี้คือ URL ลิงก์ในรายละเอียดซึ่งอาจเป็นเพลย์ลิสต์หรือเนื้อหาสื่อที่เจาะจง

contentUrl ออกแบบมาสําหรับ URL ที่เล่นได้และใช้งานได้เมื่อ URL พร้อมใช้งาน

เราเลิกใช้งาน contentId เนื่องจากความคลุมเครือว่าค่าเป็น URL ของสื่อ รหัสจริง หรือพารามิเตอร์คีย์สําหรับการค้นหาที่กําหนดเอง

เราขอแนะนําให้ใช้ 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 จะให้ข้อมูลอุปกรณ์ในอุปกรณ์ Cast ที่เชื่อมต่ออยู่และอุปกรณ์วิดีโอหรืออุปกรณ์เสียงที่เชื่อมต่ออยู่ เมธอด 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 การควบคุมด้วยการสัมผัสบน Smart Display และการควบคุมระยะไกลในอุปกรณ์ Android TV ได้ Cast SDK มี API ต่างๆ ที่ช่วยให้แอปตัวรับเว็บจัดการการโต้ตอบเหล่านี้ อัปเดต UI แอปพลิเคชันผ่านสถานะการดําเนินการของผู้ใช้ และส่งการเปลี่ยนแปลงเพื่ออัปเดตบริการแบ็กเอนด์ได้

คําสั่งสื่อที่รองรับ

สถานะการควบคุม UI ขับเคลื่อนโดย MediaStatus.supportedMediaCommands สําหรับตัวควบคุมที่ขยายสําหรับผู้ส่งของ iOS และ Android แอปตัวรับสัญญาณและรีโมตคอนโทรลที่ทํางานในอุปกรณ์ระบบสัมผัส และแอปตัวรับสัญญาณในอุปกรณ์ Android TV เมื่อเปิดใช้ Bitwise 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 สําหรับจัดการคําขอประเภทนี้ เพื่อเป็นการรองรับคําขอเหล่านี้ คุณจะต้องดําเนินการต่อไปนี้

  • สกัดกั้นข้อความ USER_ACTION และพิจารณาการทํางานที่ร้องขอ
  • อัปเดต MediaInformation UserActionState เพื่ออัปเดต UI

ข้อมูลโค้ดด้านล่างสกัดกั้นข้อความ USER_ACTION และจัดการการเรียกแบ็กเอนด์ด้วยการเปลี่ยนแปลงที่ขอ จากนั้นจะเรียกใช้งานเพื่ออัปเดต UserActionState บนผู้รับ

playerManager.setMessageInterceptor(cast.framework.messages.MessageType.USER_ACTION,
  (userActionRequestData) => {
    // Obtain the media information of the current content to associate the action to.
    let mediaInfo = playerManager.getMediaInformation();

    // If there is no media info return an error and ignore the request.
    if (!mediaInfo) {
        console.error('Not playing media, user action is not supported');
        return new cast.framework.messages.ErrorData(messages.ErrorType.BAD_REQUEST);
    }

    // Reach out to backend services to store user action modifications. See sample below.
    return sendUserAction(userActionRequestData, mediaInfo)

    // Upon response from the backend, update the client's UserActionState.
    .then(backendResponse => updateUserActionStates(backendResponse))

    // If any errors occurred in the backend return them to the cast receiver.
    .catch((error) => {
      console.error(error);
      return error;
    });
});

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

function sendUserAction(userActionRequestData, mediaInfo) {
  return new Promise((resolve, reject) => {
    switch (userActionRequestData.userAction) {
      // Handle user action changes supported by the backend.
      case cast.framework.messages.UserAction.LIKE:
      case cast.framework.messages.UserAction.DISLIKE:
      case cast.framework.messages.UserAction.FOLLOW:
      case cast.framework.messages.UserAction.UNFOLLOW:
      case cast.framework.messages.UserAction.FLAG:
      case cast.framework.messages.UserAction.SKIP_AD:
        let backendResponse = {userActionRequestData: userActionRequestData, mediaInfo: mediaInfo};
        setTimeout(() => {resolve(backendResponse)}, 1000);
        break;
      // Reject all other user action changes.
      default:
        reject(
          new cast.framework.messages.ErrorData(cast.framework.messages.ErrorType.INVALID_REQUEST));
    }
  });
}

ข้อมูลโค้ดด้านล่างนํา UserActionRequestData และเพิ่มหรือนํา UserActionState ออกจาก MediaInformation การอัปเดต UserActionState ของ MediaInformation จะเปลี่ยนสถานะของปุ่มที่เชื่อมโยงกับการดําเนินการที่ขอ การเปลี่ยนแปลงนี้จะแสดงอยู่ใน UI การควบคุม Smart Display, แอปรีโมตคอนโทรล และ 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 ไปยังแอปพลิเคชันตัวรับสัญญาณเว็บเมื่อกิจกรรมเริ่มขึ้น อีกข้อความหนึ่งจะส่งไปที่ 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 และ Smart Display เช่น Google Home Hub

การโอนสตรีม

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

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

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

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

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

ลบล้างคําขอโหลดที่สร้างโดยตัวรับสัญญาณเว็บได้ในอินเตอร์เซ็กเซอร์ข้อความ SESSION_STATE หากจําเป็น หากต้องการเพิ่มข้อมูลที่กําหนดเองลงในคําขอโหลด เราขอแนะนําให้ใส่ข้อมูลใน loadRequestData.customData

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.SESSION_STATE,
    function (sessionState) {
        // Override sessionState.loadRequestData if needed.
        const newCredentials = updateCredentials_(sessionState.loadRequestData.credentials);
        sessionState.loadRequestData.credentials = newCredentials;

        // Add custom data if needed.
        sessionState.loadRequestData.customData = {
            'membership': 'PREMIUM'
        };

        return sessionState;
    });

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

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

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

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

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

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

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

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

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

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

const CUSTOM_CHANNEL = 'urn:x-cast:com.example.cast.mynamespace';
context.addCustomMessageListener(CUSTOM_CHANNEL, function(customEvent) {
  // handle customEvent.
});

context.start();

ในทํานองเดียวกัน แอปพลิเคชัน Web Receiver จะสามารถทําให้ผู้ส่งทราบเกี่ยวกับสถานะของตัวรับเว็บ โดยส่งข้อความไปยังผู้ส่งที่เชื่อมต่อ แอปพลิเคชัน Web Receiver สามารถส่งข้อความโดยใช้ sendCustomMessage(namespace, senderId, message) บน CastReceiverContext ผู้รับเว็บสามารถส่งข้อความไปยังผู้ส่งแต่ละรายได้ ไม่ว่าจะเป็นการตอบกลับข้อความที่ได้รับ หรือจากการเปลี่ยนสถานะแอปพลิเคชัน นอกเหนือจากการรับส่งข้อความแบบจุดต่อจุด (ด้วยขีดจํากัด 64kb) ตัวรับเว็บอาจเผยแพร่ข้อความไปยังผู้ส่งที่เชื่อมต่อทั้งหมด

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

ดูคําแนะนําสําหรับอุปกรณ์ Google Cast for audio สําหรับการสนับสนุนเกี่ยวกับการเล่นเสียงเท่านั้น

Android TV

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