pingos(nginx-rtmp-module)获取实时直播数据
转载请注明出处:https://blog.csdn.net/impingo
我的开源项目地址:https://github.com/pingostack/pingos
开源项目:https://pingos.io
QQ交流群:193611565
QQ交流二群:193611565
QQ交流一群(已满):697773082
描述
nginx-rtmp-module模块里有个rtmp_stat配置,该功能可以允许用户通过http接口获取单个worker进程上的正在直播的rtmp推拉流连接和对应的流量。
但是这个功能有很大的缺陷:
- 有多个worker进程的情况下,每次请求只能随机获取到其中一个worker进程的流信息。
- 通过这个接口只能统计到rtmp连接的信息,对于pingos项目里的http-flv、http-ts、hls+等协议的连接是无法统计到的。
1. pingos中的解决方案
先看pingos中的配置:
location /sys_stat {
sys_stat;
}
location /sys_stat_proxy/ {
rewrite ^/proxy/(.*) /sys_stat break;
proxy_pass http://$1:;
}
location /bs {
broadcast unix:/tmp/http /sys_stat_proxy;
broadcast_rewrite_prefix " " [;
broadcast_suffix ];
}
-
sys_stat配置
该功能是通过http接口把当前worker进程的直播流信息以json的格式返回,其中包含详细的流量、带宽、并发信息,但是这样操作跟原生的rtmp_stat一样存在致命缺陷,不能获取全局的信息。 -
broadcast配置
该功能是将请求广播给所有的worker进程,然后将多个worker进程返回的json数据汇总。
2. APP列表和流列表
-
Get请求 URL:
http(s)://ip:port/bs
-
返回JSON内容的结构是:worker进程
们
-> live_stream -> serverid -> appid -> stream -> publish会话和play会话
也就是说通过这个接口你将获取到一个数据,其中每个节点元素都是对应一个worker进程上的数据。
json最外层的整体结构例如:
[ {worker0}, {worker1}, {worker3} ... ]
2.1 worker
结构
{
"ngx_worker": 0,
"ngx_process_slot": 0,
"ngx_pid": 29809,
"live_stream": { ... }
}
字段 | 类型 | 描述 |
---|---|---|
ngx_worker | int | worker进程的编号 |
ngx_process_slot | int | worker进程指针在master进程数组里的下标 |
ngx_pid | int | worker进程id |
live_stream | json object | 直播流列表 |
2.2 live_stream
结构
{
"server_version": "1.17.5",
"compiler": "gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) ",
"built": "Apr 11 2021",
"pid": 29809,
"timestamp": 1618637886,
"naccepted": 178,
"in": {
"bw": 3764096,
"bytes": 3421950282
},
"out": {
"bw": 4984816,
"bytes": 3643226942
},
"server_array": [ ... ]
}
字段 | 类型 | 描述 |
---|---|---|
server_version | string | 服务器版本 |
compiler | string | 编译器版本 |
built | string | 编译日期 |
pid | string | 线程id |
timestamp | time | 当前请求时候的系统时间 |
naccepted | int | 当前进程接收到的请求总数 |
in | object | 当前worker进程的网络入流情况 |
out | object | 当前worker进程的网络出流情况 |
bw | int | 当前worker进程的带宽(注意:是当前一个worker进程,而且全部worker进程;在in里就是入网带宽,在out里就是出网带宽) |
bytes | int | 从该worker进程开启到目前为止的流量总和 |
server_array | json array | 以serverid为索引的不同serverid下的流状态信息 |
2.3 server_array
结构
{
"serverid": "112.121.178.154",
"total_clients": 1,
"rtmp_clients": 1,
"flv_clients": 0,
"hls_clients": 0,
"ts_clients": 0,
"stream_array": [ ... ]
}
字段 | 类型 | 描述 |
---|---|---|
serverid | string | serverid |
total_clients | int | 当前时刻下的worker进程下的serverid下的所有客户端连接了 |
rtmp_clients | int | rtmp客户端的连接量 |
flv_clients | int | http-flv客户端的连接量 |
hls_clients | int | hls+客户端的连接量(注意,只能统计hls+的连接量,普通hls无法被统计) |
ts_clients | int | http-ts客户端的连接量 |
stream_array | json array | 在线流列表 |
2.4 stream_array
结构
{
"name": "112.121.178.154/live/111",
"time": 102641,
"in": {
"bw": 3677064,
"bytes": 30479426
},
"video_in": {
"bw": 3295320,
"bytes": 26164007
},
"audio_in": {
"bw": 376040,
"bytes": 4251276
},
"out": {
"bw": 4836912,
"bytes": 42234918
},
"meta": {
"video": {
"width": 1920,
"height": 1080,
"frame_rate": "24.0",
"codec": "H264",
"profile": "High",
"compat": "4.0"
},
"audio": {
"codec": "AAC",
"profile": "LC",
"channels": 6,
"sample_rate": 48000
}
},
"total_clients": 1,
"rtmp_clients": 1,
"flv_clients": 0,
"hls_clients": 0,
"ts_clients": 0,
"active": true,
"client_array": [ ... ]
}
字段 | 类型 | 描述 |
---|---|---|
name | string | serverid/app/流名 的组合 |
time | int | 流存在的时长 |
in | json object | 这条流在这个worker进程上的入网网络情况 |
out | json object | 这条流在这个worker进程上的出网网络情况 |
video_in | json object | 这条流的视频在这个worker进程上的入网网络情况 |
audio_in | json object | 这条流的音频在这个worker进程上的入网网络情况 |
meta | json object | 这条流的音视频信息 |
total_clients | int | 这条流在这个worker进程上的所有客户端连接量 |
rtmp_clients | int | 这条流在这个worker进程上的所有rtmp客户端连接量 |
flv_clients | int | 这条流在这个worker进程上的所有http-flv客户端连接量 |
hls_clients | int | 这条流在这个worker进程上的所有hls+客户端连接量 |
ts_clients | int | 这条流在这个worker进程上的所有http-ts客户端连接量 |
active | bool | 这条流在这个worker进程上是否处于激活状态 |
client_array | json object | 这条流在这个worker进程上的所有客户端连接列表 |
2.5 client_array
结构
[
{
"id": 430680,
"address": "0.0.0.0:1935",
"remote_address": "101.228.192.22",
"time": 82155,
"flashver": "LNX 9,0,124,2",
"dropped": 0,
"avsync": 4294967284,
"timestamp": 0,
"active": true,
"publishing": false,
"relay": false,
"interprocess": false,
"protocol": "rtmp"
}, {
"id": 0,
"address": "0.0.0.0:1935",
"remote_address": "",
"time": 102638,
"flashver": "FMLE/3.0 (compatible; Lavf58.77.100)",
"dropped": 0,
"avsync": 4294967284,
"timestamp": 0,
"active": true,
"publishing": false,
"relay": true,
"interprocess": false,
"protocol": "rtmp"
}, {
"id": 430653,
"address": "0.0.0.0:1935",
"remote_address": "101.228.192.22",
"time": 102917,
"flashver": "FMLE/3.0 (compatible; Lavf58.77.100)",
"dropped": 0,
"avsync": 4294967284,
"timestamp": 102666,
"active": true,
"publishing": true,
"relay": false,
"interprocess": false,
"protocol": "rtmp"
}
]
字段 | 类型 | 描述 |
---|---|---|
id | int | 客户端id |
address | string | 该链接对应的服务器端监听的ip和端口 |
remote_address | string | 客户端的公网ip |
time | int | 客户端的连接时长 |
flashvar | string | 如果是rtmp连接,则展示客户端的版本 |
dropped | int | 丢包量 |
avsync | int | 音视频时间戳差值(单位毫秒) |
timestamp | int | 媒体数据时间戳(毫秒) |
active | bool | 客户端是否被激活 |
publishing | bool | 是否为推流连接 |
relay | bool | 是否为转发连接(如push、pull连接) |
interprocess | bool | 是否为进程间回源连接 |
protocol | string | 客户端使用的协议(rtmp、flv、ts、hls等) |
2.6 完整的返回demo
[{
"ngx_worker": 0,
"ngx_process_slot": 0,
"ngx_pid": 29809,
"live_stream": {
"server_version": "1.17.5",
"compiler": "gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) ",
"built": "Apr 11 2021",
"pid": 29809,
"timestamp": 1618637886,
"naccepted": 178,
"in": {
"bw": 3764096,
"bytes": 3421950282
},
"out": {
"bw": 4984816,
"bytes": 3643226942
},
"server_array": [{
"serverid": "112.121.178.154",
"stream_array": [{
"name": "112.121.178.154/live/111",
"time": 102641,
"in": {
"bw": 3677064,
"bytes": 30479426
},
"video_in": {
"bw": 3295320,
"bytes": 26164007
},
"audio_in": {
"bw": 376040,
"bytes": 4251276
},
"out": {
"bw": 4836912,
"bytes": 42234918
},
"client_array": [{
"id": 430680,
"address": "0.0.0.0:1935",
"remote_address": "101.228.192.22",
"time": 82155,
"flashver": "LNX 9,0,124,2",
"dropped": 0,
"avsync": 4294967284,
"timestamp": 0,
"active": true,
"publishing": false,
"relay": false,
"interprocess": false,
"protocol": "rtmp"
}, {
"id": 0,
"address": "0.0.0.0:1935",
"remote_address": "",
"time": 102638,
"flashver": "FMLE/3.0 (compatible; Lavf58.77.100)",
"dropped": 0,
"avsync": 4294967284,
"timestamp": 0,
"active": true,
"publishing": false,
"relay": true,
"interprocess": false,
"protocol": "rtmp"
}, {
"id": 430653,
"address": "0.0.0.0:1935",
"remote_address": "101.228.192.22",
"time": 102917,
"flashver": "FMLE/3.0 (compatible; Lavf58.77.100)",
"dropped": 0,
"avsync": 4294967284,
"timestamp": 102666,
"active": true,
"publishing": true,
"relay": false,
"interprocess": false,
"protocol": "rtmp"
}],
"meta": {
"video": {
"width": 1920,
"height": 1080,
"frame_rate": "24.0",
"codec": "H264",
"profile": "High",
"compat": "4.0"
},
"audio": {
"codec": "AAC",
"profile": "LC",
"channels": 6,
"sample_rate": 48000
}
},
"total_clients": 1,
"rtmp_clients": 1,
"flv_clients": 0,
"hls_clients": 0,
"ts_clients": 0,
"active": true
}],
"total_clients": 1,
"rtmp_clients": 1,
"flv_clients": 0,
"hls_clients": 0,
"ts_clients": 0
}]
}
}]