From f3769af35039d0fe8048e3896750e76b282d2c88 Mon Sep 17 00:00:00 2001 From: xiaosi <2652281683@qq.com> Date: Wed, 2 Sep 2026 10:41:10 +0800 Subject: [PATCH] docs: require streamSessionId for live play-url Align Monitor and Media play-url callers with backend-required streamSessionId query param; no legacy no-arg compatibility. --- ...6-09-02-live-play-url-session-id-design.md | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 docs/superpowers/specs/2026-09-02-live-play-url-session-id-design.md diff --git a/docs/superpowers/specs/2026-09-02-live-play-url-session-id-design.md b/docs/superpowers/specs/2026-09-02-live-play-url-session-id-design.md new file mode 100644 index 0000000..233ae62 --- /dev/null +++ b/docs/superpowers/specs/2026-09-02-live-play-url-session-id-design.md @@ -0,0 +1,108 @@ +# 直播 play-url 必传 streamSessionId + +日期:2026-09-02 +状态:已确认(待实现计划) + +## 背景 + +后端 `GET /v1/live/{dockId}/play-url` 现要求查询参数 `streamSessionId`。前端当前两处调用仍只传 `dockId`: + +1. `src/api/live.js` → `getLivePlayURL(dockId)`,由 `useMonitorLive.refreshPlayURL()` 使用 +2. `src/views/MediaView/MediaView.vue` → `request.get(urls.LIVE_PLAY_URL(stream.dockId))` + +`heartbeat` / `leave` 已带 sessionId;join 成功后 `result.session.id` 可用。 + +## 目标 + +- play-url 请求一律携带 `streamSessionId` +- Monitor 直播与 Media 页打开直播两处行为一致 +- 无 session 时不发 play-url 请求 + +## 非目标 + +- 不改 join / heartbeat / leave 契约 +- 不把 MediaView 重构为走 `api/live.js` +- 不做旧无参调用兼容 +- 不改播放器 / UI +- 不处理 MediaView 未 leave session 的既有问题 + +## 方案 + +统一用 axios `params` 传 `streamSessionId`,不手拼 query string。 + +### 1. API + +文件:`src/api/live.js` + +```js +export function getLivePlayURL(dockId, sessionId) { + return request.get(`/v1/live/${dockId}/play-url`, { + params: { streamSessionId: sessionId } + }) +} +``` + +### 2. URL 常量 + +文件:`src/config/urls.js` + +`LIVE_PLAY_URL(dockId)` 仍只返回 path(签名不变): + +```js +export const LIVE_PLAY_URL = (dockId) => `/v1/live/${dockId}/play-url` +``` + +所有直接使用该常量的调用必须附加: + +```js +{ params: { streamSessionId: sessionId } } +``` + +实现时全仓检索 `LIVE_PLAY_URL` / `getLivePlayURL` / `play-url`,确保无遗漏。 + +### 3. Monitor 调用 + +文件:`src/composables/useMonitorLive.js` + +```js +async function refreshPlayURL() { + if (!live.dockId || !live.session?.id) return + const play = await getLivePlayURL(live.dockId, live.session.id) + live.playUrl = play.playUrl || '' +} +``` + +触发点不变:`openLive` 在 `phase === 'streaming'`;heartbeat 在 streaming 且尚无 `playUrl`。 + +### 4. Media 调用 + +文件:`src/views/MediaView/MediaView.vue` 的 `openLive` + +```js +const result = await request.post(urls.LIVE_SESSIONS(stream.dockId)) +if (result?.session?.phase === 'streaming') { + if (!result.session?.id) { + ui.toast('直播会话无效') + return + } + const play = await request.get(urls.LIVE_PLAY_URL(stream.dockId), { + params: { streamSessionId: result.session.id } + }) + if (play?.playUrl && !play.playUrl.startsWith('fake://')) window.open(play.playUrl, '_blank') + else ui.toast('控制面已验证,当前未配置可播放媒体流') +} else { + ui.toast('直播正在启动,请稍后重试') +} +``` + +## 验收 + +1. Monitor 进入 streaming 后,play-url 请求带 `streamSessionId=` +2. Media 页打开直播同样带 `streamSessionId` +3. 全仓无旧式无参 `getLivePlayURL(dockIdOnly)` / 无 `streamSessionId` 的 play-url GET +4. `npm run build` 通过 + +## 风险 + +- 后端参数名若不是 `streamSessionId`:以本 spec 为准;联调不符再改 +- 百分比/网络时序导致 session 尚未写入:`refreshPlayURL` 守卫直接 return,避免无参请求