Skip to content

配方 · 高清需要登录

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

需求:未登录用户只能看标清;高清档位显示「登录享」;点击弹登录框; 登录成功后自动切到高清。


关键认知:「被锁档位」不是契约概念

契约里的 QualityLevel 只有 { level, label?, height?, bitrate? } —— 没有 requiresAuth 这种字段,也不会有。

清晰度要不要登录,是你的业务规则,SDK 不掺和。所以这个配方的做法是: SDK 照常给出全部档位,团队层在渲染菜单时自己判断哪些该锁。

ts
// 被锁档位 = 需鉴权且未登录的那些(业务概念,不进契约)
const lockedQuality = computed(() =>
  props.isLoggedIn ? [] : props.qualityLevels.filter((q) => q.requiresAuth).map((q) => q.index),
)

requiresAuth 来自你自己的视频详情接口,不是 ready 事件。


三步接线

① 改标签

ts
const qualityLabels = computed<Record<number, string>>(() => {
  const map: Record<number, string> = {}
  for (const q of props.qualityLevels) {
    map[q.index] = q.requiresAuth && !props.isLoggedIn
      ? t('quality.hdLoginRequired')     // 「高清(登录享)」
      : q.label
  }
  return map
})

② 拦截点击

被锁的档位点了不切换,而是走登录流程:

ts
function handleQualityLocked(level: number) {
  const chosen = props.qualityLevels.find((q) => q.index === level)
  if (!chosen) return
  wasHdRequested.value = true            // 记下用户想要高清
  analytics.track(ANALYTICS_EVENTS.QUALITY_LOGIN_REQUIRED, {
    resolution: chosen.resolution,
  })
  showDialog({ /* ... */ }).then(() => emit('loginRequired', chosen))
}

③ 登录后自动补上

ts
watch(
  () => props.isLoggedIn,
  (loggedIn) => {
    if (loggedIn && wasHdRequested.value) {
      playerRef.value?.setQuality(props.premiumQualityIndex)
      currentQualityIndex.value = props.premiumQualityIndex
      wasHdRequested.value = false
    }
  },
)

wasHdRequested 这个标记是体验的关键。没有它,用户为了看高清专门去登录, 回来发现还是标清,得再点一次菜单 —— 白费一次交互。


别忘了 qualitychangeauto 字段

js
onQualityChange({ level, auto })

auto: true 表示是 ABR 自适应切的,不是用户选的。

菜单里「当前选中」的高亮不该被 ABR 的自动切换改掉 —— 否则用户手动选了 720p,网络一波动 ABR 降到 480p,菜单跟着跳, 用户会以为自己的选择被系统推翻了。

js
function handleQualityChange({ level, auto }) {
  currentPlayingLevel.value = level          // 实际在播的,用于显示"当前 480p"
  if (!auto) userSelectedLevel.value = level // 只有手动切才更新"用户选择"
}

高清源本身也要鉴权

菜单锁住只是 UI 层面 —— 用户改改前端代码就能绕过。真正的门槛在源上:

高清那一档的 URL 应该是登录后才签得出来的签名 URL。未登录时, 要么这一档根本不在 manifest 里,要么拉流会 403。

前端的锁是为了体验(告诉用户为什么看不了),不是为了安全。

签名 URL 与过期


相关