mirror of
https://github.com/lkmio/gb-cms.git
synced 2026-04-22 23:17:22 +08:00
147 lines
4.1 KiB
Markdown
147 lines
4.1 KiB
Markdown
## 简介
|
|
基于Go语言实现的GB28181信令服务器, 支持常见的GB功能, 以及JT1078转GB28181等功能。API适配LiveGBS开源的前端项目, 运行效果如下:
|
|
|
|
<img width="2518" height="1054" alt="image" src="https://github.com/user-attachments/assets/6c732800-36a7-41c7-be49-92f65b9c2f02" />
|
|
|
|
|
|
<img width="2518" height="1054" alt="image" src="https://github.com/user-attachments/assets/a92d4b26-6e64-437a-944e-0e1f28d113d7" />
|
|
|
|
## 安装使用
|
|
1. 运行lkm流媒体程序, 注意需要[开启http hook](https://github.com/lkmio/lkm/blob/7150525c205d209925b3c88a9dcf0a437a31cbc0/config.json#L58);
|
|
2. gb-cms[配置流媒体接口地址](https://github.com/lkmio/gb-cms/blob/b933857d3d7a7178314b58762a7eebafde2d8fc7/config.json#L12), 对应lkm的[http参数项](https://github.com/lkmio/lkm/blob/7150525c205d209925b3c88a9dcf0a437a31cbc0/config.json#L13);
|
|
3. 运行gb-cms, 浏览器打开http://localhost:9000
|
|
|
|
## JT1078转GB28181流程
|
|
|
|
### 1. 创建GB28181 UA
|
|
调用接口: http://localhost:9000/api/v1/jt/device/add 请求体如下:
|
|
|
|
```
|
|
{
|
|
"username": "34020000001400000001",
|
|
"server_id": "34020000002000000001",
|
|
"server_addr": "192.168.31.112:15060",
|
|
"transport": "udp",
|
|
"password": "12345678",
|
|
"register_expires": 3600,
|
|
"keepalive_interval": 60,
|
|
"name": "模拟1078设备4",
|
|
"sim_number":"13800138000",
|
|
"manufacturer":"github.com/lkmio",
|
|
"model":"gb-cms",
|
|
"firmware":"dev"
|
|
}
|
|
|
|
```
|
|
|
|
username: 自定义国标设备ID, 唯一键
|
|
|
|
sim_number: 对应的部标设备sim卡号, 唯一键
|
|
|
|
|
|
### 2. 添加视频通道
|
|
|
|
调用接口: http://localhost:9000/api/v1/jt/channel/add 请求体如下:
|
|
|
|
```
|
|
{
|
|
"root_id": "34020000001400000001",
|
|
"device_id": "34020000001310000001",
|
|
"name": "视频通道",
|
|
"manufacturer": "github.com/lkmio",
|
|
"model": "gb-cms",
|
|
"owner": "github.com/lkmio",
|
|
"channel_number": 1
|
|
}
|
|
|
|
```
|
|
|
|
root_id: 创建GB28181 UA接口的username
|
|
|
|
device_id: 自定义国标视频通道ID
|
|
|
|
channel_number: 国标视频通道ID对应的1078视频通道号
|
|
|
|
### 3. 实现invite钩子
|
|
|
|
```
|
|
{
|
|
"sip_port": 5060,
|
|
"http_port": 9000,
|
|
"listen_ip": "0.0.0.0",
|
|
"public_ip": "192.168.31.112",
|
|
|
|
"sip_id":"34020000002000000001",
|
|
"password":"123456",
|
|
"alive_expires": 180,
|
|
"mobile_position_interval": 10,
|
|
|
|
"media_server": "0.0.0.0:8080",
|
|
|
|
"?auto_close_on_idle": "拉流空闲时, 立即关闭流",
|
|
"auto_close_on_idle": true,
|
|
|
|
"hooks": {
|
|
"?online": "设备上线通知",
|
|
"online": "",
|
|
|
|
"?offline": "设备下线通知",
|
|
"offline": "",
|
|
|
|
"?position" : "设备位置通知",
|
|
"position": "",
|
|
|
|
"?on_invite": "被邀请, 用于通知1078信令服务器, 向设备下发推流指令",
|
|
"on_invite": "http://localhost:8081/api/v1/jt1078/on_invite",
|
|
|
|
"?on_answer": "被查询录像,用于通知1078信令服务器",
|
|
"on_query_record": ""
|
|
}
|
|
}
|
|
|
|
```
|
|
|
|
用户自行实现`on_invite`钩子, 当上级国标服务器预览部标设备时, 会通过`on_invite`钩子, 通知部标信令服务器。此时部标信令服务器, 向设备下发请求视频信令,推流到lkm收流端口, lkm再转发到国标流媒体服务器。[钩子示例如下](https://github.com/lkmio/lkm/blob/02689f5e09b1f2ffccf26aad62e7b930e30aeafe/jt1078/jt_test.go#L210):
|
|
|
|
```
|
|
t.Run("hook_on_invite", func(t *testing.T) {
|
|
// 创建http server
|
|
router := mux.NewRouter()
|
|
|
|
// 示例路由
|
|
router.HandleFunc("/api/v1/jt1078/on_invite", func(w http.ResponseWriter, r *http.Request) {
|
|
v := struct {
|
|
SimNumber string `json:"sim_number,omitempty"`
|
|
ChannelNumber string `json:"channel_number,omitempty"`
|
|
}{}
|
|
|
|
// 读取请求体
|
|
bytes := make([]byte, 1024)
|
|
n, err := r.Body.Read(bytes)
|
|
if n < 1 {
|
|
panic(err)
|
|
}
|
|
err = json.Unmarshal(bytes[:n], &v)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Printf("on_invite sim_number: %s, channel_number: %s\r\n", v.SimNumber, v.ChannelNumber)
|
|
w.WriteHeader(http.StatusOK)
|
|
go publish()
|
|
})
|
|
|
|
server := &http.Server{
|
|
Addr: "localhost:8081",
|
|
Handler: router,
|
|
WriteTimeout: 15 * time.Second,
|
|
ReadTimeout: 15 * time.Second,
|
|
}
|
|
|
|
err := server.ListenAndServe()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
})
|
|
```
|