Co-Doing API を実装する

このページでは、Co-Doing API を使用して共同行動のシナリオをサポートする方法について説明します。

初期設定

ライブラリを使用できるように準備するには、ライブ共有アプリケーションで、共同セッションを表す CoDoingClient オブジェクトを初期化する必要があります。

Meet ライブ共有 SDK を使用するには、AddonClientFactory.getClient メソッドを呼び出します。これにより、共同セッションのエントリ ポイントとして機能する AddonClient が返されます。

クライアントを使用するには、AddonClient から newSessionBuilder メソッドを呼び出して、新しい AddonSession のビルダーを返します。newSessionBuilder は、セッションのアドオンから提供されるコールバックを処理する 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 メッセージを作成し、setGlobalState メソッドを使用して他のすべての参加者にブロードキャストするよう Google Meet に指示します。共有されたグローバル状態は、新しい状態が設定されるまで、既存または新規のすべての参加者のデフォルト状態になります。

次のコードサンプルは、一時停止状態をユーザーに通知する方法を示しています。

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 Sharing 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 に保存されます。

次のコードサンプルは、更新された動画の URL をユーザーに通知する方法を示しています。

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