106 lines
3.0 KiB
Markdown
106 lines
3.0 KiB
Markdown
# 直播状态自动重置问题诊断
|
||
|
||
## 问题描述
|
||
OBS推流后,直播间 `is_live` 状态会被不断重置为 0。
|
||
|
||
## 可能原因
|
||
|
||
### 1. SRS 的 `on_unpublish` 回调被触发
|
||
当 SRS 检测到推流断开时,会调用 `on_unpublish` 回调,将 `is_live` 设置为 0。
|
||
|
||
**可能的触发原因:**
|
||
- OBS 推流不稳定,频繁断开重连
|
||
- SRS 配置的超时时间太短
|
||
- 网络问题导致 SRS 认为推流已断开
|
||
|
||
### 2. Node.js 服务的 `donePublish` 事件
|
||
Node.js 的 NodeMediaServer 也会监听推流状态,当检测到推流结束时会调用 `roomStore.setLiveStatus(streamKey, false)`。
|
||
|
||
## 排查步骤
|
||
|
||
### 步骤1:检查 Node.js 服务日志
|
||
在服务器上查看 live-streaming 服务的日志:
|
||
```bash
|
||
# 如果使用 Docker
|
||
docker logs live-streaming-api-1 --tail 100 -f
|
||
|
||
# 如果直接运行
|
||
pm2 logs live-streaming
|
||
```
|
||
|
||
看是否有以下日志:
|
||
- `[SRS] 推流开始: stream=xxx`
|
||
- `[SRS] 推流结束: stream=xxx`
|
||
|
||
### 步骤2:检查 Java 后端日志
|
||
查看 Java 后端是否收到 SRS 回调:
|
||
```bash
|
||
# 查看后端日志
|
||
tail -f /path/to/java-backend/logs/xxx.log
|
||
```
|
||
|
||
看是否有:
|
||
- `[SRS] 推流开始: stream=xxx`
|
||
- `[SRS] 推流结束: stream=xxx`
|
||
|
||
### 步骤3:检查 SRS 配置
|
||
查看 SRS 是否配置了正确的回调地址:
|
||
```bash
|
||
# 查看 SRS 配置
|
||
cat /path/to/srs/conf/srs.conf
|
||
```
|
||
|
||
应该有类似配置:
|
||
```
|
||
vhost __defaultVhost__ {
|
||
http_hooks {
|
||
enabled on;
|
||
on_publish http://localhost:3001/api/srs/on_publish;
|
||
on_unpublish http://localhost:3001/api/srs/on_unpublish;
|
||
}
|
||
}
|
||
```
|
||
|
||
### 步骤4:检查 OBS 推流状态
|
||
确认 OBS 推流是否稳定:
|
||
1. 查看 OBS 底部状态栏的 "丢帧" 和 "比特率"
|
||
2. 如果频繁丢帧或比特率波动大,可能导致推流不稳定
|
||
|
||
## 临时解决方案
|
||
|
||
### 方案1:禁用 on_unpublish 回调
|
||
修改 `live-streaming/server/routes/srs.js`,注释掉 `on_unpublish` 的数据库更新:
|
||
|
||
```javascript
|
||
router.post('/on_unpublish', (req, res) => {
|
||
const { app, stream } = req.body;
|
||
console.log(`[SRS] 推流结束: app=${app}, stream=${stream}`);
|
||
|
||
// 暂时禁用自动关闭直播
|
||
// const room = roomStore.setLiveStatus(stream, false);
|
||
// forwardToJava('/api/front/live/srs/on_unpublish', { stream });
|
||
|
||
res.json({ code: 0 });
|
||
});
|
||
```
|
||
|
||
### 方案2:禁用 NodeMediaServer 的 donePublish 事件
|
||
修改 `live-streaming/server/index.js`,注释掉 `donePublish` 事件:
|
||
|
||
```javascript
|
||
// nms.on('donePublish', (id, streamPath) => {
|
||
// const parts = String(streamPath || '').split('/').filter(Boolean);
|
||
// const streamKey = parts[1];
|
||
// if (streamKey) roomStore.setLiveStatus(streamKey, false);
|
||
// });
|
||
```
|
||
|
||
### 方案3:手动控制直播状态
|
||
不依赖推流回调,改为主播手动点击"开始直播"和"结束直播"按钮来控制状态。
|
||
|
||
## 推荐方案
|
||
|
||
**建议先执行方案1和方案2**,禁用自动关闭直播的逻辑,然后观察是否还会自动重置。
|
||
|
||
如果问题解决,说明是 SRS 或 NodeMediaServer 的回调导致的,需要进一步排查为什么会频繁触发 unpublish 事件。
|