前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >国标GB28181协议客户端EasyGBS国标视频平台级联EasyNVR:EasyNVR到EasyGBS上是如何注册及注销的?

国标GB28181协议客户端EasyGBS国标视频平台级联EasyNVR:EasyNVR到EasyGBS上是如何注册及注销的?

作者头像
EasyNVR
发布2020-08-25 15:26:10
9590
发布2020-08-25 15:26:10
举报
文章被收录于专栏:EasyNVREasyNVR

我们知道TSINGSEE青犀视频EasyGBS国标平台可以作为上级平台或下级平台,可以与支持国标协议的平台进行级联,上文提到与宇视等平台进行级联(EasyGBS如何实现视频流的向上级联)就是一个很好的案例。其实除了与市面上支持的国标平台做级联,Easy系列产品之间也可以与EasyGBS做级联。最近,有客户需要同时使用EasyGBS和EasyNVR两个平台融合使用,此时我们就可以将EasyNVR接入到EasyGBS中,使其方便管理。

由于文章内容比较多,我们分两块来讲一下这个配置过程。本文详细描述了EasyNVR平台到国标EasyGBS上的注册和注销。

EasyNVR视频监控直播解决方案

EasyGBS国标视频云直播解决方案

EasyGBS采用gb28181协议接入摄像头,我们将EasyNVR当作边缘设备,通过gb28181协议和EasyGBS平台进行对接。

EasyGBS有级联注册到其他EasyGBS的功能,EasyNVR接入到EasyGBS中其实就是将EasyNVR注册到EasyGBS中,我们可以仿照现有的EasyGBS级联注册功能仿写。从EasyGBS中找到级联注册功能那块代码,仿写EasyNVR的代码。此处是EasyNVR与EasyGBS交互的客户端:

代码语言:javascript
复制
func NewClient(cascade Cascade) *Client {
   client := &Client{
      Stoped:        false,
      Cascade:       cascade,
      AckTimeout:    cascade.AckTimeout,
      LocalHost:     cascade.LocalHost,
      LocalPort:     cascade.LocalPort,
      LocalWanIP:    "",
      LocalSerial:   cascade.LocalSerial,
      handleMap:     make(map[string][]HandleFunc),
      dispatcher:    events.NewDispatcher(),
      KeepAliveQuit: make(chan bool, 0),
      RegisterQuit:  make(chan bool, 0),
      DevCache:      cache.New(time.Duration(cascade.KeepaliveTimeout)*time.Second, 10*time.Second),
   }
   return client
}

以上我们已经完成了客户端的配置,接下来就可以启动客户端正式与EasyGBS交互了。

代码语言:javascript
复制
func (c *Client) Run() {
   if c.LocalPort == 0 {
      log.Println("没有可用的UDP级联端口")
      return
   }
   lUdpAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf(":%d", c.LocalPort))
   if err != nil {
      return
   }
   rUdpAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", c.Cascade.Host, c.Cascade.Port))
   if err != nil {
      return
   }
   c.udpConn, err = net.DialUDP("udp", lUdpAddr, rUdpAddr)
   if err != nil {
      log.Printf("uac start error:%v", err)
      return
   }
   if e := c.udpConn.SetReadBuffer(UDP_BUF_SIZE); e != nil {
      log.Printf("sip udp set connection read buffer[%d] error, %v", UDP_BUF_SIZE, e)
   }
   if e := c.udpConn.SetWriteBuffer(UDP_BUF_SIZE); e != nil {
      log.Printf("sip udp set connection write buffer[%d] error, %v", UDP_BUF_SIZE, e)
   }
   defer c.udpConn.Close()
   c.Transport = c.NewUDPTransport(rUdpAddr, c.udpConn)
   go c.Register(false)
   log.Printf("uac start ok:%s", c.udpConn.LocalAddr().String())
   c.Stoped = false
   c.Handle("MESSAGE", HandleMessage)
   c.Handle("INVITE", HandleInvite)
   c.Handle("BYE", HandleBye)
   c.Handle("INFO", HandleInfo)
   for !c.Stoped {
      bufUDP := make([]byte, UDP_BUF_SIZE)
      n, _, err := c.udpConn.ReadFromUDP(bufUDP)
      if err != nil {
         log.Printf("udp read error, %v", err)
         continue
      }
      sipBuf := bufUDP[:n]
      sipRaw := string(sipBuf)
      sipMsg := siprocket.Parse(sipBuf)
      statusCode := string(sipMsg.Req.StatusCode)
      contentLen, _ := strconv.Atoi(string(sipMsg.ContLen.Value))
      header := sipRaw[:len(sipRaw)-contentLen]
      body := sipRaw[len(sipRaw)-contentLen:]
      Logf("级联消息:[%s]<<<<<<[%s]<<<<<<\r\n%v", c.udpConn.LocalAddr().String(), c.udpConn.RemoteAddr().String(), sipRaw)
      if statusCode == "" { // request
         req, err := UnmarshalRequest(header, body)
         if err != nil {
            log.Printf("unmarshal request failed, %v", err)
            continue
         }
         req.FixVia(c.Transport)
         c.HandleRequest(req, &sipMsg)
      } else { // response
         res, err := UnmarshalResponse(header, body)
         if err != nil {
            log.Printf("unmarshal response failed, %v", err)
            continue
         }
         callid := res.HeaderMap["Call-ID"]
         cseq := res.HeaderMap["CSeq"]
         c.dispatcher.Dispatch(fmt.Sprintf("%s:%s", callid, cseq), res)
      }
   }
}

上面两段代码都是实现EasyNVR注册到EasyGBS中,然后就需要将其整合到一起。

代码语言:javascript
复制
func Start() {
   cascade := GetGbsConfig()
   if cascade.Enable != 0 {
      client = NewClient(cascade)
      go client.Run()
   }
   return
}
 
func Stop() {
   if client != nil {
      if !client.Stoped {
         client.Stoped = true
         client.RegisterQuit <- true
         client.KeepAliveQuit <- true
      }
      client = nil
      log.Println("级联stop")
   }
}

实现后效果如下:

这个设备就是虚拟构造的EasyNVR设备。我们接入的是16通道的EasyNVR,所以此处应该显示16个通道,然而现在注册上来并没有显示通道,所以我们还需要继续配置EasyGBS级联调阅EasyNVR的通道列表:EasyGBS如何实现调阅EasyNVR的视频通道。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-08-24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • EasyNVR视频监控直播解决方案
  • EasyGBS国标视频云直播解决方案
相关产品与服务
云直播
云直播(Cloud Streaming Services,CSS)为您提供极速、稳定、专业的云端直播处理服务,根据业务的不同直播场景需求,云直播提供了标准直播、快直播、云导播台三种服务,分别针对大规模实时观看、超低延时直播、便捷云端导播的场景,配合腾讯云视立方·直播 SDK,为您提供一站式的音视频直播解决方案。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档