跳到主要内容
版本:4.0

实时播放示例 (异步 HTTP API)

本示例在 同步示例 基础上增加 异步打开STOMP WebSocket 通知,适合需要 多路播放打开接口快速返回 的场景。客户端协议仍为 HTTP-FLVproto: 0)。

项目说明
示例页面live-example-flv-3
示例代码live-example-flv-3.zip
API 基址https://wx.gratour.info:7011/v1
依赖库axiosmpegts.jsstomp-websocket
测试终端模拟终端 8888000001(演示站可用)

相关文档:应用指南概览 · 异步与同步模式 · StrmNotif 通知结构

适合场景

  • 同一页面 多路 实时预览,不宜长时间阻塞在 open 接口
  • 需要在终端推流前就拿到 reqId,便于随时 取消 尚未就绪的请求
  • 可接受维护 HTTP API + STOMP WebSocket 双连接

若只需单路、逻辑尽量简单,请先用 example-1-live。新应用也可考虑 WebSocket API 示例,避免 STOMP 与 token 双管理。

与同步示例的差异

同步(example-1)异步(本示例)
async省略 / falsetrue
打开返回时通常已可播放通常 ready: false
WebSocket不需要必须 订阅 StrmNotif
何时创建播放器open 返回后立即ready: true 或收到 act=ready 通知
HTTP 基址:7200:7011(演示环境)

整体流程

live-sequence.png

1. 终端上线
2. POST /login → authToken
3. 连接 STOMP WebSocket → 订阅 /user/{token}/queue/strm
4. POST /strm/live/open (async) → 立即返回 reqId、playUrl(ready 可能为 false)
5. 若 ready=false → 等待 StrmNotif (act=ready)
6. flv.js 加载 playUrl → 播放
7. 每 15 秒 POST /strm/keep_alive
8. 停止:销毁播放器 → POST /strm/close

准备工作

example-1-live 相同:终端指向 wx.gratour.info:7510,在 演示站 确认 8888000001 在线。

term-online.png

步骤详解

步骤 1:登录

POST https://wx.gratour.info:7011/v1/login
Content-Type: application/json

{ "userName": "admin", "password": "admin" }

保存 data[0].authTokentoken,并记录 最后 API 调用时间(用于 WebSocket 重连时判断 token 是否仍有效)。见 会话与 token

步骤 2:连接 WebSocket 并订阅通知

WebSocket 地址 由 HTTP 基址派生:

https://wx.gratour.info:7011/v1
→ wss://wx.gratour.info:7011/v1/ws?__token=<authToken>

订阅队列:

/user/<authToken>/queue/strm
function connectWs() {
let url = apiUrlPrefix().replace('https://', 'wss://');
if (!url.endsWith('/v1/')) url += 'v1/';
url += 'ws?__token=' + token;

stomp = Stomp.client(url);
stomp.connect({}, function () {
stomp.subscribe('/user/' + token + '/queue/strm', (frame) => {
const notif = JSON.parse(frame.body);
handleStrmNotif(notif);
});
}, function (err) {
// token 仍有效时可延时重连,见下文
});
}

约定说明:STOMP WebSocket 基本约定

登录成功后立即 connectWs(),且须在 调用 open 之前 完成订阅,以免错过 ready 通知。

重连注意

WebSocket 断线时,仅在 token 仍有效时重连(如距上次 API 调用不足约 10 分钟);否则应先重新 POST /login 并用新 token 建连。

步骤 3:异步打开实时音视频

POST https://wx.gratour.info:7011/v1/strm/live/open
Content-Type: application/json
X-Auth-Token: ...

{
"simNo": "8888000001",
"channel": 1,
"dataType": 0,
"codeStream": 1,
"proto": 0,
"async": true
}

与同步示例相比,必须 增加 "async": true

典型应答(通道尚未被他人打开时):

{
"data": [{
"reqId": "AbctuB9sSJe8bbBzv-yr9g",
"ctrl": true,
"playUrl": "https://...",
"mediaTyp": "av",
"ready": false
}],
"errCode": 0
}
ready含义客户端动作
true通道已有流或已就绪立即 createPlayerAndLoad(playUrl)
false等待终端推流等 StrmNotif act=ready 再播放
axios.post(apiUrlPrefix() + 'strm/live/open', {
simNo, channel, dataType, codeStream,
proto: 0,
async: true
}, { headers: { 'X-Auth-Token': token } })
.then(function (resp) {
let data = apiCheck(resp).data[0];
reqId = data.reqId;
keepAliveTimer = setInterval(apiKeepAlive, 15000);

if (data.ready) {
createPlayerAndLoad(data.playUrl, data.mediaTyp);
}
// ready=false 时,在 handleStrmNotif 中处理
});

步骤 4:处理 StrmNotif 通知

客户端应处理的主要 act 值:

act含义建议处理
sent已下发 9101可选:UI 显示「等待终端…」
failed终端失败 / 不在线提示错误,调用 stop()
ready可播放createPlayerAndLoad(notif.playUrl, notif.mediaTyp)
closed请求已关闭停止播放器与保活
function handleStrmNotif(notif) {
if (notif.reqId !== reqId) return;

switch (notif.act) {
case 'ready':
if (!flvPlayer) {
createPlayerAndLoad(notif.playUrl, notif.mediaTyp);
}
break;
case 'failed':
case 'closed':
stop();
break;
}
}

结构详见 StrmNotif

HTTP-FLV 特殊说明: ready=false 时也可 提前 创建播放器并 load playUrl,播放器会等待码流;本示例选择在 ready 后再创建,逻辑更清晰。

步骤 5:保活

与同步示例相同,打开成功后每 15 秒 调用一次:

POST .../strm/keep_alive
{ "reqIds": ["<reqId>"] }

步骤 6:播放

createPlayerAndLoad()example-1-live 相同:根据 mediaTyp 配置 flv.js,绑定 <video> 元素。

步骤 7:停止播放

function stop() {
clearInterval(keepAliveTimer);
flvPlayer?.destroy();
axios.post(apiUrlPrefix() + 'strm/close', { reqIds: [reqId] }, {
headers: { 'X-Auth-Token': token }
});
reqId = null;
}

异步模式下的两种播放路径

路径 A(通道已被打开,ready=true)
open 返回 → 直接 createPlayerAndLoad

路径 B(常见,ready=false)
open 返回 → 启动保活 → 收到 act=ready → createPlayerAndLoad

路径 B 中若 未订阅 WebSockettoken 与 WS 不一致,将永远等不到 ready,表现为一直黑屏。

检查清单

  • 登录后先 connectWs(),再 open
  • 请求体含 "async": true
  • 订阅地址中的 {token} 与当前 authToken 一致
  • 处理 readyfailedclosed 通知
  • 保活与关闭逻辑与 example-1 一致

常见错误

现象原因
打开成功但永不播放未订阅 WS,或错过 ready
收不到通知WS 的 __token 与 HTTP 请求头 token 不一致
重连后仍异常token 已过期,需重新 login
-27终端不在线

更多:常见问题与排错

下一步

目标文档
更简单单路集成example-1-live
单连接 API + 通知ws-example-1-live
生命周期与状态机音视频请求的生命周期
HTTP vs WS APIHTTP 与 WebSocket API 选型