EasyGBS新内核版本摄像头流量统计为零的优化方案
EasyGBS的部分项目现场是具有摄像头直播流量统计功能的,在某项目中,我们发现EasyGBS通道直播正常的情况下;所有摄像头的直播流量上下行均为零后发现公网也存在此问题。
此问题仅出现在EasyGBS的新内核版本里,因此判断为新内核版本EasyGBS该功能并未实现。查看功能模块代码发现老版本内核的流量统计,是由Go后端定时访问nginx的获取流量统计接口得到数据,新内核丢弃了nginx,这也证实了该功能确实未实现。
resp, err := client.Get(fmt.Sprintf(“http://127.0.0.1:%d/getlivesessions”, GetHTTPPort()))
根据新内核官方API文档,发现新内核也拥有流量统计接口暴露,因此可以通过此接口获取到对应通道的上下行流量信息。
Golang json格式展示:
type AllGroup struct {
ErrorCode int `json:"error_code"`
Desp string `json:"desp"`
Data struct {
Groups []struct {
StreamName string `json:"stream_name"`
AudioCodec string `json:"audio_codec"`
VideoCodec string `json:"video_codec"`
VideoWidth int `json:"video_width"`
VideoHeight int `json:"video_height"`
Pub struct {
Protocol string `json:"protocol"`
SessionId string `json:"session_id"`
RemoteAddr string `json:"remote_addr"`
StartTime string `json:"start_time"`
ReadBytesSum int64 `json:"read_bytes_sum"`
WroteBytesSum int64 `json:"wrote_bytes_sum"`
Bitrate int `json:"bitrate"`
ReadBitrate int `json:"read_bitrate"`
WriteBitrate int `json:"write_bitrate"`
} `json:"pub"`
Subs []struct {
Protocol string `json:"protocol"`
SessionId string `json:"session_id"`
RemoteAddr string `json:"remote_addr"`
StartTime string `json:"start_time"`
ReadBytesSum int64 `json:"read_bytes_sum"`
WroteBytesSum int64 `json:"wrote_bytes_sum"`
Bitrate int `json:"bitrate"`
ReadBitrate int `json:"read_bitrate"`
WriteBitrate int `json:"write_bitrate"`
} `json:"subs"`
Pull struct {
Protocol string `json:"protocol"`
SessionId string `json:"session_id"`
RemoteAddr string `json:"remote_addr"`
StartTime string `json:"start_time"`
ReadBytesSum int64 `json:"read_bytes_sum"`
WroteBytesSum int64 `json:"wrote_bytes_sum"`
Bitrate int `json:"bitrate"`
ReadBitrate int `json:"read_bitrate"`
WriteBitrate int `json:"write_bitrate"`
} `json:"pull"`
} `json:"groups"`
} `json:"data"`
}
部分代码:
func GetLiveSessions(port string) (sessions []*SessionInfo) {
sessions = make([]*SessionInfo, 0)
defer func() {
if p := recover(); p != nil {
log.Println(p)
}
}()
client := http.Client{
Timeout: 3 * time.Second,
}
resp, err := client.Get(fmt.Sprintf("http://127.0.0.1:%s/api/stat/all_group", port))
if err != nil {
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return
}
var allGourp AllGroup
err = json.Unmarshal(body, &allGourp)
if err != nil {
return
}
for _, v := range allGourp.Data.Groups {
strs := strings.Split(v.StreamName, "_")
var worteSum int64
for _, s := range v.Subs {
if s.WroteBytesSum != 0 {
worteSum += s.WroteBytesSum
}
}
if len(strs) < 3 || (v.Pub.ReadBytesSum == 0 && worteSum == 0) {
continue
}
sessions = append(sessions, &SessionInfo{
ID: fmt.Sprintf("%s_%s", strs[0], strs[1]),
InBytes: v.Pub.ReadBytesSum,
OutBytes: worteSum,
})
}
return
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· 地球OL攻略 —— 某应届生求职总结