支持时移

在 TV 输入服务中使用时移 API 可让用户在服务频道中暂停、快退和快进直播节目。如果您的应用支持时移,用户便可以更灵活地控制观看内容的方式,例如:

  • 用户可以在处理短期中断的过程中暂停播放节目,确保不会错过关键情节。
  • 用户可以快进播放他们看过的内容或不感兴趣的内容。
  • 用户可以快退并回看节目内容中最喜爱的情节。

图 1. 时移用到的 Android TV 播放控件。

时移使用简短、临时、录制的节目数据片段来实现播放直播节目的功能。用户无法在当前播放会话之外播放这些时移录制内容,因此他们无法使用时移来暂停某个节目并留到第二天观看,也无法暂停某个节目并切换到其他频道,然后再回来继续观看。如果您想要让用户能够录制节目内容以在当前播放会话之外观看,请使用电视录制 API

添加时移支持

如需向 TV 输入服务添加时移支持,您需要在 TvInputService.Session 类中实现时移 API,在您的应用中处理时移录制内容的录制和播放,并通知系统您的输入服务提供时移支持。

您必须实现的 TvInputService.Session 方法包括:

如需详细了解如何通知系统您的输入服务支持时移,请参阅将时移状态告知系统

如果您使用 TIF 随播内容库实现 TvInputService.Session 类,会自动获得使用 ExoPlayer 的时移实现。您可以使用此实现,也可以在 BaseTvInputService.Session 中替换时移 API 方法,并提供您自己的实现。如需详细了解如何使用 TIF 随播内容库,请参阅使用 TIF 随播内容库创建 TV 输入服务

在会话开始时录制内容

用户可以通过访问频道的播放控件(在观看内容时按选择,然后转到播放控件)或使用设备遥控器上的专用播放控件(如果可用),来暂停、快退和快进播放节目内容。由于用户在观看节目内容时可以随时使用时移,因此您的 TV 输入服务必须在用户调到您的 onTune() 实现中的某个频道后立即开始录制时移内容。此时,您还需要通过调用 notifyTimeShiftStatusChanged(int) 来通知系统您可以录制内容(如将时移状态告知系统中所述)。

管理录制内容存储

TV 输入服务负责将时移录制内容存储到您应用的专用应用存储空间中,并在系统调用时移方法(例如 onTimeShiftResume())时播放内容。如果您的内容已存储在云端,并且您的应用可以管理云端的时移录制内容,那么您可以使用云端存储空间,而不必使用应用存储空间。

如果您的内容使用受保护内容,则 TV 输入服务将负责在播放过程中对录制内容进行适当加密及解密内容。

由于录制的视频内容可能需要大量的存储空间,因此您需要在会话播放过程中谨慎管理录制内容。如果播放会话时间超过您可以录制和存储时移的时间,您应该调整时移录制内容以保持当前的缓冲区,但要确保将当前时间捕获下来。例如,如果用户已播放某内容 31 分钟,而您的时移录制内容的大小上限为 30 分钟,您可以调整录制内容和起始时间以包含从第 1 分钟到第 31 分钟的内容。

如果您的 TV 输入服务因缺少存储空间而无法支持时移,您必须通知系统。如需详细了解如何将时移支持限制条件告知系统,请参阅将时移状态告知系统

在用户切换到其他频道或结束播放会话后,您应该删除录制的时移数据。

将时移状态告知系统

如果您的 TV 输入服务支持时移,请在用户调到某个频道时,在 onTune() 实现中调用 notifyTimeShiftStatusChanged(TvInputManager.TIME_SHIFT_STATUS_AVAILABLE)

如需在输入服务的任何时移功能发生更改时通知系统,请使用 notifyTimeShiftStatusChanged(int)。例如,如果您的 TV 输入服务因存储空间限制或其他原因而无法支持时移,请调用 notifyTimeShiftStatusChanged(TvInputManager.TIME_SHIFT_STATUS_UNAVAILABLE)

如果您的 TV 输入服务不支持时移,请在创建播放会话时调用 notifyTimeShiftStatusChanged(TvInputManager.TIME_SHIFT_STATUS_UNSUPPORTED)。系统会将从不调用 notifyTimeShiftStatusChanged() 的输入服务视为不支持时移的输入服务,这就涵盖了使用 API 级别 22 及更低版本的输入服务。

跟踪播放时间

时移录制内容的起始位置是用户可以跳转到的最早的绝对时间位置(以从公元纪年开始计算的毫秒数表示)。这通常是在调用 onTune() 后视频播放开始的时间。不过,如果用户观看的内容量超出了应用可以录制的上限,您可能需要开始录制新的时移片段,还应该相应地更新起始时间。

时移录制内容的当前位置是当前播放位置,以从公元纪年开始计算的毫秒数表示。此位置会在播放过程中不断更改。通常,您可以使用播放引擎来确定此值;例如:

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

请确保您在系统调用您的 onTimeShiftGetStartPosition() 时提供的起始时间绝不会大于您在 onTimeShiftGetCurrentPosition() 中提供的当前时间位置。系统会使用这些调用来更新播放控件界面中的时移持续时间。

支持播放参数

如需在时移过程中更改播放速度,系统需要使用播放参数。例如,如果用户决定快退当前播放,系统会向您的应用传递包含负播放速度的新播放参数。 时移还支持几种不同级别的快退或快进播放速度(2 倍、3 倍)。

系统会使用包含当前会话参数的 PlaybackParams 对象调用您的 onTimeShiftSetPlaybackParams(PlaybackParams) 方法。请使用此信息对您的媒体播放引擎进行适当配置。

如果您的播放引擎不支持某个参数,您应该尝试尽可能地模拟预期的行为。例如,如果您的播放引擎不支持两倍速度,请在您的播放引擎上使用重复跳转操作实现大约两倍的播放速度。

在参数设置完毕后,除非用户发出需要使用其他参数的播放命令或切换到新频道,否则不要更改这些设置。