zhibo/diagnose_live_status_issue.md

106 lines
3.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 直播状态自动重置问题诊断
## 问题描述
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 事件。