Triển khai API Co-Doing

Trang này mô tả cách sử dụng API cùng làm để hỗ trợ trường hợp cùng làm.

Thiết lập ban đầu

Để chuẩn bị thư viện cho việc sử dụng, ứng dụng chia sẻ trực tiếp phải khởi chạy đối tượng CoDoingClient đại diện cho một phiên cùng làm.

Để sử dụng SDK Chia sẻ trực tiếp của Meet, hãy gọi phương thức AddonClientFactory.getClient. Thao tác này sẽ trả về một AddonClient đóng vai trò là điểm truy cập cho phiên cùng làm.

Để sử dụng ứng dụng, hãy gọi phương thức newSessionBuilder từ AddonClient để trả về trình tạo cho AddonSession mới. newSessionBuilder triển khai giao diện AddonSessionHandler để xử lý các lệnh gọi lại do tiện ích bổ sung cung cấp cho phiên.

Để bắt đầu một phiên, hãy thêm phương thức withCoDoing vào trình tạo.

Mã mẫu sau đây cho thấy cách khởi chạy cơ bản của đối tượng ứng dụng cùng làm:

Java

class AwesomeVideoAddonSessionHandler implements AddonSessionHandler {}

//For sample implementation, see the "Handle incoming updates" section.
class AwesomeVideoCoDoingHandler implements CoDoingHandler {}

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

Tạm dừng video

Khi tham gia trải nghiệm chia sẻ trực tiếp, nếu người dùng tạm dừng phát trên ứng dụng video cục bộ, thì bạn phải đảm bảo rằng tất cả người tham gia chia sẻ trực tiếp cũng tạm dừng video của họ.

Để làm việc này, hãy tạo một thông báo CoDoingState cho biết video đã bị tạm dừng và yêu cầu Google Meet phát đi thông báo đó cho tất cả những người tham gia khác bằng phương thức setGlobalState. Trạng thái chung được chia sẻ trở thành trạng thái mặc định cho tất cả người tham gia, hiện tại hoặc mới, cho đến khi trạng thái mới được đặt.

Mã mẫu sau đây trình bày cách thông báo cho người dùng về trạng thái tạm dừng:

Java

public void onVideoPaused(String videoUrl, Instant currentTimestamp) {
  // Create an internal state object to share with other participants. Note: It's
  // good practice to encode all metadata—even seemingly irrelevant data—into
  // ActivityState updates to guard against race conditions and other subtle
  // failures.
  AwesomeVideoState videoState = AwesomeVideoState
    .builder()
    .videoUrl(videoUrl)
    .videoTimestamp(currentTimestamp)
    .isPaused(true)
    .build();

  // Create the CoDoingState object to wrap the internal state
  CoDoingState coDoingState = new CoDoingState();
  coDoingState.state = SerializationUtils.serialize(videoState);

  // Use Meet to broadcast internal state update to all other participants
  this.coDoingClient.setGlobalState(coDoingState);
};

Mã mẫu kích hoạt việc truyền tin đối tượng videoState tuần tự đến tất cả thực thể khác của Meet tham gia vào trải nghiệm chia sẻ trực tiếp. Để biết thông tin chi tiết về cách nhận thông tin cập nhật truyền tin từ những người tham gia khác, hãy xem phần Xử lý bản cập nhật đến.

Sơ đồ dưới đây mô tả trình tự các sự kiện sau khi hành động tạm dừng được kích hoạt:

Sơ đồ về Bắt đầu API Chia sẻ trực tiếp.

Tiếp tục phát video

Tương tự như việc tạm dừng video, nếu người dùng tiếp tục xem video trên ứng dụng cục bộ, thì Meet phải phát sóng thao tác này cho những người tham gia khác để chia sẻ trực tiếp.

Ở phía người gửi (người dùng tiếp tục video), điểm khác biệt duy nhất so với ví dụ tạm dừng là trạng thái isPaused được cập nhật.

Mã mẫu sau đây cho biết cách thông báo cho người dùng về trạng thái huỷ tạm dừng từ phía người gửi:

Java

public void onVideoUnpaused(String videoUrl, Instant currentTimestamp) {
  AwesomeVideoState videoState = AwesomeVideoState
    .builder()
    .videoUrl(videoUrl)
    .videoTimestamp(currentTimestamp)
    .isPaused(false)
    .build();

  CoDoingState coDoingState = new CoDoingState();
  coDoingState.state = SerializationUtils.serialize(videoState);

  this.coDoingClient.setGlobalState(coDoingState);
}

Tua video

Giống như tính năng tạm dừng videohuỷ tạm dừng video, nếu người dùng kéo dòng thời gian trên ứng dụng cục bộ đến một dấu thời gian mới, thì Meet phải phát đi thao tác này cho tất cả người tham gia.

Mã mẫu sau đây cho biết cách thông báo cho người dùng về dấu thời gian đã cập nhật từ phía người gửi:

Java

public void onVideoSeeked(String videoUrl, Instant currentTimestamp, bool isPaused) {
  AwesomeVideoState videoState = AwesomeVideoState
    .builder()
    .videoUrl(videoUrl)
    .videoTimestamp(currentTimestamp)
    .isPaused(isPaused)
    .build();

  CoDoingState coDoingState = new CoDoingState();
  coDoingState.state = SerializationUtils.serialize(videoState);

  this.coDoingClient.setGlobalState(coDoingState);
}

Phát một video khác

Nếu người dùng cũng thay đổi video đang xem bằng cách chọn một video khác trên ứng dụng cục bộ, thì Meet phải phát video mới cho tất cả những người tham gia chia sẻ trực tiếp. Video đã thay đổi được lưu trữ trong videoState.videoUrl.

Mã mẫu sau đây trình bày cách thông báo cho người dùng về URL của video đã cập nhật:

Java

public void onVideoChanged(String videoUrl, Duration currentTimestamp, bool isPaused) {
  AwesomeVideoState videoState = AwesomeVideoState
    .builder()
    .videoUrl(videoUrl)
    .videoTimestamp(currentTimestamp)
    .isPaused(isPaused)
    .build();

  CoDoingState coDoingState = new CoDoingState();
  coDoingState.state = SerializationUtils.serialize(videoState);

  this.coDoingClient.setGlobalState(coDoingState);
}

Kết thúc quy trình cùng làm

Khi người dùng chọn kết thúc hoạt động, phương thức endSession sẽ ngắt kết nối khỏi ứng dụng Meet. Thao tác này không buộc Meet kết thúc cuộc họp và cũng không khiến người dùng rời khỏi cuộc họp.

Mã mẫu sau đây trình bày cách thông báo cho người dùng về phiên bị dừng:

Java

public void endCoDoing() {
  this.session.endSession();
}

Xử lý bản cập nhật đến

Khi ứng dụng Meet của một người tham gia khác nhận được thông báo truyền tin, lệnh gọi lại onGlobalStateChanged() sẽ được kích hoạt. Thông thường, bạn cần phải đưa ra quyết định sáng suốt về hành động cần thực hiện để phản hồi các bản cập nhật sắp tới, chẳng hạn như chỉ khớp với dấu thời gian của video đến nếu chúng đủ khác biệt với dấu thời gian cục bộ.

Mã mẫu sau đây cho biết cách xử lý các bản cập nhật sắp tới:

Java

class AwesomeVideoCoDoingHandler implements CoDoingHandler {
  public void onGlobalStateChanged(CoDoingState update) {
    AwesomeVideoState videoState = SerializationUtils.deserialize(update.state());

    // Handle transition to new video.
    if (!videoState.videoUrl.equals(this.videoPlayer.videoUrl)) {
      this.videoPlayer.loadVideo(videoState.videoUrl);
    }

    // If the timestamp in the arriving update has sufficiently diverged, adjust
    // the local video playout.
    if (videoState.videoTimestamp.minus(this.videoPlayer.videoTimestamp).abs() >
                                        Duration.ofSeconds(2)) {
      this.videoPlayer.seek(videoState.videoTimestamp);
    }

    // Update pause state, if necessary.
    if (!videoState.isPaused && this.videoPlayer.isPaused) {
      this.videoPlayer.unpause();
    } else if (videoState.isPaused && !this.videoPlayer.isPaused) {
      this.videoPlayer.pause();
    }
  }
}