Cómo implementar la API de Co-Doing

En esta página, se describe cómo usar la API de Co-Doing para admitir una situación de colaboración.

Configuración inicial

A fin de preparar la biblioteca para usarla, la aplicación de compartir en vivo debe inicializar un objeto CoDoingClient que represente una sesión de acción conjunta.

Si quieres usar el SDK de Meet para compartir en vivo, llama al método AddonClientFactory.getClient. Se mostrará un objeto AddonClient que sirve como punto de entrada para la sesión de colaboración.

Para usar el cliente, llama al método newSessionBuilder desde AddonClient a fin de mostrar un compilador para una AddonSession nueva. El newSessionBuilder implementa la interfaz de AddonSessionHandler para controlar las devoluciones de llamada que proporciona el complemento para la sesión.

Para iniciar una sesión, agrega el método withCoDoing al compilador.

En la siguiente muestra de código, se muestra una inicialización básica del objeto de cliente en conjunto:

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

Pausar video

Cuando participas en una experiencia de compartir en vivo, si un usuario pausa la reproducción en su app de video local, debes asegurarte de que todos los participantes de la experiencia de compartir en vivo también pausen el video.

Para ello, crea un mensaje CoDoingState que muestre que el video está en pausa y pídele a Google Meet que transmita a todos los demás participantes con el método setGlobalState. El estado global compartido se convierte en el estado predeterminado para todos los participantes, existentes o nuevos, hasta que se establezca un estado nuevo.

En la siguiente muestra de código, se indica cómo notificar a los usuarios sobre el estado de pausa:

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

La muestra de código activa el objeto videoState serializado para que se transmita a todas las demás instancias de Meet que participan en la experiencia de compartir en vivo. Si deseas obtener información para recibir actualizaciones de anuncios de otros participantes, consulta la sección Cómo controlar las actualizaciones entrantes.

En el siguiente diagrama, se describe la secuencia de eventos después de que se activa la acción de pausa:

Diagrama de Comienza a usar la API para compartir en vivo

Reanudar video

Al igual que con pausar video, si un usuario reanuda el video en su app local, Meet debe transmitir esta operación a otros participantes de la función Compartir en vivo.

Del lado del remitente (el usuario que reanuda el video), la única diferencia del ejemplo de pausa es que se actualiza el estado isPaused.

En la siguiente muestra de código, se indica cómo notificar a los usuarios sobre el estado reanudado desde el lado del remitente:

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

Buscar video

Al igual que con las opciones pausar video y reanudar video, si un usuario arrastra la línea de tiempo de la app local a una marca de tiempo nueva, Meet debe transmitir esta operación a todos los participantes.

En la siguiente muestra de código, se indica cómo notificar a los usuarios sobre la marca de tiempo actualizada desde el remitente:

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

Reproducir otro video

Si el usuario también cambia el video que se está mirando cuando selecciona otro video en la app local, Meet debe reproducir el video nuevo para todos los participantes del uso compartido en vivo. El video modificado se almacena en videoState.videoUrl.

En la siguiente muestra de código, se indica cómo notificar a los usuarios sobre la URL del video actualizada:

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

Finalizar la acción colaborativa

Cuando un usuario decide finalizar la actividad, el método endSession se desconecta de la app de Meet. Esto no obliga a Meet a finalizar la reunión ni provoca que el usuario abandone la reunión.

En la siguiente muestra de código, se indica cómo notificar a los usuarios sobre la sesión detenida:

Java

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

Cómo controlar las actualizaciones entrantes

Cuando la app de Meet de otro participante recibe una transmisión, se activa la devolución de llamada onGlobalStateChanged(). Por lo general, es importante tomar buenas decisiones sobre qué acción tomar en respuesta a las actualizaciones entrantes, como solo hacer coincidir las marcas de tiempo de los videos entrantes si son lo suficientemente diferentes de las marcas de tiempo locales.

En la siguiente muestra de código, se indica cómo controlar las diferentes actualizaciones entrantes:

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