นำ Co-Watching API ไปใช้

หน้านี้จะอธิบายวิธีใช้ API การดูร่วมกันเพื่อรองรับสถานการณ์การดูร่วมกัน

การตั้งค่าเบื้องต้น

แอปพลิเคชันการแชร์สดควรเริ่มต้นออบเจ็กต์ CoWatchingClient ซึ่งแสดงถึงเซสชันการดูร่วมกันเพื่อเตรียมไลบรารีให้พร้อมสำหรับการใช้งาน

หากต้องการใช้ SDK การแชร์สดของ Meet ให้เรียกใช้เมธอด AddonClientFactory.getClient ซึ่งจะแสดง AddonClient ที่ทำหน้าที่เป็นจุดแรกเข้าสำหรับเซสชันการดูร่วมกัน

หากต้องการใช้ไคลเอ็นต์ ให้เรียกใช้เมธอด newSessionBuilder จาก AddonClient เพื่อแสดงเครื่องมือสร้างสำหรับ AddonSession ใหม่ newSessionBuilder จะใช้อินเทอร์เฟซ AddonSessionHandler เพื่อจัดการ Callback ที่ส่วนเสริมมีให้สำหรับเซสชัน

หากต้องการเริ่มเซสชัน ให้เพิ่มเมธอด withCoWatching ลงในเครื่องมือสร้าง

ตัวอย่างโค้ดต่อไปนี้แสดงการเริ่มต้นพื้นฐานของออบเจ็กต์ไคลเอ็นต์ที่ดูร่วมกัน

Java

class AwesomeVideoAddonSessionHandler implements AddonSessionHandler {}

// For sample implementation, see the "Manage remote state" section below.
class AwesomeVideoCoWatchingHandler implements CoWatchingHandler {}

public ListenableFuture<AddonSession> initialSetup() {
  AddonClient meetClient = AddonClientFactory.getClient();
  return meetClient
      .newSessionBuilder(
          new AwesomeVideoAddonSessionHandler())
      .withCoWatching(new AwesomeVideoCoWatchingHandler())
      .begin();
}

แจ้งเตือนการดำเนินการของผู้ใช้

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

คุณควบคุมสถานะการดูร่วมกันได้โดยใช้วิธีการเหล่านี้

  • CoWatchingClient.notifyBuffering: แจ้ง Meet ว่าสื่อไม่พร้อมเล่นเนื่องจากการบัฟเฟอร์ อันเนื่องมาจากสวิตช์สื่อก่อนหน้า การกรอสื่อ หรือความหนาแน่นของเครือข่ายตามปกติ
  • CoWatchingClient.notifyEnded: แจ้ง Meet ว่ามีเดียเพลเยอร์เล่นสื่อปัจจุบันจนสุดแล้ว
  • CoWatchingClient.notifyPauseState แจ้งให้ Meet ทราบว่าผู้ใช้หยุดเล่นสื่อชั่วคราวหรือยกเลิกการหยุดเล่นสื่อชั่วคราว เพื่อให้ Meet มิเรอร์การดำเนินการดังกล่าวให้ผู้ใช้คนอื่นๆ ได้
  • CoWatchingClient.notifyPlayoutRate: แจ้ง Meet ว่าผู้ใช้อัปเดตอัตราการเล่นของสื่อเป็นค่าใหม่ (เช่น 1.25x)
  • CoWatchingClient.notifyQueueUpdate: แจ้งให้ Meet ทราบว่าคิวมีการเปลี่ยนแปลง เพื่อให้ Meet มิเรอร์การดำเนินการดังกล่าวให้ผู้ใช้คนอื่นๆ ได้
  • CoWatchingClient.notifyReady: แจ้งให้ Meet ทราบว่าการบัฟเฟอร์เสร็จสมบูรณ์แล้ว และสื่อก็พร้อมให้เล่นแล้ว โดยเริ่มตั้งแต่การประทับเวลาที่ระบุ
  • CoWatchingClient.notifySeekToTimestamp: แจ้งเตือน Meet ว่าผู้ใช้ได้กรอไปยังจุดเล่นของสื่อแล้วเพื่อให้ Meet มิเรอร์การดำเนินการดังกล่าวให้ผู้ใช้คนอื่นๆ ได้
  • CoWatchingClient.notifySwitchedToMedia: แจ้ง Meet ว่าผู้ใช้เปลี่ยนสื่อ เพื่อให้ Meet ส่งต่อข้อมูลนี้ให้ผู้ใช้รายอื่นได้ นอกจากนี้ยังมีตัวเลือก สำหรับการอัปเดตคิวพร้อมกัน

ตัวอย่างโค้ดต่อไปนี้แสดงวิธีแจ้งให้ผู้ใช้ทราบ

Java

public void onVideoPaused(Duration currentTimestamp) {
  // Use Meet to broadcast the pause state to ensure other participants also pause.
  this.session.getCoWatching().notifyPauseState(/* paused= */ true, currentTimestamp);
};

จัดการสถานะระยะไกล

หากต้องการใช้การอัปเดตขาเข้าจากผู้เข้าร่วมระยะไกล คุณต้องเสนอวิธีจัดการสถานะการเล่นสื่อในเครื่องโดยตรงโดยใช้ Callback CoWatchingHandler.onCoWatchingStateChanged() ของ Meet

Meet ยังต้องดึงข้อมูลตำแหน่งปัจจุบันของการเล่นสื่อด้วยการเรียกใช้ Callback CoWatchingHandler.onStateQuery() โดยระบบจะเรียกสิ่งนี้เป็นประจำ ดังนั้นควรเขียนให้มีประสิทธิภาพ (เช่น <100 มิลลิวินาที)

ตัวอย่างโค้ดต่อไปนี้แสดงการใช้งาน CoWatchingHandler

Java

class AwesomeVideoCoWatchingHandler implements CoWatchingHandler {
  /** Applies incoming playback state to the local video. */
  public void onCoWatchingStateChanged(CoWatchingState newState) {
    // Handle transition to new video.
    if (!newState.mediaId().equals(this.videoPlayer.videoUrl)) {
      this.videoPlayer.loadVideo(newState.mediaId());
    }

    // Only adjust the local video playout if it's sufficiently diverged from the timestamp in the
    // applied update.
    if (newState
            .mediaPlayoutPosition()
            .minus(this.videoPlayer.videoTimestamp)
            .compareTo(Duration.ofMillis(500))
        > 0) {
      this.videoPlayer.seek(newState.mediaPlayoutPosition());
    }

    // Update pause state, if necessary.
    if (newState.playbackState().equals(PLAY) && this.videoPlayer.isPaused) {
      this.videoPlayer.unpause();
    } else if (newState.playbackState().equals(PAUSE) && !this.videoPlayer.isPaused) {
      this.videoPlayer.pause();
    }
  }

  /** Returns local video playback state. */
  public Optional<QueriedCoWatchingState> onStateQuery() {
    return Optional.of(QueriedCoWatchingState.of(
      /* mediaPlayoutPosition= */ this.videoPlayer.videoTimestamp));
  }
}