随笔 - 936  文章 - 0  评论 - 3  阅读 - 30万

国标GB28181协议客户端EasyGBS如何实现调阅EasyNVR视频平台的视频?

很多用户反应EasyGBS的级联功能十分便捷,EasyGBS除了能够级联海康这样的视频平台,也能够级联用户自己的第三方平台,此外也可以与我们其他的视频平台,比如EasyNVR进行级联。EasyNVR级联注册到EasyGBS上之后,通过EasyGBS已经可以看到EasyNVR的通道信息,也就能通过EasyGBS进行观看EasyNVR通道的直播。

EasyNVR直播原理是通过EasyNVR的拉流库对EasyNVR通道配置的RTSP地址进行拉流,然后通过EasyNVR推流库进行推流,推到nginx里面,然后通过地址就可以观看直播。

EasyGBS直播原理(级联)是先通过GB28181协议发送给级联客户端,然后进行udp或tcp通道传输RTP包,存到nginx里面,然后通过地址就可以观看直播。

EasyGBS是如何实现调阅EasyNVR的视频流的?由于两者的直播原理不同,我们就想到在EasyNVR拉流库获取裸流然后通过推流库推到nginx的地方添加一个逻辑,如果EasyNVR有级联到EasyGBS上面,就多推一份视频流到EasyGBS上。

1
2
3
4
if client.CascadeSink != nil {
   //log.Printf("----------------------------codec:%d", int(frameInfo.codec))
   client.CascadeSink.SendRTMP(avFrame, int(frameInfo.codec))
}

  此处的frameInfo.codec是判断视频格式是H.264还是H.265的。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
func (obj *SinkUDP) SendRTMP(avFrame *C.EASY_AV_Frame, codec int) (err error) {
   defer func() {
      if err := recover(); err != nil {
         fmt.Sprintf("%s\n", err)
         fmt.Sprintln(string(debug.Stack()))
      }
   }()
   //avFrame := (*C.EASY_AV_Frame)(unsafe.Pointer(data))
   if avFrame.u32AVFrameFlag == C.EASY_SDK_VIDEO_FRAME_FLAG {
      resbuf := make([]byte, int(avFrame.u32AVFrameLen))
      copy(resbuf, (*[1 << 32]byte)(unsafe.Pointer(avFrame.pBuffer))[:int(avFrame.u32AVFrameLen)])
      if avFrame.u32VFrameType == C.EASY_SDK_VIDEO_FRAME_I {
         out, _ := ps.ConvertEs2Rtp(resbuf, 0, codec, true, &obj.rtpInfo)
         for _, v := range out {
            _, err := obj.DataConn.Write(v.Payload)
            if err != nil {
               //log.Println(err.Error())
            }
         }
      } else {
         out, _ := ps.ConvertEs2Rtp(resbuf, 0, codec, false, &obj.rtpInfo)
         for _, v := range out {
            _, err := obj.DataConn.Write(v.Payload)
            if err != nil {
               //log.Println(err.Error())
            }
         }
      }
   } else {
      resbuf := (*[1 << 32]byte)(unsafe.Pointer(avFrame.pBuffer))[:int(avFrame.u32AVFrameLen)]
      out, _ := ps.ConvertEs2Rtp(resbuf, 1, codec, false, &obj.rtpInfo)
      for _, v := range out {
         _, err := obj.DataConn.Write(v.Payload)
         if err != nil {
            //log.Println(err.Error())
         }
      }
   }
   return
}

  

将拉流库获取到的裸流进行一层RTP封包,然后就通过udp或tcp传输到EasyGBS的nginx里面,之后EasyGBS就可以观看EasyNVR的通道直播了。

关于EasyGBS的级联,有兴趣的朋友可以阅读下EasyGBS级联接入下级宇视平台以及海康平台上进行级联配置步骤。如有疑问,欢迎和我们一起探讨。此外,视频相关解决方案均可访问TSINGSEE青犀视频,可以联系我们获取演示方案,直观感受,也可自行进行下载及测试。

posted on   EasyGBS  阅读(275)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· 地球OL攻略 —— 某应届生求职总结
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示