Browse Source

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.
main
xiaosi 3 weeks ago
parent
commit
f3769af350
  1. 108
      docs/superpowers/specs/2026-09-02-live-play-url-session-id-design.md

108
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=<session.id>`
2. Media 页打开直播同样带 `streamSessionId`
3. 全仓无旧式无参 `getLivePlayURL(dockIdOnly)` / 无 `streamSessionId` 的 play-url GET
4. `npm run build` 通过
## 风险
- 后端参数名若不是 `streamSessionId`:以本 spec 为准;联调不符再改
- 百分比/网络时序导致 session 尚未写入:`refreshPlayURL` 守卫直接 return,避免无参请求
Loading…
Cancel
Save