Skip to content

配方 · 播完倒计时跳下一集

参考实现:examples/team-video-vue/VideoPageWithRec.vue

需求:视频播完 → 显示「5 秒后播放下一集」→ 倒计时结束跳转,期间可取消。


最重要的一件事:倒计时是你自己跑的

SDK 不提供任何倒计时能力。它只发一个 ended 事件,剩下全是团队层的事。

这是 ADR-025 的直接结果:结束覆盖层归团队层。SDK 不做 UI,自然也不做 UI 的计时器。

SDK 的职责:  ────────────▶ ended
团队层的职责:              倒计时 · 文案 · 取消按钮 · 路由跳转 · 推荐列表联动

完整接线

ts
// VideoPageWithRec.vue
const endOverlayConfig = computed(() => ({
  type: 'countdown' as const,
  duration: props.countdownDuration,
  text: nextVideo.value
    ? t('nextEpisode', { seconds: '{seconds}', title: nextVideo.value.title })
    : t('backToList', { seconds: '{seconds}' }),
  cancellable: true,
  onComplete: () => {
    if (nextVideo.value) router.push(`/video/${nextVideo.value.id}`)
    else router.back()
  },
  onTick: (payload: { remaining: number }) => {
    countdownRemaining.value = payload.remaining
  },
}))
vue
<TeamVideoPlayer :source="source" :end-overlay="endOverlayConfig" />

end-overlay 不是 SDK 的 prop

它是 TeamVideoPlayer(团队封装层)自己的 prop。SDK 的 VideoPlayerFrame 上没有这个东西 —— 它只有 @ended 事件。

参考实现把倒计时封装进了团队层,所以业务页面看起来像是"配置"出来的。 你自己写的时候,这一层需要你实现。


onTick 的用处:让推荐列表同步

只有 onComplete 是不够的。倒计时期间,推荐列表里「下一集」那张卡应该有个进度条 在走 —— 这需要每秒的剩余时间:

ts
onTick: ({ remaining }) => { countdownRemaining.value = remaining }
vue
<!-- 推荐列表里下一集的卡片 -->
<div class="progress" :style="{ width: `${(1 - remaining / duration) * 100}%` }" />

没有这个联动,用户会觉得播放器上的倒计时和列表是两个不相干的东西。


为什么要 cancellable

用户可能只是想看完这一集就停,或者想回看某一段。倒计时必须能取消, 而且取消后不该再自动跳。

ts
cancellable: true

取消之后建议保留一个「播放下一集」按钮 —— 用户取消的是自动跳转, 不是"不想看下一集"。


点播才有 ended

直播没有「播完」这回事。这个配方只适用于点播。

如果你的源是 live: true,ended 基本不会触发(除非推流方断了), 不要基于它做业务逻辑。见点播和直播差在哪


切到下一集:改 source,不调方法

跳转如果是路由级的(整个页面重建),不用管。但如果你想不跳路由直接换下一集:

vue
<TeamVideoPlayer :source="currentSource" />
ts
function playNext() {
  currentSource.value = videoToSource(nextVideo.value)   // 改 prop 就行
}

内部会自动 load,不重建 iframe —— 比销毁重建快得多,也不会闪一下黑屏。


相关