实时播放示例 (异步 HTTP API)
本示例在 同步示例 基础上增加 异步打开 与 STOMP WebSocket 通知,适合需要 多路播放、打开接口快速返回 的场景。客户端协议仍为 HTTP-FLV(proto: 0)。
| 项目 | 说明 |
|---|---|
| 示例页面 | live-example-flv-3 |
| 示例代码 | live-example-flv-3.zip |
| API 基址 | https://wx.gratour.info:7011/v1 |
| 依赖库 | axios、mpegts.js、stomp-websocket |
| 测试终端 | 模拟终端 8888000001(演示站可用) |
相关文档:应用指南概览 · 异步与同步模式 · StrmNotif 通知结构
适合场景
- 同一页面 多路 实时预览,不宜长时间阻塞在
open接口 - 需要在终端推流前就拿到
reqId,便于随时 取消 尚未就绪的请求 - 可接受维护 HTTP API + STOMP WebSocket 双连接
若只需单路、逻辑尽量简单,请先用 example-1-live。新应用也可考虑 WebSocket API 示例,避免 STOMP 与 token 双管理。
与同步示例的差异
| 同步(example-1) | 异步(本示例) | |
|---|---|---|
async | 省略 / false | true |
| 打开返回时 | 通常已可播放 | 通常 ready: false |
| WebSocket | 不需要 | 必须 订阅 StrmNotif |
| 何时创建播放器 | open 返回后立即 | ready: true 或收到 act=ready 通知 |
| HTTP 基址 | :7200 | :7011(演示环境) |
整体流程

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 在线。

步骤详解
步骤 1:登录
POST https://wx.gratour.info:7011/v1/login
Content-Type: application/json
{ "userName": "admin", "password": "admin" }
保存 data[0].authToken 为 token,并记录 最后 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 中若 未订阅 WebSocket 或 token 与 WS 不一致,将永远等不到 ready,表现为一直黑屏。
检查清单
- 登录后先
connectWs(),再open - 请求体含
"async": true - 订阅地址中的
{token}与当前authToken一致 - 处理
ready、failed、closed通知 - 保活与关闭逻辑与 example-1 一致
常见错误
| 现象 | 原因 |
|---|---|
| 打开成功但永不播放 | 未订阅 WS,或错过 ready |
| 收不到通知 | WS 的 __token 与 HTTP 请求头 token 不一致 |
| 重连后仍异常 | token 已过期,需重新 login |
-27 | 终端不在线 |
更多:常见问题与排错
下一步
| 目标 | 文档 |
|---|---|
| 更简单单路集成 | example-1-live |
| 单连接 API + 通知 | ws-example-1-live |
| 生命周期与状态机 | 音视频请求的生命周期 |
| HTTP vs WS API | HTTP 与 WebSocket API 选型 |