Appearance
配方 · 播完倒计时跳下一集
参考实现:
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 —— 比销毁重建快得多,也不会闪一下黑屏。
相关
- 在播放器上做 UI · 场景 5 —— 播完覆盖层的具体写法
- 为何没有逃生舱 —— 为什么倒计时不做进 SDK