Android Dev Summit, October 23-24: two days of technical content, directly from the Android team. Sign-up for livestream updates.

Cómo agregar compatibilidad con la pausa en directo

Usa las API de pausa en directo en tu servicio de entrada de TV para permitir que los usuarios pausen, retrocedan y adelanten los programas en vivo en los canales de tu servicio. Si tu app admite la pausa en directo, los usuarios obtienen mayor flexibilidad en cuanto a la manera en que miran tu contenido, por ejemplo:

  • Pueden pausar programas mientras controlan una interrupción de corto plazo, lo que garantiza que nunca se pierdan de momentos clave.
  • Pueden adelantar el contenido que ya vieron o que no les interesa.
  • Pueden retroceder o volver a mirar sus momentos favoritos del contenido del programa.

Figura 1: Controles de reproducción de Android TV para pausa en directo

La función de pausa en directo usa segmentos cortos, temporales y grabados de los datos del programa a fin de implementar la capacidad de reproducción de programas en vivo. Los usuarios no pueden reproducir estas grabaciones con pausa en directo fuera de la sesión de reproducción de ese momento, por lo que no pueden pausar un programa mediante esta función para verlo al día siguiente o más tarde cuando cambian a un canal diferente. Usa las API de grabación de TV si quieres permitir que los usuarios graben contenido de programas para ver fuera de la sesión reproducción.

Cómo agregar compatibilidad con la pausa en directo

Para agregar compatibilidad con la pausa en directo a tu servicio de entrada de TV, deberás implementar las API de pausa en directo en tu clase TvInputService.Session, administrar la grabación y reproducción de grabaciones con pausa en directo en tu app, y notificar al sistema que tu servicio de entrada proporciona compatibilidad con esta función.

Los métodos TvInputService.Session que debes implementar son los siguientes:

Para obtener más detalles sobre cómo informar al sistema que tu servicio de entrada admite pausa en directo, consulta Cómo notificar al sistema sobre el estado de la pausa en directo.

Si usas la Biblioteca complementaria del TIF para implementar tu clase TvInputService.Session, automáticamente obtendrás una implementación de pausa en directo que usa ExoPlayer. Puedes usar esta implementación, o bien anular los métodos de la API de pausa en directo en BaseTvInputService.Session y proporcionar tu propia implementación. Para obtener más información sobre cómo usar la Biblioteca complementaria del TIF, consulta Cómo crear un servicio de entrada de TV mediante la Biblioteca complementaria del TIF.

Cómo grabar contenido cuando comienza una sesión

Un usuario puede pausar, retroceder y adelantar el contenido de un programa al acceder a los controles de reproducción del canal (al presionar Seleccionar mientras mira contenido y, luego, navegar a los controles de reproducción), o bien al usar los controles de reproducción dedicados en un dispositivo remoto, si están disponibles. Como el usuario puede usar la pausa en directo en cualquier momento cuando mira el contenido de un programa, tu servicio de entrada de TV debe comenzar a grabar el contenido con pausa en directo apenas el usuario sintoniza un canal en tu implementación onTune(). En este punto, también deberás informar al sistema que tienes la capacidad de grabar mediante una llamada a notifyTimeShiftStatusChanged(int), como se describe en Cómo notificar al sistema sobre el estado de la pausa en directo.

Cómo administrar el almacenamiento de contenido grabado

Tu servicio de TV es responsable de almacenar las grabaciones con pausa en directo en el almacenamiento privado de la app y reproducir el contenido cuando el sistema llama a tus métodos de pausa en directo, como onTimeShiftResume(). Si tu contenido ya está almacenado en la nube y tu app puede administrar las grabaciones con pausa en directo en esta, puedes usar el almacenamiento en la nube en lugar de en la app.

Si tu contenido usa contenido protegido, tu servicio de entrada de TV es responsable de realizar la encriptación adecuada del contenido grabado y la desencriptación durante la reproducción.

Como el contenido de video grabado puede requerir mucho espacio de almacenamiento, debes administrar cuidadosamente el contenido grabado durante la sesión de reproducción. Si el tiempo de la sesión de reproducción excede el total de tiempo de pausa en directo que puedes grabar y almacenar, deberías ajustar la grabación con pausa en directo a fin de mantener el búfer de ese momento, pero garantizar que se capture lo que está reproduciendo en ese momento en simultáneo. Por ejemplo, si el usuario reprodujo contenido durante 31 minutos y el tamaño máximo de grabación con pausa en directo es de 30 minutos, puedes ajustar la grabación y el tiempo de inicio a fin de incluir contenido desde el minuto 1 al minuto 31.

Si tu servicio de entrada de TV no admite la pausa en directo debido a falta de espacio de almacenamiento, deberás informarlo al sistema. Para obtener más detalles sobre cómo notificar al sistema sobre las restricciones de compatibilidad con la pausa en directo, consulta Cómo notificar al sistema sobre el estado de la pausa en directo.

Cuando un usuario cambia a un canal diferente o finaliza la sesión de reproducción, deberías borrar los datos grabados de la pausa en directo.

Cómo notificar al sistema sobre el estado de la pausa en directo

Si tu servicio de entrada de TV admite la pausa en directo, llama a notifyTimeShiftStatusChanged(TvInputManager.TIME_SHIFT_STATUS_AVAILABLE) en tu implementación de onTune() cuando un usuario sintonice un canal.

Para informar al sistema sobre algún cambio en las capacidades de pausa en directo de tu servicio de entrada, usa notifyTimeShiftStatusChanged(int). Por ejemplo, si tu servicio de entrada de TV no admite pausa en directo debido a restricciones de espacio de almacenamiento u otros motivos, llama a notifyTimeShiftStatusChanged(TvInputManager.TIME_SHIFT_STATUS_UNAVAILABLE).

Si tu servicio de entrada de TV simplemente no admite la pausa en directo, llama a notifyTimeShiftStatusChanged(TvInputManager..TIME_SHIFT_STATUS_UNSUPPORTED) cuando se cree una sesión de reproducción. El sistema trata cualquier servicio de entrada que nunca llama a notifyTimeShiftStatusChanged() como un servicio de entrada que no admite la pausa en directo (se incluyen los servicios de entrada que usan la API nivel 22 y versiones anteriores).

Cómo realizar el seguimiento de los tiempos de la reproducción

La posición de inicio de una grabación con pausa en directo es la posición de tiempo absoluto más temprana (en milisegundos desde la época) a la que el usuario puede saltar. Este suele ser el tiempo en el que se inicia la reproducción de video luego de que se llama a onTune(). Sin embargo, en los casos en los que el usuario mira una cantidad de contenido que excede el total que la app puede grabar, es posible que debas comenzar a grabar un nuevo segmento para la pausa en directo, y deberías actualizar el tiempo de inicio según corresponda.

La posición del momento de una grabación con pausa en directo es la posición de reproducción de ese momento, en milisegundos desde la época. Esta posición cambia constantemente durante la reproducción. Por lo general, puedes usar un motor de reproducción para determinar este valor, por ejemplo:

Kotlin

    override fun onTimeShiftGetCurrentPosition(): Long =
            tvPlayer?.run {
                currentProgram?.let { program ->
                    currentPosition + program.startTimeUtcMillis
                }
            } ?: TvInputManager.TIME_SHIFT_INVALID_TIME
    

Java

    @Override
    public long onTimeShiftGetCurrentPosition() {
      if (getTvPlayer() != null && currentProgram != null) {
        return getTvPlayer().getCurrentPosition() +
          currentProgram.getStartTimeUtcMillis();
      }
      return TvInputManager.TIME_SHIFT_INVALID_TIME;
    }
    

Asegúrate de que el tiempo de inicio que proporciones cuando el sistema llame a onTimeShiftGetStartPosition() no sea mayor que la posición de tiempo que proporciones en onTimeShiftGetCurrentPosition(). El sistema usa estas llamadas para actualizar la duración de la pausa en directo en la IU de controles de reproducción.

Cómo agregar compatibilidad con los parámetros de reproducción

Para cambiar la velocidad de reproducción durante la pausa en directo, el sistema usa parámetros de reproducción. Por ejemplo, si el usuario decide retroceder la reproducción, los nuevos parámetros de reproducción se pasan a tu app con una velocidad de reproducción negativa. La función de pausa en directo admite diferentes niveles (2x y 3x) de velocidad de reproducción para retroceder o adelantar contenido.

El sistema llama a tu método onTimeShiftSetPlaybackParams(PlaybackParams) con un objeto PlaybackParams que contiene parámetros para la sesión del momento. Usa esta información para configurar el motor de reproducción de contenido multimedia según corresponda.

Si tu motor de reproducción no admite un parámetro, deberías intentar emular el comportamiento esperado lo mejor que puedas. Por ejemplo, si tu motor de reproducción no admite la velocidad 2x, usa operaciones de salto repetidas en el motor de reproducción a fin de lograr una velocidad de reproducción doble aproximada.

Cuando hayas configurado los parámetros, no debes modificar la configuración a menos que el usuario emita un comando de reproducción que requiera un parámetro diferente o sintonice un nuevo canal.