JT1078轉GB28181流程
項目地址:
JT1078轉GB28181的流媒體服務器: https://github.com/lkmio/lkm
JT1078轉GB28181的信令服務器: https://github.com/lkmio/gb-cms
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/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/lkmio","model": "gb-cms","owner": "github/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再轉發到國標流媒體服務器。鉤子示例如下:
t.Run("hook_on_invite", func(t *testing.T) {// 創建http serverrouter := 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)}})