Cómo mejorar la participación en Ver a continuación para películas o episodios de TV en Android TV

1. Introducción

Ver siguiente

El canal Ver a continuación es la fila que aparece en la pantalla principal de Android TV con videos que los usuarios pueden ver a continuación. Según la versión del sistema, la fila Ver a continuación podría llamarse "Mi lista" o "Continuar viendo".

b0ca4ea7c72ba8f6.png

El sistema crea y mantiene este canal. Cada elemento de este canal se llama programa. Tu app puede agregar, actualizar o quitar programas en el canal Ver a continuación, como contenido que el usuario dejó de ver por la mitad o contenido con el que el usuario interactuó (por ejemplo, el siguiente episodio de una serie o la siguiente temporada de un programa).

Conceptos

El canal Ver a continuación permite que tu app vuelva a generar participación del usuario.

Puedes agregar, actualizar o quitar contenido en el canal Ver a continuación, con el que el usuario ya interactuó. Por ejemplo, mostrar un video sin terminar o sugerir el siguiente episodio o la siguiente serie, etc.

Las apps también pueden quitar el episodio una vez que se terminó de ver y agregar el siguiente episodio de la temporada nueva de la serie.

Existen cuatro tipos de casos de uso para el canal Ver a continuación:

  • Continuar mirando un video que el usuario no terminó
  • Sugerir el siguiente video para mirar (por ejemplo, si el usuario terminó de mirar el episodio 1, puedes sugerir el episodio 2)
  • Mostrar episodios nuevos de una serie que el usuario estuvo mirando.
  • Mantener una lista para ver de videos interesantes que el usuario haya agregado

En este codelab, se muestra cómo incluir un video en el canal Ver a continuación cuando el usuario lo pausa. También, se explica cómo eliminar un video de Ver a continuación cuando se reproduce hasta el final y cómo agregar el siguiente episodio cuando esté disponible.

En este codelab, no se tratan los casos de uso de Ver a continuación para episodios nuevos publicados ni la lista para ver.

Ver a continuación para episodios de TV y películas

El canal Ver a continuación es una función muy importante en la pantalla principal de Android TV, ya que permite que los usuarios se pongan al día con películas y programas de TV sin terminar. En particular, es muy importante para los usuarios que miran episodios de TV, ya que una serie de TV suele tener muchos episodios y, muchas veces, el usuario continuará viendo desde donde dejó.

Imagina el momento en que el usuario regresa y se sienta frente a la TV mientras decide qué mirar. Con Ver a continuación, la app le permite reanudar los episodios de TV desde donde dejó directamente en la pantalla principal. De esta manera, se aumenta la participación de los usuarios, lo que beneficia tanto a tu app como al usuario.

En este codelab, te guiaremos por la app de referencia de TV, te mostraremos cómo tratar casos diferentes en el canal Ver a continuación y te explicaremos los lineamientos de calidad de Google en la función Ver a continuación. Este codelab se enfoca en cómo controlar, de manera específica, los episodios de TV, pero puedes aplicar reglas similares para las películas.

Disponibilidad

El código de este codelab funciona en dispositivos Android TV, incluidos los que ejecutan la experiencia de Google TV.

Qué compilarás

En este codelab, deberás agregar, quitar y actualizar un canal Ver a continuación para películas o episodios de TV. Tu app hará lo siguiente:

  • Implementará casos diferentes de uso para controlar películas
  • Implementará casos diferentes de uso para controlar episodios de TV

Qué aprenderás

  • Los lineamientos de calidad de Google para Ver a continuación

Requisitos

  • Conocimientos básicos sobre el desarrollo de aplicaciones para Android
  • Android Studio 4.1 o una versión posterior (puedes descargarlo aquí)

2. Cómo prepararte

Cómo clonar el proyecto inicial

Puedes descargar el código fuente del repositorio de GitHub:

git clone https://github.com/android/codelab-watchnext-for-movie-tv-episodes.git

También, puedes descargarlo directamente desde el siguiente vínculo.

Descargar código fuente

Abre Android Studio y haz clic en File > Open en la barra de menú, o bien ve a Open an Existing Android Studio Project en la pantalla de bienvenida y selecciona la carpeta clonada recientemente.

8271a7b581390845.png

Información sobre el proyecto inicial

34641bc2c9f71f0f.png

El proyecto consta de cuatro pasos. En cada paso, deberás agregar el código según las instrucciones de la sección pertinente. Cuando completes una sección, podrás comparar tu código con el código que se encuentra en step_x_completed.

Por cuestiones de simplicidad, agregamos código básico para crear una lista de videos y un exoplayer a fin de ver contenido dentro de la app. De esta manera, se creará una estructura básica de una app para TV, que está fuera del alcance de este codelab.

Nuestro objetivo es aprender a agregar, quitar o actualizar los videos sin terminar y terminados en el canal Ver a continuación y volver a generar participación para nuestra app.

Estos son los componentes principales de la app:

  • FileVideoRepository es la clase para cargar y consultar metadatos de videos.
  • PlaybackFragment es el fragmento de reproducción de video.
  • WatchNextPlaybackStateListener es un objeto de escucha de cambio de estado de reproducción; escucha los eventos de reproducción y activa las operaciones relacionadas.
  • WatchNextWorker es un trabajador responsable de actualizar el canal Ver a continuación.
  • WatchNextHelper es una clase auxiliar que simplifica el trabajo con el canal Ver a continuación.

En este codelab, se usan datos multimedia en res/raw/api.json para propagar las entradas de Ver a continuación.

Cómo ejecutar el proyecto inicial

Ejecuta step_1. Si tienes problemas, consulta la documentación sobre cómo comenzar.

  1. Conecta tu Android TV o inicia el emulador.
  1. Selecciona la configuración de step_1, luego tu dispositivo Android y presiona el botón run en la barra de menú. 249ea91a556fbd61.png
  2. Deberías ver un esquema simple de la app para TVs con cuatro colecciones de videos similares a la siguiente captura de pantalla.
  3. Navega por la pantalla principal de la app y familiarízate con la app de referencia de TV. Existen cuatro categorías de videos:
  4. Clips optimizados
  5. Varios clips
  6. Beverly Hillbillies: algunos episodios de TV de dos temporadas diferentes.
  7. Películas de Charlie Chaplin.
  8. Haz clic en uno de los episodios de TV de la categoría Beverly Hillbillies y míralo. En este codelab, aprenderás a agregar programas a Ver a continuación para estos episodios de TV

d7b51de54f4a1199.png

Qué aprendiste

En esta introducción, aprendiste lo siguiente:

  • Estructura de código y clases principales que se usan en este codelab.
  • Cómo configurar y ejecutar la app de ejemplo

¿Qué sigue?

Lineamientos de calidad de Ver a continuación

3. Cómo comprender los lineamientos de calidad de Ver a continuación

Para brindar una mejor experiencia en la pantalla principal, todas las apps que agregan contenido a Ver a continuación deben comportarse de manera coherente.

En particular, existen situaciones que los desarrolladores deben ocuparse para los episodios de TV. Google resume una lista de lineamientos de calidad para Ver a continuación que debe seguirse a fin de garantizar la calidad del canal Ver a continuación.

Cómo compilar la función de Ver a continuación para cumplir con los estándares de calidad de Google

Cuando Google evalúa la función Ver a continuación, se verifican los siguientes puntos

  1. El programa se agrega a Ver a continuación cuando se pausa o se detiene
  2. La app puede reanudar la reproducción desde la entrada de Ver a continuación
  3. La app actualiza, de manera oportuna, la posición de reproducción en Ver a continuación
  4. El programa se quita de Ver a continuación cuando se completa la reproducción
  5. El siguiente episodio se agrega cuando finaliza el episodio actual
  6. La app no agrega a Ver a continuación contenido con el que el usuario no haya interactuado
  7. Todo el contenido sin terminar se envía a Ver a continuación
  8. La app configura los metadatos correctos y completos, como los números de temporada o episodio
  9. La app no agrega varios episodios para la misma serie de TV

A continuación, te explicamos cada requisito de calidad

  1. El programa se agrega a Ver a continuación cuando se pausa o se detiene.
  • Las apps deben agregar películas y programas de TV tradicionales a la fila Ver a continuación cuando no se completó la reproducción
  1. La app puede reanudar la reproducción desde la entrada de Ver a continuación.
  • Se reanuda la reproducción del contenido que se agregó al canal Ver a continuación desde la última posición de reproducción; el video debe comenzar a reproducirse inmediatamente después de que se cargue el contenido
  1. La app actualiza, de manera oportuna, la posición de reproducción en Ver a continuación.
  • La app debe realizar un seguimiento del progreso de reproducción y actualizar el programa de Ver a continuación en la última posición de reproducción después de que el usuario deja de ver el video.
  1. El programa se quita de Ver a continuación cuando se completa la reproducción.
  • Una app debe funcionar de manera adecuada y realizar una limpieza después. La fila Ver a continuación es una fila compartida para todas las apps, y deseamos asegurarnos de que el contenido en la fila sea preciso a fin de mantener la confianza del usuario
  1. El siguiente episodio se agrega cuando finaliza el episodio actual.
  • Cuando los usuarios miran una serie de TV, la app debería facilitarles seguir viendo. Para ello, esta agrega el siguiente episodio de la serie a fila Ver a continuación
  1. La app no agrega a Ver a continuación contenido con el que el usuario no haya interactuado.
  • Según los lineamientos de Ver a continuación, la app solo debe agregar una película o un episodio de TV al canal Ver a continuación si el usuario "comenzó" a mirar
  • No te recomendamos que agregues avances ni clips de video de poca duración al canal Ver a continuación, ya que, de esta manera, se genera muy poca participación
  1. Todo el contenido sin terminar se envía a Ver a continuación.
  • Los proveedores no deben limitar, de manera artificial, la cantidad de tarjetas que envían a Ver a continuación. Si el usuario tiene contenido sin terminar, debería enviarse a la fila Ver a continuación
  1. La app configura los metadatos correctos y completos.
  • Asegúrate de que los metadatos asociados con el episodio sean correctos
  • El número de episodio, el número de temporada y el título deben ser precisos
  • La barra de progreso debe ser proporcional a la cantidad que se miró
  • La imagen del episodio o la serie debe aparecer en el mosaico
  1. La app no debe agregar varios episodios de la misma serie de TV.
  • La app debe mantener, como máximo, una entrada de Ver a continuación para cada serie de TV; si el usuario mira la mitad de dos episodios diferentes, en Ver a continuación, solo se debe mostrar el último episodio que miró.

Estos requisitos de calidad permitirán que tu app ofrezca una experiencia excelente del usuario en Ver a continuación.

Comencemos y compilemos las funciones de Ver a continuación teniendo en cuenta estas guías de calidad.

Qué aprendiste

En esta sección, aprendiste sobre lo siguiente:

  • Requisitos de calidad de Ver a continuación

¿Qué sigue?

Agrega un episodio sin terminar al canal Ver a continuación

4. Cómo agregar contenido sin terminar a Ver a continuación

Comenzaremos con la funcionalidad básica: agregar un episodio sin terminar a Ver a continuación.

En el codelab, te guiaremos para crear un elemento WatchNextProgram, completar los metadatos correctos para el episodio, como el número de episodio, el número de temporada y el tipo de video, etc. La entrada de Ver a continuación se puede actualizar a fin de asegurarse de que tenga la información más reciente sobre la posición de reproducción del usuario, de modo que pueda reanudar la reproducción con un clic en el programa.

En esta sección, se tratará lo siguiente:

  • El programa se agrega a Ver a continuación cuando se pausa o se detiene.
  • La app puede reanudar la reproducción desde la entrada de Ver a continuación.
  • La app actualiza, de manera oportuna, la posición de reproducción en Ver a continuación.
  • La app configura los metadatos correctos y completos.

Cómo agregar un video sin terminar: la diferencia entre películas y episodios

El procedimiento para agregar una película y un episodio al canal Ver a continuación es muy similar. La única diferencia es que los metadatos son distintos para cada uno.

Por ejemplo, para los episodios, tenemos métodos de metadatos específicos en WatchNextProgram.Builder, como setEpisodeNumber, setSeasonNumber(), setSeasonTitle() y setEpisodeTitle().

Cómo agregar un video sin terminar (películas o episodios) al canal Ver a continuación

Para agregar un video sin terminar a un canal Ver a continuación, los desarrolladores pueden usar WatchNextProgram.Builder a fin de compilar una instancia WatchNextProgram y llamar a PreviewChannelHelper.publishWatchNextProgram, de modo que se publique en el canal Ver a continuación.

Primero, crea una instancia de compilador de WatchNextProgram y configura todos los metadatos para describir el video.

Busca el método setBuilderMetadata en PlayNextHelper.kt, en step_1, copia y pega el siguiente código entre los comentarios "Step 1.1 - Set video metadata for WatchNextProgram.".

WatchNextHelper.kt

builder.setType(type)
   .setWatchNextType(watchNextType)
   .setLastPlaybackPositionMillis(watchPosition)
   .setLastEngagementTimeUtcMillis(System.currentTimeMillis())
   .setTitle(video.name)
   .setDurationMillis(duration.toMillis().toInt())
   .setPreviewVideoUri(Uri.parse(video.videoUri))
   .setDescription(video.description)
   .setPosterArtUri(Uri.parse(video.thumbnailUri))
   // Intent uri used to deep link video when the user clicks on watch next item.
   .setIntentUri(Uri.parse(video.uri))
   .setInternalProviderId(video.id)
   // Use the contentId to recognize the same content across different channels.
   .setContentId(video.id)

if (type == TYPE_TV_EPISODE) {
   builder.setEpisodeNumber(video.episodeNumber.toInt())
       .setSeasonNumber(video.seasonNumber.toInt())
       // User TV series name and season number to generate a fake season name.
       .setSeasonTitle(context.getString(
           R.string.season, video.category, video.seasonNumber))
       // Use the name of the video as the episode name.
       .setEpisodeTitle(video.name)
       // Use TV series name as the tile, in this sample,
       // we use category as a fake TV series.
       .setTitle(video.category)
}

Consulta el código del paso 1.1 e intenta comprender por qué se configuran estos metadatos.

  1. setLastPlaybackPositionMillis() y setDurationMillis() permiten mostrar el progreso correcto de reproducción y actualizarlo cuando el usuario interactúa con el video.
  2. setLastEngagementTimeUtcMillis() establece la marca de tiempo cuando el usuario mira este video, lo que permite que el canal Ver a continuación priorice las entradas.

Cómo agregar una película sin terminar a Ver a continuación

Podemos usar WATCH_NEXT_TYPE_NEXT para agregar una película sin terminar al canal Ver a continuación.

Cómo configurar metadatos de películas: título y descripción

Para las películas, configura el título y la descripción, así como otros atributos, de modo que los usuarios sepan que están mirando el contenido correcto sin hacer clic en el video.

builder.setType(type)
   .setWatchNextType(watchNextType)
   .setLastPlaybackPositionMillis(watchPosition)
   .setLastEngagementTimeUtcMillis(System.currentTimeMillis())
   .setTitle(video.name)
   .setDurationMillis(duration.toMillis().toInt())
   .setPreviewVideoUri(Uri.parse(video.videoUri))
   .setDescription(video.description)
   .setPosterArtUri(Uri.parse(video.thumbnailUri))
...

Captura de pantalla de ejemplo para una película.

99a21ecd22268f2d.png

Cómo agregar un episodio sin terminar a Ver a continuación

Puedes usar cuatro tipos para setWatchNextType(), WATCH_NEXT_TYPE_CONTINUE para episodios de TV sin terminar y WATCH_NEXT_TYPE_NEXT para el siguiente episodio.

Cómo configurar metadatos de episodios: número de episodio y número de temporada o título

Para los episodios de TV, configura el número de episodio y el número de temporada, de modo que los usuarios sepan que están mirando el episodio correcto sin hacer clic en el video.

if (type == TYPE_TV_EPISODE) {
   Builder.setType(PreviewPrograms.TYPE_EPISODE)
       .setEpisodeNumber(video.episodeNumber.toInt())
       .setSeasonNumber(video.seasonNumber.toInt())
       // Use TV series name and season number to generate a fake season name.
       .setSeasonTitle(context.getString(
           R.string.season, video.category, video.seasonNumber))
       // Use the name of the video as the episode name.
       .setEpisodeTitle(video.name)
       // Use TV series name as the tile, in this sample,
       // we use category as a fake TV series.
       .setTitle(video.category)
}

SeasonTitle, EpisodeTitle y Title se deben configurar de manera correcta. Cada episodio tiene su propio título que describe el contenido del episodio. Podemos usarlo para EpisodeTitle. Usa el título de la serie de TV para el atributo Title del programa de TV, de modo que los usuarios sepan de qué serie son los episodios. Si tienes el título de una temporada, úsalo para SeasonTitle; en cambio, puedes usar una combinación del nombre de la serie y los números de temporada, p.ej., <nombre de la serie de TV> temporada <número de temporada>.

Captura de pantalla de ejemplo para un episodio.

658c430b13bcb3a6.png

Cómo reanudar la reproducción

setLastPlaybackPositionMillis(watchPosition) se usa para pasar el tiempo en el que el usuario dejó de ver la película o el episodio; este progreso se mostrará en la tarjeta de Ver a continuación. En la app de referencia de TV, el código usa WatchProgressDatabase para realizar un seguimiento del progreso de reproducción de cada video. De esta manera, se permite que los usuarios reanuden la reproducción desde el punto anterior, sin importar cómo navegan al video.

De acuerdo con los lineamientos de reproducción de acciones de visualización, el episodio debe comenzar a reproducirse inmediatamente después de que se cargue el contenido de video. No es necesario volver a mostrar la información de la serie de TV, ya que los usuarios ya comenzaron a verla.

Luego, llama al elemento PreviewChannelHelper.publishWatchNextProgram para publicarlo en el canal Ver a continuación. Busca "Step 1.2" en el mismo archivo y pega el siguiente código:

WatchNextHelper.kt

try {
   programId = PreviewChannelHelper(context)
       .publishWatchNextProgram(updatedProgram)
   Timber.v("Added New program to Watch Next row: ${updatedProgram.title}")
} catch (exc: IllegalArgumentException) {
   Timber.e(
       exc, "Unable to add program to Watch Next row. ${exc.localizedMessage}"
   )
   exc.printStackTrace()
}

Cómo actualizar el progreso de reproducción

Si ya existe una tarjeta del canal Ver a continuación, la app deberá mantenerla actualizada si el usuario mira más contenido del video para reflejar el último progreso de reproducción.

Cuando actualices WatchNextProgram, usa la misma clase de compilador para compilar WatchNextProgram y llama a updateWatchNextProgram de PreviewChannelHelper a fin de actualizar una entrada existente. Pega el siguiente código en "Step 1.3", en WatchNextHelper.kt.

WatchNextHelper.kt

programId = existingProgram.id
PreviewChannelHelper(context).updateWatchNextProgram(updatedProgram, programId)

Cómo verificar el resultado

Revisa el código, compara los cambios con el código fuente en step_1_completed, ejecuta step_1_completed y mira parte del episodio. Verifica si se agregó al canal Ver a continuación.

Validaciones

  • ✅ APROBADA: El programa se agrega a Ver a continuación cuando se pausa o se detiene
  • ✅ APROBADA: La app puede reanudar la reproducción desde la entrada de Ver a continuación
  • ✅ APROBADA: La app actualiza, de manera oportuna, la posición de reproducción en Ver a continuación
  • ✅ APROBADA: La app configura los metadatos correctos y completos
  • ✅ APROBADA: Todo el contenido sin terminar se envía a Ver a continuación
  • ❗ FALLIDA: El programa se quita de Ver a continuación cuando se completa la reproducción
  • ❗ FALLIDA: El siguiente episodio se agrega cuando finaliza el episodio actual
  • ❗ FALLIDA: La app no agrega a Ver a continuación contenido con el que el usuario no haya interactuado
  • ❗ FALLIDA: La app no agrega varios episodios para la misma serie de TV

Qué aprendiste

En esta sección, aprendiste a hacer lo siguiente:

  • Crear un elemento WatchNextProgram
  • Insertar o actualizar WatchNextProgram en el canal Ver a continuación
  • Actualizar el progreso de reproducción
  • Reanudar la reproducción
  • Configurar los metadatos correctos para un episodio de TV

¿Qué sigue?

Agrega un episodio sin terminar al canal Ver a continuación

5. Cómo quitar contenido (películas o episodios) de Ver a continuación cuando se completa la reproducción

Las tarjetas del canal Ver a continuación se ordenan por el tiempo de participación más reciente, y se ubica el video con la participación más reciente al principio del canal. La app debe quitar el programa del canal Ver a continuación después de que el usuario termina de mirarlo y debe promover contenido más relevante para los usuarios.

Los desarrolladores deben supervisar el progreso de reproducción de un video. Una vez que el usuario termina de mirar un video, la app debe quitarlo del canal Ver a continuación.

Nota: Puedes usar la misma lógica para quitar una película o un episodio del canal Ver a continuación.

Cómo quitar WatchNextProgram

A fin de borrar una entrada del canal Ver a continuación, los desarrolladores deben buscar el elemento WatchNextProgram correcta y usar el URI del programa para borrarlo del proveedor de contenido. Para ello, los desarrolladores deben lograr que WatchNextProgram coincida con las entidades de video en su propia base de datos. Podemos aprovechar el campo internalProviderId, configurar un identificador único de video y vincularlo con una de las entidades de la base de datos del desarrollador.

Primero, para encontrar el elemento WatchNextProgram correcto, busca el ID de video. Puedes acceder a internalProviderId desde WatchNextProgram. getInternalProviderId o acceder a través del proveedor de contenido de WatchNextProgram y, luego, quitarlo del canal Ver a continuación con el URI.

Busca "Step 2.1", copia y pega el siguiente código:

WatchNextHelper.kt

val foundProgram = getWatchNextProgramByVideoId(video.id, context)
if (foundProgram == null) {
   Timber.e(
       "Unable to delete. No program found with videoID ${video.id}"
   )
   return null
}

// Use the found program's URI to delete it from the content resolver
return foundProgram.let {
   val programUri = TvContractCompat.buildWatchNextProgramUri(it.id)
   // delete returns the number of rows deleted.
   val deleteCount = context.contentResolver.delete(
       programUri, null, null
   )

   if (deleteCount == 1) {
       Timber.v("Content successfully removed from Watch Next")
       programUri
   } else {
       Timber.e("Content failed to be removed from Watch Next, delete count $deleteCount")
       null
   }
}

Si deseas quitar varios elementos WatchNextProgram a la vez, siempre puedes solicitar una operación por lotes para optimizar las visitas al proveedor de contenido de la TV. Busca "Step 2.2", copia y pega el siguiente fragmento de código en WatchNextHelper.kt.

WatchNextHelper.kt

val foundPrograms = getWatchNextProgramByVideoIds(videos.map { it.id }, context)
val operations = foundPrograms.map {
   val programUri = TvContractCompat.buildWatchNextProgramUri(it.id)
   ContentProviderOperation.newDelete(programUri).build()
} as ArrayList<ContentProviderOperation>

val results = context.contentResolver.applyBatch(TvContractCompat.AUTHORITY, operations)

results.forEach { result ->
   if (result.count != 1) {
       Timber.e("Content failed to be removed from Watch Next: ${result.uri}")
   }
}

Según los lineamientos de Ver a continuación, se debe quitar un episodio si el usuario lo terminó. Cuando comiencen los créditos finales, el usuario habrá "terminado" de verlo. En este caso, no lo agregues al canal Ver a continuación (o quítalo si ya se agregó). Puedes determinar este estado mediante una tecnología para detectar automáticamente los créditos finales o usar una aproximación basada en la duración del contenido (por ejemplo, menos de 3 minutos en un episodio).

Si observas el método handleWatchNextForEpisodes() en WatchNextHelper.kt, puedes encontrar el siguiente fragmento:

WatchNextHelper.kt

video.isAfterEndCreditsPosition(watchPosition.toLong()) -> {
   removeVideoFromWatchNext(context, video)

   ...
}

En este codelab, usamos VIDEO_COMPLETED_DURATION_MAX_PERCENTAGE para simular la posición de la escena de créditos; puedes reemplazar el código en isAfterEndCreditsPosition() por tu propia lógica.

Cómo verificar el resultado

Revisa el código, compara los cambios con el código fuente en step_2_completed, ejecuta step_2_completed y mira un episodio. Verifica si se quitó del canal Ver a continuación después de que terminaste de verlo.

Validación

  • ✅ APROBADA: El programa se agrega a Ver a continuación cuando se pausa o se detiene
  • ✅ APROBADA: La app puede reanudar la reproducción desde la entrada de Ver a continuación
  • ✅ APROBADA: La app actualiza, de manera oportuna, la posición de reproducción en Ver a continuación
  • ✅ APROBADA: La app configura los metadatos correctos y completos
  • ✅ APROBADA: Todo el contenido sin terminar se envía a Ver a continuación
  • ✅ APROBADA: El programa se quita de Ver a continuación cuando se completa la reproducción
  • ❗ FALLIDA: El siguiente episodio se agrega cuando finaliza el episodio actual
  • ❗ FALLIDA: La app no agrega a Ver a continuación contenido con el que el usuario no haya interactuado
  • ❗ FALLIDA: La app no agrega varios episodios para la misma serie de TV

Qué aprendiste

En esta introducción, aprendiste lo siguiente:

  • Identificar la escena de créditos de los episodios de TV
  • Buscar el elemento WatchNextProgram por ID de video
  • Borrar un solo elemento WatchNextProgram
  • Borrar varios elementos WatchNextProgram

¿Qué sigue?

Agrega el siguiente episodio al canal Ver a continuación

6. Cómo agregar el siguiente episodio

A diferencia de las películas, los programas de TV tienen más de 1 temporada y muchos episodios en cada temporada. Si el usuario termina de ver un episodio, en lugar de solo quitarlo del canal Ver a continuación, te recomendamos que lo reemplaces por el siguiente episodio. El siguiente episodio puede ser uno que se reproduce justo después del que se vio en la misma temporada o el primer episodio de la siguiente temporada si el episodio que se terminó es el último de la temporada actual.

Cuando agregues el siguiente episodio al canal Ver a continuación, configura el tipo Ver a continuación en WATCH_NEXT_TYPE_NEXT, que indica que este episodio no es un programa que se haya visto antes, sino un episodio completamente nuevo que el usuario podría seguir. Las apps deben permitir que el usuario mire el siguiente episodio desde el principio. Busca "TODO: Step 3.1 - Add next episode from TV series.", copia y pega el siguiente código en el paso 3.1:

WatchNextHelper.kt

videoRepository.getNextEpisodeInSeries(video)?.let {
       insertOrUpdateVideoToWatchNext(
           it,
           0,
           WATCH_NEXT_TYPE_NEXT,
           context
       )
       newWatchNextVideo = it
   }

El método getNextEpisodeInSeries() captura el siguiente episodio.

Siguiente episodio de la misma temporada

Si la temporada actual todavía tiene más episodios, las apps deben seleccionar el siguiente episodio disponible y establecerlo como el siguiente.

Primer episodio de la siguiente temporada

Si el usuario terminó de mirar la temporada actual, pero hay una temporada más reciente disponible, las apps deberían seleccionar el primer episodio de la siguiente temporada como el siguiente episodio.

Publicación de un episodio nuevo

Si no existen más episodios, las apps no necesitan agregar un siguiente episodio. Sin embargo, cuando haya un episodio nuevo disponible, es una idea excelente mostrárselo al cliente y agregarlo al canal Ver a continuación. Los episodios nuevos deben usar WATCH_NEXT_TYPE_NEW como el tipo WatchNextProgram. Esta solución necesita notificaciones push desde el servidor, pero, en este codelab, no se trata este tema.

Cómo verificar el resultado

Revisa el código, compara los cambios con el código fuente en step_3_completed, ejecuta step_3_completed y mira un episodio. Verifica si el siguiente episodio se agregó al canal Ver a continuación después de que terminaste de verlo.

Validación

  • ✅ APROBADA: El programa se agrega a Ver a continuación cuando se pausa o se detiene
  • ✅ APROBADA: La app puede reanudar la reproducción desde la entrada de Ver a continuación
  • ✅ APROBADA: La app actualiza, de manera oportuna, la posición de reproducción en Ver a continuación
  • ✅ APROBADA: La app configura los metadatos correctos y completos
  • ✅ APROBADA: Todo el contenido sin terminar se envía a Ver a continuación
  • ✅ APROBADA: El programa se quita de Ver a continuación cuando se completa la reproducción
  • ✅ APROBADA: El siguiente episodio se agrega cuando finaliza el episodio actual
  • ❗ FALLIDA: La app no agrega a Ver a continuación contenido con el que el usuario no haya interactuado
  • ❗ FALLIDA: La app no agrega varios episodios para la misma serie de TV

Qué aprendiste

En esta sección, aprendiste a hacer lo siguiente:

  • Seleccionar el siguiente episodio
  • Agregar el siguiente episodio a la serie de TV

¿Qué sigue?

Comprende el interés del usuario.

7. Comprende el interés del usuario

Para mantener la atención de los usuarios en el contenido más relevante del canal Ver a continuación, la app debe tener en cuenta otras consideraciones cuando se agrega un episodio de TV al canal Ver a continuación o cuando se quita de este.

Varios episodios de la misma serie

Por varios motivos, el usuario puede tener más de 1 episodio sin terminar en un momento específico. Por ejemplo:

  1. La serie de TV está disponible en varias apps o al aire.
  2. El usuario desea adelantarse y omitir parte del contenido.

El canal Ver a continuación cuenta con entradas muy limitadas en la pantalla principal. Google recomienda que las apps conserven un máximo de un episodio de cada serie de TV en el canal Ver a continuación. Además, el episodio que se muestre debe ser el último episodio que el usuario miró.

En la clase WatchNextHelper, lo controlamos en handlePlayNextForEpisode(). Busca "Step 4.1", copia y pega el siguiente código en el área en blanco del paso 4.1.

WatchNextHelper.kt

newWatchNextVideo?.let { videoToKeep ->
   videoRepository.getAllVideosFromSeries(videoToKeep.seriesUri)?.let { allEpisodes ->
           filterWatchNextVideos(allEpisodes, context)
               ?.let { watchedEpisodes ->
                   removeVideosFromWatchNext(
                       context, watchedEpisodes.filter { it.id != videoToKeep.id })
               }
       }
}

En el paso 4.1, realizamos el seguimiento del último episodio que miró el usuario y eliminamos todos los demás episodios de la misma serie de TV. Como, en este paso, se quitan varios episodios a la vez, creamos un método removeVideosFromWatchNext() nuevo para aprovechar la operación por lotes del proveedor de contenido de Android.

Contenido con menos interacción

Según los lineamientos de Ver a continuación, un episodio solo debe agregarse al canal Ver a continuación si el usuario comenzó a verlo. Se considera que el usuario "comenzó" un episodio si lo miró por más de 2 minutos. Busca "Step 4.2", copia y pega el siguiente código en el área del paso 4.2.

WatchNextHelper.kt

val durationInMilliSeconds = duration.toMillis().toInt()
// Return true if either X minutes or Y % have passed
// Following formatting spans over multiple lines to accommodate max 100 limit
val watchNextMinStartedMillis = TimeUnit.MINUTES.toMillis(WATCH_NEXT_STARTED_MIN_MINUTES)
// Check if either X minutes or Y% has passed
val hasVideoStarted =
   (currentPosition >= (durationInMilliSeconds * WATCH_NEXT_STARTED_MIN_PERCENTAGE)) or
           (currentPosition >= watchNextMinStartedMillis)
val hasVideoStartedWithValidPosition =
   ((currentPosition <= durationInMilliSeconds) and hasVideoStarted)
Timber.v(
   "Has video started: %s, duration: %s, watchPosition: %s",
   hasVideoStartedWithValidPosition,
   duration,
   currentPosition
)
return hasVideoStartedWithValidPosition

Cómo verificar el resultado

Revisa el código, compara los cambios con el código fuente en step_4_completed, ejecuta step_4_completed y mira un episodio. Verifica lo siguiente:

  1. Si el código quita el episodio adicional de la serie de TV
  2. Si solo se agrega al canal Ver a continuación cuando el usuario comienza a verlo

Validación

  • ✅ APROBADA: El programa se agrega a Ver a continuación cuando se pausa o se detiene
  • ✅ APROBADA: La app puede reanudar la reproducción desde la entrada de Ver a continuación
  • ✅ APROBADA: La app actualiza, de manera oportuna, la posición de reproducción en Ver a continuación
  • ✅ APROBADA: La app configura los metadatos correctos y completos
  • ✅ APROBADA: Todo el contenido sin terminar se envía a Ver a continuación
  • ✅ APROBADA: El programa se quita de Ver a continuación cuando se completa la reproducción
  • ✅ APROBADA: El siguiente episodio se agrega cuando finaliza el episodio actual
  • ✅ APROBADA: La app no agrega a Ver a continuación contenido con el que el usuario no haya interactuado
  • ✅ APROBADA: La app no agrega varios episodios para la misma serie de TV

Qué aprendiste

En esta sección, aprendiste a hacer lo siguiente:

  • Evitar agregar varios episodios de la misma serie de TV
  • Evitar agregar contenido con menos interacción

¿Qué sigue?

Felicitaciones

8. Felicitaciones

Felicitaciones. Compilaste con éxito Ver a continuación para tu episodio de TV y aprendiste todos los requisitos de calidad en Ver a continuación.

Bien hecho.

Lecturas adicionales

Documentos de referencia