實作 Co-Doing API

本頁說明如何使用 Co-Doing API 協助共同工作 情境。

初始設定

為了準備程式庫使用,即時分享應用程式應將 CoDoingClient敬上 物件。

如要使用 Meet 即時分享 SDK,請呼叫 AddonClientFactory.getClient敬上 方法。這會傳回 AddonClient敬上 做為共同合作工作階段的進入點

如要使用用戶端,請呼叫 newSessionBuilder敬上 從 AddonClient 的 方法,為新的 AddonSessionnewSessionBuilder 會導入 AddonSessionHandler 介面,處理 外掛程式

如要開始練習,請在 withCoDoing敬上 方法新增至建構工具。

下列程式碼範例顯示共同執行用戶端的基本初始化 物件:

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

暫停影片

進行即時分享時,當使用者暫停播放時 在他們的本機視訊應用程式中,你必須確認所有參與者 分享體驗也會暫停播放影片。

方法很簡單 CoDoingState敬上 訊息顯示視訊已暫停,並要求 Google Meet 將其廣播 系統中的其他參與者 setGlobalState 方法。共用的全域狀態會成為所有參與者的預設狀態。 直到設定新狀態為止

以下程式碼範例說明如何通知使用者暫停狀態:

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

這個程式碼範例會觸發要播送的序列化 videoState 物件 參與即時分享功能的所有其他 Meet 執行個體 無須專人管理進一步瞭解如何接收其他來源的廣播更新 請參閱這篇文章,瞭解如何處理傳入的更新 專區。

下圖說明暫停動作之後的事件順序 已觸發:

啟動 Live Share API 圖表。

取消暫停影片

暫停影片功能類似,如果使用者將自己的影片取消暫停, 接著,Meet 就必須將這項作業播送至其他線上應用程式 正在分享參與者。

在傳送端 (取消暫停影片的使用者) 中,唯一的差別是 暫停範例為 isPaused 狀態已更新。

以下程式碼範例說明如何通知使用者解除暫停狀態的時間: 傳送者的端:

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

跳轉影片

就像暫停影片取消暫停影片一樣, 當使用者將本機應用程式中的時間軸拖曳至新的時間戳記時, Meet 必須向所有參與者廣播這項作業。

下列程式碼範例說明如何通知使用者更新後的時間戳記 :

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

播放其他影片

如果使用者同時選取其他影片來變更正在觀看的影片 本機應用程式,Meet 必須播放新影片,才能使用即時分享功能 位參與者。變更的影片會儲存在「videoState.videoUrl」中。

以下程式碼範例說明如何將更新後的影片網址告知使用者:

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

結束共同活動

當使用者選擇結束活動時, endSession敬上 方法就會與 Meet 應用程式中斷連線。這並不強制 Meet 結束會議,也不會讓使用者離開 建立會議

下列程式碼範例說明如何通知使用者已停止的工作階段:

Java

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

處理傳入的更新

當其他參與者的 Meet 應用程式收到廣播時, onGlobalStateChanged()敬上 回呼函式。一般而言,制定明智的決策時 回應傳入更新時應採取的行動,例如僅比對收到的更新 影片時間戳記 (若與本機時間戳記有足夠差異)。

下列程式碼範例說明如何處理不同的傳入更新:

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