gb28181

package module
v4.4.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 27, 2023 License: AGPL-3.0 Imports: 29 Imported by: 0

README

GB28181插件

该插件提供SIP server的服务,以及流媒体服务器能力,可以将NVR和摄像头的流抓到m7s中,可获取的设备的录像数据以及访问录像视频。也可以控制摄像头的旋转、缩放等。

插件地址

github.com/Monibuca/plugin-gb28181

插件引入

import (
_ "m7s.live/plugin/gb28181/v4"
)

默认插件配置

gb28181:
  invitemode:     1 #0、手动invite 1、表示自动发起invite,当Server(SIP)接收到设备信息时,立即向设备发送invite命令获取流,2、按需拉流,既等待订阅者触发
  position:
    autosubposition: false #是否自动订阅定位
    expires: 3600s #订阅周期(单位:秒),默认3600
    interval: 6s #订阅间隔(单位:秒),默认6
  sipip:          "" #sip服务器地址 默认 自动适配设备网段
  serial:         "34020000002000000001"
  realm:          "3402000000"
  username:       ""
  password:       ""
  registervalidity:  60s #注册有效期
  mediaip:          "" #媒体服务器地址 默认 自动适配设备网段
  port:
    sip: udp:5060 #sip服务器端口
    media: tcp:58200-59200 #媒体服务器端口,用于接收设备的流

  removebaninterval: 10m #定时移除注册失败的设备黑名单,单位秒,默认10分钟(600秒)
  loglevel:         info

**如果配置了端口范围(默认为范围端口),将采用范围端口机制,每一个流对应一个端口

注意某些摄像机没有设置用户名的地方,摄像机会以自身的国标id作为用户名,这个时候m7s会忽略使用摄像机的用户名,忽略配置的用户名 如果设备配置了错误的用户名和密码,连续三次上报错误后,m7s会记录设备id,并在10分钟内禁止设备注册

插件功能

使用SIP协议接受NVR或其他GB28181设备的注册
  • 服务器启动时自动监听SIP协议端口,当有设备注册时,会记录该设备信息,可以从UI的列表中看到设备
  • 定时发送Catalog命令查询设备的目录信息,可获得通道数据或者子设备
  • 发送RecordInfo命令查询设备对录像数据
  • 发送Invite命令获取设备的实时视频或者录像视频
  • 发送PTZ命令来控制摄像头云台
  • 自动同步设备位置
作为GB28281的流媒体服务器接受设备的媒体流
  • 当invite设备的实时视频流时,会在m7s中创建对应的流,StreamPath由设备编号和通道编号组成,即[设备编号]/[通道编号],如果有多个层级,通道编号是最后一个层级的编号
  • 当invite设备的录像视频流时,StreamPath由设备编号和通道编号以及录像的起止时间拼接而成即[设备编号]/[通道编号]/[开始时间]-[结束时间]

接口API

罗列所有的gb28181协议的设备

/gb28181/api/list 设备的结构体如下

type Device struct {
	ID              string
	Name            string
	Manufacturer    string
	Model           string
	Owner           string
	RegisterTime    time.Time
	UpdateTime      time.Time
	LastKeepaliveAt time.Time
	Status          string
	Channels        []*Channel
	NetAddr         string
}

根据golang的规则,小写字母开头的变量不会被序列化

从设备拉取视频流

/gb28181/api/invite

参数名 必传 含义
id 设备ID
channel 通道编号
startTime 开始时间(纯数字Unix时间戳)
endTime 结束时间(纯数字Unix时间戳)

返回200代表成功, 304代表已经在拉取中,不能重复拉(仅仅针对直播流)

停止从设备拉流

/gb28181/api/bye

参数名 必传 含义
id 设备ID
channel 通道编号

http 200 表示成功,404流不存在

发送控制命令

/gb28181/api/control

参数名 必传 含义
id 设备ID
channel 通道编号
ptzcmd PTZ控制指令
查询录像

/gb28181/api/records

参数名 必传 含义
id 设备ID
channel 通道编号
startTime 开始时间(Unix时间戳)
endTime 结束时间(Unix时间戳)
移动位置订阅

/gb28181/api/position

参数名 必传 含义
id 设备ID
expires 订阅周期(秒)
interval 订阅间隔(秒)

Documentation

Index

Constants

View Source
const (
	ChannelOnStatus  = "ON"
	ChannelOffStatus = "OFF"
)
View Source
const (
	INVIDE_MODE_MANUAL = iota
	INVIDE_MODE_AUTO
	INVIDE_MODE_ONSUBSCRIBE
)
View Source
const (
	DeviceRegisterStatus = "REGISTER"
	DeviceRecoverStatus  = "RECOVER"
	DeviceOnlineStatus   = "ONLINE"
	DeviceOfflineStatus  = "OFFLINE"
	DeviceAlarmedStatus  = "ALARMED"
)
View Source
const MaxRegisterCount = 3
View Source
const TIME_LAYOUT = "2006-01-02T15:04:05"

Variables

View Source
var (
	Devices             sync.Map
	DeviceNonce         sync.Map //保存nonce防止设备伪造
	DeviceRegisterCount sync.Map //设备注册次数
)
View Source
var (
	// CatalogXML 获取设备列表xml样式
	CatalogXML = `<?xml version="1.0"?><Query>
<CmdType>Catalog</CmdType>
<SN>%d</SN>
<DeviceID>%s</DeviceID>
</Query>
`
	// RecordInfoXML 获取录像文件列表xml样式
	RecordInfoXML = `` /* 191-byte string literal not displayed */

	// DeviceInfoXML 查询设备详情xml样式
	DeviceInfoXML = `<?xml version="1.0"?>
<Query>
<CmdType>DeviceInfo</CmdType>
<SN>%d</SN>
<DeviceID>%s</DeviceID>
</Query>
`
	// DevicePositionXML 订阅设备位置
	DevicePositionXML = `` /* 132-byte string literal not displayed */

)
View Source
var (
	AlarmResponseXML = `<?xml version="1.0"?>
<Response>
<CmdType>Alarm</CmdType>
<SN>17430</SN>
<DeviceID>%s</DeviceID>
</Response>
`
)

AlarmResponseXML alarm response xml样式

View Source
var GB28181Plugin = InstallPlugin(&conf)
View Source
var PullStreams sync.Map //拉流
View Source
var QUERY_RECORD_TIMEOUT = time.Second * 5
View Source
var RecordQueryLink = NewRecordQueryLink(time.Second * 60)

对于录像查询,通过 queryKey (即 deviceId + channelId + sn) 唯一区分一次请求和响应 并将其关联起来,以实现异步响应的目的 提供单例实例供调用

Functions

func BuildAlarmResponseXML

func BuildAlarmResponseXML(id string) string

BuildRecordInfoXML 获取录像文件列表指令

func BuildCatalogXML

func BuildCatalogXML(sn int, id string) string

BuildCatalogXML 获取NVR下设备列表指令

func BuildDeviceInfoXML

func BuildDeviceInfoXML(sn int, id string) string

BuildDeviceInfoXML 获取设备详情指令

func BuildDevicePositionXML

func BuildDevicePositionXML(sn int, id string, interval int) string

BuildDevicePositionXML 订阅设备位置

func BuildRecordInfoXML

func BuildRecordInfoXML(sn int, id string, start, end int64) string

BuildRecordInfoXML 获取录像文件列表指令

func CreateRequest

func CreateRequest(exposedId string, Method sip.RequestMethod, recipient *sip.Address, netAddr string) (req sip.Request)

func Explain

func Explain(statusCode int) string

func GetSipServer

func GetSipServer(transport string) gosip.Server
func NewRecordQueryLink(resultTimeout time.Duration) *recordQueryLink

func RequestForResponse

func RequestForResponse(transport string, request sip.Request,
	options ...gosip.RequestWithContextOption) (sip.Response, error)

Types

type Authorization

type Authorization struct {
	*sip.Authorization
}

func (*Authorization) Verify

func (a *Authorization) Verify(username, passwd, realm, nonce string) bool

type Channel

type Channel struct {
	LiveSubSP   string    // 实时子码流,通过rtsp
	GpsTime     time.Time // gps时间
	Longitude   string    // 经度
	Latitude    string    // 纬度
	*log.Logger `json:"-" yaml:"-"`
	ChannelInfo
	// contains filtered or unexported fields
}

func FindChannel

func FindChannel(deviceId string, channelId string) (c *Channel)

func (*Channel) Bye

func (channel *Channel) Bye(streamPath string) int

func (*Channel) CanInvite

func (channel *Channel) CanInvite() bool

func (*Channel) Control

func (channel *Channel) Control(PTZCmd string) int

func (*Channel) CreateRequst

func (channel *Channel) CreateRequst(Method sip.RequestMethod) (req sip.Request)

func (*Channel) Invite

func (channel *Channel) Invite(opt *InviteOptions) (code int, err error)

func (*Channel) MarshalJSON

func (c *Channel) MarshalJSON() ([]byte, error)

func (*Channel) Pause

func (channel *Channel) Pause(streamPath string) int

func (*Channel) PlayAt

func (channel *Channel) PlayAt(streamPath string, second uint) int

func (*Channel) PlayForward

func (channel *Channel) PlayForward(streamPath string, speed float32) int

func (*Channel) QueryRecord

func (channel *Channel) QueryRecord(startTime, endTime string) ([]*Record, error)

func (*Channel) Resume

func (channel *Channel) Resume(streamPath string) int

func (*Channel) TryAutoInvite

func (channel *Channel) TryAutoInvite(opt *InviteOptions)

type ChannelInfo

type ChannelInfo struct {
	DeviceID     string // 通道ID
	ParentID     string
	Name         string
	Manufacturer string
	Model        string
	Owner        string
	CivilCode    string
	Address      string
	Port         int
	Parental     int
	SafetyWay    int
	RegisterWay  int
	Secrecy      int
	Status       ChannelStatus
}

Channel 通道

type ChannelStatus

type ChannelStatus string

type Device

type Device struct {
	//*transaction.Core `json:"-" yaml:"-"`
	ID              string
	Name            string
	Manufacturer    string
	Model           string
	Owner           string
	RegisterTime    time.Time
	UpdateTime      time.Time
	LastKeepaliveAt time.Time
	Status          DeviceStatus

	NetAddr string

	GpsTime     time.Time //gps时间
	Longitude   string    //经度
	Latitude    string    //纬度
	*log.Logger `json:"-" yaml:"-"`
	// contains filtered or unexported fields
}

func (*Device) Catalog

func (d *Device) Catalog() int

func (*Device) CreateRequest

func (d *Device) CreateRequest(Method sip.RequestMethod) (req sip.Request)

func (*Device) MarshalJSON

func (d *Device) MarshalJSON() ([]byte, error)

func (*Device) MobilePositionSubscribe

func (d *Device) MobilePositionSubscribe(id string, expires time.Duration, interval time.Duration) (code int)

MobilePositionSubscribe 移动位置订阅

func (*Device) QueryDeviceInfo

func (d *Device) QueryDeviceInfo()

func (*Device) SipRequestForResponse

func (d *Device) SipRequestForResponse(request sip.Request) (sip.Response, error)

func (*Device) Subscribe

func (d *Device) Subscribe() int

func (*Device) UpdateChannelPosition

func (d *Device) UpdateChannelPosition(channelId string, gpsTime string, lng string, lat string)

UpdateChannelPosition 更新通道GPS坐标

func (*Device) UpdateChannelStatus

func (d *Device) UpdateChannelStatus(deviceList []*notifyMessage)

UpdateChannelStatus 目录订阅消息处理:新增/移除/更新通道或者更改通道状态

func (*Device) UpdateChannels

func (d *Device) UpdateChannels(list ...ChannelInfo)

type DevicePosition

type DevicePosition struct {
	ID        string
	GpsTime   time.Time //gps时间
	Longitude string    //经度
	Latitude  string    //纬度
}

type DeviceStatus

type DeviceStatus string

type GB28181Config

type GB28181Config struct {
	InviteMode int    `default:"1"` //邀请模式,0:手动拉流,1:预拉流,2:按需拉流
	InviteIDs  string //按照国标gb28181协议允许邀请的设备类型:132 摄像机 NVR
	ListenAddr string `default:"0.0.0.0"`
	//sip服务器的配置
	SipNetwork string `default:"udp"` //传输协议,默认UDP,可选TCP
	SipIP      string //sip 服务器公网IP
	SipPort    uint16 `default:"5060"`                 //sip 服务器端口,默认 5060
	Serial     string `default:"34020000002000000001"` //sip 服务器 id, 默认 34020000002000000001
	Realm      string `default:"3402000000"`           //sip 服务器域,默认 3402000000
	Username   string //sip 服务器账号
	Password   string //sip 服务器密码
	Port       struct {
		Sip   string `default:"udp:5060"`
		Media string `default:"tcp:58200-59200"`
	}
	// AckTimeout        uint16 //sip 服务应答超时,单位秒
	RegisterValidity time.Duration `default:"3600s"` //注册有效期,单位秒,默认 3600
	// RegisterInterval  int    //注册间隔,单位秒,默认 60
	HeartbeatInterval time.Duration `default:"60s"` //心跳间隔,单位秒,默认 60

	//媒体服务器配置
	MediaIP      string //媒体服务器地址
	MediaPort    uint16 `default:"58200"` //媒体服务器端口
	MediaNetwork string `default:"tcp"`   //媒体传输协议,默认UDP,可选TCP
	MediaPortMin uint16 `default:"58200"`
	MediaPortMax uint16 `default:"59200"`

	// WaitKeyFrame      bool //是否等待关键帧,如果等待,则在收到第一个关键帧之前,忽略所有媒体流
	RemoveBanInterval time.Duration `default:"600s"` //移除禁止设备间隔
	// UdpCacheSize      int           //udp缓存大小
	LogLevel string `default:"info"` //trace, debug, info, warn, error, fatal, panic

	DumpPath string //dump PS流本地文件路径
	Ignores  map[string]struct{}

	Position GB28181PositionConfig //关于定位的配置参数
	// contains filtered or unexported fields
}

func (*GB28181Config) API_bye

func (c *GB28181Config) API_bye(w http.ResponseWriter, r *http.Request)

func (*GB28181Config) API_control

func (c *GB28181Config) API_control(w http.ResponseWriter, r *http.Request)

func (*GB28181Config) API_get_position

func (c *GB28181Config) API_get_position(w http.ResponseWriter, r *http.Request)

func (*GB28181Config) API_invite

func (c *GB28181Config) API_invite(w http.ResponseWriter, r *http.Request)

func (*GB28181Config) API_list

func (c *GB28181Config) API_list(w http.ResponseWriter, r *http.Request)

func (*GB28181Config) API_play_forward

func (c *GB28181Config) API_play_forward(w http.ResponseWriter, r *http.Request)

func (*GB28181Config) API_play_pause

func (c *GB28181Config) API_play_pause(w http.ResponseWriter, r *http.Request)

func (*GB28181Config) API_play_resume

func (c *GB28181Config) API_play_resume(w http.ResponseWriter, r *http.Request)

func (*GB28181Config) API_play_seek

func (c *GB28181Config) API_play_seek(w http.ResponseWriter, r *http.Request)

func (*GB28181Config) API_position

func (c *GB28181Config) API_position(w http.ResponseWriter, r *http.Request)

func (*GB28181Config) API_ptz

func (c *GB28181Config) API_ptz(w http.ResponseWriter, r *http.Request)

func (*GB28181Config) API_records

func (c *GB28181Config) API_records(w http.ResponseWriter, r *http.Request)

func (*GB28181Config) IsMediaNetworkTCP

func (c *GB28181Config) IsMediaNetworkTCP() bool

func (*GB28181Config) OnBye

func (c *GB28181Config) OnBye(req sip.Request, tx sip.ServerTransaction)

func (*GB28181Config) OnEvent

func (c *GB28181Config) OnEvent(event any)

func (*GB28181Config) OnMessage

func (c *GB28181Config) OnMessage(req sip.Request, tx sip.ServerTransaction)

func (*GB28181Config) OnNotify

func (c *GB28181Config) OnNotify(req sip.Request, tx sip.ServerTransaction)

OnNotify 订阅通知处理

func (*GB28181Config) OnRegister

func (c *GB28181Config) OnRegister(req sip.Request, tx sip.ServerTransaction)

func (*GB28181Config) ReadDevices

func (c *GB28181Config) ReadDevices()

func (*GB28181Config) RecoverDevice

func (c *GB28181Config) RecoverDevice(d *Device, req sip.Request)

func (*GB28181Config) SaveDevices

func (c *GB28181Config) SaveDevices()

func (*GB28181Config) StoreDevice

func (c *GB28181Config) StoreDevice(id string, req sip.Request) (d *Device)

type GB28181PositionConfig

type GB28181PositionConfig struct {
	AutosubPosition bool          //是否自动订阅定位
	Expires         time.Duration `default:"3600s"` //订阅周期(单位:秒)
	Interval        time.Duration `default:"6s"`    //订阅间隔(单位:秒)
}

type InviteOptions

type InviteOptions struct {
	Start int
	End   int

	SSRC       uint32
	MediaPort  uint16
	StreamPath string
	// contains filtered or unexported fields
}

func (*InviteOptions) CreateSSRC

func (o *InviteOptions) CreateSSRC()

func (InviteOptions) IsLive

func (o InviteOptions) IsLive() bool

func (InviteOptions) Record

func (o InviteOptions) Record() bool

func (InviteOptions) String

func (o InviteOptions) String() string

func (*InviteOptions) Validate

func (o *InviteOptions) Validate(start, end string) error

type PortManager

type PortManager struct {
	Valid bool
	// contains filtered or unexported fields
}

func (*PortManager) GetPort

func (pm *PortManager) GetPort() (p uint16, err error)

func (*PortManager) Init

func (pm *PortManager) Init(start, end uint16)

func (*PortManager) Range

func (pm *PortManager) Range() uint16

func (*PortManager) Recycle

func (pm *PortManager) Recycle(p uint16) (err error)

type PullStream

type PullStream struct {
	// contains filtered or unexported fields
}

func (*PullStream) Bye

func (p *PullStream) Bye() int

func (*PullStream) CreateRequest

func (p *PullStream) CreateRequest(method sip.RequestMethod) (req sip.Request)

func (*PullStream) Pause

func (p *PullStream) Pause() int

暂停播放

func (*PullStream) PlayAt

func (p *PullStream) PlayAt(second uint) int

跳转到播放时间 second: 相对于起始点调整到第 sec 秒播放

func (*PullStream) PlayForward

func (p *PullStream) PlayForward(speed float32) int

快进/快退播放 speed 取值: 0.25 0.5 1 2 4 或者其对应的负数表示倒放

func (*PullStream) Resume

func (p *PullStream) Resume() int

恢复播放

type Record

type Record struct {
	DeviceID  string
	Name      string
	FilePath  string
	Address   string
	StartTime string
	EndTime   string
	Secrecy   int
	Type      string
}

Record 录像

func (*Record) GetPublishStreamPath

func (r *Record) GetPublishStreamPath() string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL