You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

6.7 KiB

Live Playback Stabilize Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Reduce dock live stutter / artifacting / full-player reconnects by tuning HLS for normal (non-LL) live and narrowing play-url rebuilds.

Architecture: Keep responsibilities: LivePlayer.vue owns media attach/retry/recover; useMonitorLive.js owns session/lease/play-url. Soften hls.js for 6–12s segments, lengthen startup same-URL 404 window, attempt one media recover before bubbling fatals, leave TLS/403/57006 paths unchanged.

Tech Stack: Vue 3, hls.js, existing Monitor live composable

Spec: docs/superpowers/specs/2026-09-03-live-playback-stabilize-design.md


Task 1: LivePlayer HLS config + startup window

Files:

  • Modify: src/components/LivePlayer.vue

  • Step 1: Lengthen startup retry constants

Near top of <script setup> replace:

const STARTUP_RETRY_DELAYS_MS = [500, 1000, 2000, 4000]
const STARTUP_WINDOW_MS = 15_000

with:

const STARTUP_RETRY_DELAYS_MS = [500, 1000, 2000, 4000, 6000, 8000]
const STARTUP_WINDOW_MS = 30_000
  • Step 2: Switch Hls to normal live + wider load retries

In attachPlayer, replace the new Hls({...}) block with:

    // 现网为普通 6–12s HLS,不是 LL-HLS;放宽分片重试,启动 404 仍由同 URL 窗口控制
    hls = new Hls({
      enableWorker: true,
      lowLatencyMode: false,
      manifestLoadingMaxRetry: 2,
      manifestLoadingRetryDelay: 1000,
      levelLoadingMaxRetry: 2,
      levelLoadingRetryDelay: 1000,
      fragLoadingMaxRetry: 4,
      fragLoadingRetryDelay: 1000,
    })
  • Step 3: One-shot media recover before bubbling other fatals

Still inside the hls.on(Hls.Events.ERROR, ...) handler, after the startup-404 branch and before the final emitFatal for generic fatals, insert:

      // 播放中解码/媒体缓冲类 fatal:先尝试一次 recover,避免整段重建
      if (data.type === Hls.ErrorTypes.MEDIA_ERROR) {
        try {
          console.warn('[live-player] hls media fatal, recover once', data)
          hls.recoverMediaError()
          return
        } catch (recoverErr) {
          console.warn('[live-player] hls recover failed', recoverErr)
        }
      }

Keep existing branches for:

  • isSecurityFailureSecurityError fatal
  • httpCode === 403 → fatal
  • startup 404 / MANIFEST_LOAD_ERRORscheduleSameUrlRetry then fatal

Do not call recoverMediaError for network/manifest fatals already handled above.

  • Step 4: Static check

Run:

rg -n "lowLatencyMode|STARTUP_WINDOW_MS|STARTUP_RETRY_DELAYS_MS|recoverMediaError|fragLoadingMaxRetry" src/components/LivePlayer.vue

Expected:

  • lowLatencyMode: false

  • STARTUP_WINDOW_MS = 30_000

  • delays include 6000, 8000

  • fragLoadingMaxRetry: 4

  • recoverMediaError present once

  • Step 5: Commit

git add src/components/LivePlayer.vue
git commit -m "$(cat <<'EOF'
fix: stabilize LivePlayer for normal HLS live

Disable lowLatencyMode, widen fragment retries, extend startup 404
window to 30s, and recover media fatals once before bubbling.
EOF
)"

Task 2: Tighten onPlayError comments / branch clarity

Files:

  • Modify: src/composables/useMonitorLive.js

Behavior should already mostly match the spec. This task only adjusts comments / ordering if needed so the policy is explicit; do not change heartbeat math, phase poll, stop gate, or 57006 rejoin.

  • Step 1: Read current onPlayError

Confirm current order is effectively:

  1. ignore AbortError / NotAllowedError
  2. ignore recoverable === true
  3. 57006rejoinAfterLeaseInvalid
  4. TLS/403 → markPlayFatal (no play-url refresh)
  5. HlsError (startup exhausted etc.) → markPlayFatal
  6. else limited refreshPlayURL({ fromRetry: true }) up to PLAY_RETRY_MAX
  • Step 2: If comments are misleading, rewrite the header comment only

Replace / add above onPlayError:

  // 播放错误策略(稳播):
  // - 启动 404 由 LivePlayer 同 URL 窗口消化,recoverable 不上冒
  // - TLS/403 致命,禁止刷 play-url
  // - 其它 LivePlayer fatal:有限次 refreshPlayURL;57006 整段 rejoin

Only change control flow if Step 1 finds a real divergence from the spec (e.g. TLS path accidentally refreshing). Prefer minimal diff.

  • Step 3: Commit (skip if no file change)
git add src/composables/useMonitorLive.js
git commit -m "docs: clarify live onPlayError stabilize policy"

If unchanged:

git status -sb

Expected: clean for that file / nothing to commit.


Task 3: Build + smoke notes + deploy

Files:

  • None required (verification)

  • Step 1: Production build

npm run build

Expected: success (chunk size warnings OK).

  • Step 2: Manual / API smoke checklist (dock-1)

Against deployed or local-proxied env:

  1. Open live on dock-1 → may show「正在等待直播流就绪」briefly → picture appears (no instant fail on first 404).
  2. Keep playing ~1–2 minutes → no frequent full black-flash reconnect loops.
  3. Stop dialog → Cancel still closes only (no /stop).
  4. Optional: confirm console no longer configures lowLatencyMode: true.

If browser automation blocked, API-level checks from the design evidence section remain acceptable for start/play-url; UI reconnect feel still needs a human glance when possible.

  • Step 3: Deploy (same pipeline as recent frontend ships)
git push origin main
tar -C dist -czf - . | ssh -o BatchMode=yes jg-serv1 'rm -rf /usr/share/nginx/laic-frontend/dist/* && tar -C /usr/share/nginx/laic-frontend/dist -xzf - && cat /usr/share/nginx/laic-frontend/dist/index.html'
  • Step 4: Final commit for plan doc if not already committed with earlier tasks
git add docs/superpowers/plans/2026-09-03-live-playback-stabilize.md
git commit -m "docs: add live playback stabilize plan"

(If this plan is committed before execution, do this step first; then execute Tasks 1–3.)


Spec coverage

Spec item Task
lowLatencyMode: false + wider load retries Task 1
Startup delays + 30s window Task 1
recoverMediaError once for media fatals Task 1
TLS/403/57006 / recoverable unchanged Task 1–2
onPlayError limited refreshPlayURL Task 2 (verify)
No http→https rewrite / no backend all (non-goals)
build + dock-1 acceptance Task 3

Out of scope reminders

  • Backend lease 57006 root cause
  • vpull HTTPS certificate
  • Forcing https playUrl