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 este tipo.

Configuración inicial

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

Para usar el SDK de Compartir en vivo de Meet, llama al método AddonClientFactory.getClient. Esto muestra un AddonClient que funciona como punto de entrada para la sesión de cooperación.

Si deseas usar el cliente, llama al método newSessionBuilder desde AddonClient para mostrar un compilador para un AddonSession nuevo. 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 observa una inicialización básica del objeto de cliente de cohacer:

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 un usuario participa 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 esa experiencia también pausen su video.

Para ello, crea un mensaje CoDoingState que muestre que el video está en pausa y pídele a Google Meet que lo 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 establece 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. Para obtener detalles sobre cómo recibir actualizaciones de transmisión de otros participantes, consulta la sección Cómo administrar 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 la API de comenzar a compartir en vivo

Reanudar video

De manera similar a la pausa de video, si un usuario reanuda el video en su app local, Meet debe transmitir esta operación a otros participantes del uso compartido en vivo.

En el lado del remitente (el usuario que reanuda el video), la única diferencia con el ejemplo de pausa es que se actualiza el estado de 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 los pasos para pausar video y reactivar video, si un usuario arrastra el cronograma en 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 selecciona otro video en la app local para cambiar el video que se está mirando, Meet debe reproducir el video nuevo para todos los participantes de la función Compartir 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 colaboración

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

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 hacer coincidir solo las marcas de tiempo de video entrantes si son lo suficientemente diferentes de la marca de tiempo local.

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