main.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. package gb28181
  2. import (
  3. "os"
  4. "strings"
  5. "sync"
  6. "time"
  7. //"fmt"
  8. "github.com/ghettovoice/gosip/sip"
  9. myip "github.com/husanpao/ip"
  10. "go.uber.org/zap"
  11. . "m7s.live/engine/v4"
  12. "m7s.live/engine/v4/util"
  13. )
  14. type GB28181PositionConfig struct {
  15. AutosubPosition bool `desc:"是否自动订阅定位"` //是否自动订阅定位
  16. Expires time.Duration `default:"3600s" desc:"订阅周期"` //订阅周期
  17. Interval time.Duration `default:"6s" desc:"订阅间隔"` //订阅间隔
  18. }
  19. type GB28181Config struct {
  20. SipId int64 `desc:"sip服务器id,在库里面的id"`
  21. InviteMode int `default:"1" desc:"拉流模式" enum:"0:手动拉流,1:预拉流,2:按需拉流"` //邀请模式,0:手动拉流,1:预拉流,2:按需拉流
  22. InviteIDs string `default:"131,132" desc:"允许邀请的设备类型( 11~13位是设备类型编码),逗号分割"` //按照国标gb28181协议允许邀请的设备类型:132 摄像机 NVR
  23. ListenAddr string `default:"0.0.0.0" desc:"监听IP地址"` //监听地址
  24. //sip服务器的配置
  25. SipNetwork string `default:"udp" desc:"废弃,请使用 Port"` //传输协议,默认UDP,可选TCP
  26. SipIP string `desc:"sip 服务IP地址"` //sip 服务器公网IP
  27. SipPort sip.Port `default:"5060" desc:"废弃,请使用 Port"` //sip 服务器端口,默认 5060
  28. Serial string `default:"34020000002000000001" desc:"sip 服务 id"` //sip 服务器 id, 默认 34020000002000000001
  29. Realm string `default:"3402000000" desc:"sip 服务域"` //sip 服务器域,默认 3402000000
  30. Username string `desc:"sip 服务账号"` //sip 服务器账号
  31. Password string `desc:"sip 服务密码"` //sip 服务器密码
  32. Port struct { // 新配置方式
  33. Sip string `default:"udp:5060" desc:"sip服务端口号"`
  34. Media string `default:"tcp:58200-59200" desc:"媒体服务端口号"`
  35. }
  36. RegisterValidity time.Duration `default:"3600s" desc:"注册有效期"` //注册有效期,单位秒,默认 3600
  37. HeartbeatInterval time.Duration `default:"60s" desc:"心跳间隔"` //心跳间隔,单位秒,默认 60
  38. //媒体服务器配置
  39. MediaIP string `desc:"媒体服务IP地址"` //媒体服务器地址
  40. MediaPort uint16 `default:"58200" desc:"废弃,请使用 Port"` //媒体服务器端口
  41. MediaNetwork string `default:"tcp" desc:"废弃,请使用 Port"` //媒体传输协议,默认UDP,可选TCP
  42. MediaPortMin uint16 `default:"58200" desc:"废弃,请使用 Port"`
  43. MediaPortMax uint16 `default:"59200" desc:"废弃,请使用 Port"`
  44. RemoveBanInterval time.Duration `default:"600s" desc:"移除禁止设备间隔"` //移除禁止设备间隔
  45. routes map[string]string
  46. DumpPath string `desc:"dump PS流本地文件路径"` //dump PS流本地文件路径
  47. Ignores []string `desc:"忽略的设备ID"` //忽略的设备ID
  48. ignores map[string]struct{}
  49. tcpPorts PortManager
  50. udpPorts PortManager
  51. Position GB28181PositionConfig //关于定位的配置参数
  52. }
  53. var SipUri *sip.SipUri
  54. func (c *GB28181Config) initRoutes() {
  55. c.routes = make(map[string]string)
  56. tempIps := myip.LocalAndInternalIPs()
  57. for k, v := range tempIps {
  58. c.routes[k] = v
  59. if lastdot := strings.LastIndex(k, "."); lastdot >= 0 {
  60. c.routes[k[0:lastdot]] = k
  61. }
  62. }
  63. GB28181Plugin.Info("LocalAndInternalIPs", zap.Any("routes", c.routes))
  64. }
  65. func (c *GB28181Config) OnEvent(event any) {
  66. //fmt.Println("FIRST 111111111111111111111111111")
  67. switch e := event.(type) {
  68. case FirstConfig:
  69. // fmt.Println("FIRST 111111111111111111111111111")
  70. if c.Port.Sip != "udp:5060" {
  71. protocol, ports := util.Conf2Listener(c.Port.Sip)
  72. c.SipNetwork = protocol
  73. c.SipPort = sip.Port(ports[0])
  74. }
  75. if c.Port.Media != "tcp:58200-59200" {
  76. protocol, ports := util.Conf2Listener(c.Port.Media)
  77. c.MediaNetwork = protocol
  78. if len(ports) > 1 {
  79. c.MediaPortMin = ports[0]
  80. c.MediaPortMax = ports[1]
  81. } else {
  82. c.MediaPortMin = 0
  83. c.MediaPortMax = 0
  84. c.MediaPort = ports[0]
  85. }
  86. }
  87. if len(c.Ignores) > 0 {
  88. c.ignores = make(map[string]struct{})
  89. for _, v := range c.Ignores {
  90. c.ignores[v] = util.Null
  91. }
  92. }
  93. // 重启服务将所有设备都离线
  94. //SetAllDeviceOffline()
  95. os.MkdirAll(c.DumpPath, 0766)
  96. c.ReadDevices()
  97. SipUri = &sip.SipUri{
  98. FUser: sip.String{Str: c.Serial},
  99. FHost: c.SipIP,
  100. FPort: &conf.SipPort,
  101. }
  102. go c.initRoutes()
  103. c.startServer()
  104. //fmt.Println("11111111111111111111111111111111111111",EngineConfig.Engine.RebootCacheTime)
  105. case InvitePublish:
  106. //fmt.Println("INVITE PUBULISH PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP")
  107. //if c.InviteMode == INVIDE_MODE_ONSUBSCRIBE {
  108. //流可能是回放流,stream path是device/channel/start-end形式
  109. streamNames := strings.Split(e.Target, "/")
  110. if channel := FindChannel(streamNames[0], streamNames[1]); channel != nil {
  111. if GetInvistMode(c.InviteMode,channel.Model,channel.DeviceID) == INVIDE_MODE_ONSUBSCRIBE{
  112. opt := InviteOptions{}
  113. if len(streamNames) > 2 {
  114. last := len(streamNames) - 1
  115. timestr := streamNames[last]
  116. trange := strings.Split(timestr, "-")
  117. if len(trange) == 2 {
  118. startTime := trange[0]
  119. endTime := trange[1]
  120. opt.Validate(startTime, endTime)
  121. }
  122. }
  123. channel.TryAutoInvite(&opt)
  124. }
  125. }
  126. //}
  127. case SEpublish:
  128. //fmt.Println("11111111111111111111111111111111111111111111111:",e.Target.AppName,e.Target.StreamName,e.Target.Path)
  129. if channel := FindChannel(e.Target.AppName, strings.TrimSuffix(e.Target.StreamName, "/rtsp")); channel != nil {
  130. channel.LiveSubSP = e.Target.Path
  131. go channel.UpdateChanelLiveSubSp()
  132. }
  133. case SEclose:
  134. if channel := FindChannel(e.Target.AppName, strings.TrimSuffix(e.Target.StreamName, "/rtsp")); channel != nil {
  135. channel.LiveSubSP = ""
  136. go channel.UpdateChanelLiveSubSp()
  137. }
  138. if v, ok := PullStreams.LoadAndDelete(e.Target.Path); ok {
  139. //fmt.Println("bye 11111111111111111111111111111111")
  140. go v.(*PullStream).Bye()
  141. }
  142. }
  143. }
  144. func (c *GB28181Config) IsMediaNetworkTCP() bool {
  145. return strings.ToLower(c.MediaNetwork) == "tcp"
  146. }
  147. var conf GB28181Config
  148. var GB28181Plugin = InstallPlugin(&conf)
  149. var PullStreams sync.Map //拉流