gb28181

package module
v3.0.7 Latest Latest
Warning

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

Go to latest
Published: Feb 28, 2022 License: AGPL-3.0 Imports: 22 Imported by: 1

README

GB28181插件

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

插件地址

github.com/Monibuca/plugin-gb28181

插件引入

import (
_ "github.com/Monibuca/plugin-gb28181"
)

默认插件配置

[GB28181]
Serial = "34020000002000000001"
Realm = "3402000000"
Expires = 3600
ListenAddr = "127.0.0.1:5060"
AutoCloseAfter = -1
AutoInvite = false
MediaPort = 58200
CatalogInterval = 30
RemoveBanInterval = 600
Username = ""
Password = ""
UdpCacheSize = 0 
TCP = false
  • ListenAddr是监听的地址,这里需要注意的是必须要带上Server的IP地址,这个IP地址是向设备发送信息的时候需要带上的。
  • Serial Server(SIP)的编号
  • Realm Server(SIP)的域
  • AutoCloseAfter 如果设置大于等于0,则当某个流最后一个订阅者取消订阅时会延迟N秒,会自动发送bye,节省流量。如果为了响应及时,可以设置成-1,保持流的连接
  • AutoInvite 表示自动发起invite,当Server(SIP)接收到设备信息时,立即向设备发送invite命令获取流
  • MediaPort 表示用于接收设备流的端口号
  • CatalogInterval 定时获取设备目录的间隔,单位秒
  • RemoveBanInterval 定时移除注册失败的设备黑名单,单位秒,默认10分钟(600秒)
  • Username 国标用户名
  • Password 国标密码
  • TCP 是否开启TCP接收国标流,默认false
  • UdpCacheSize 表示UDP缓存大小,默认为0,不开启。仅当TCP关闭,切缓存大于0时才开启,会最多缓存最多N个包,并排序,修复乱序造成的无法播放问题,注意开启后,会有一定的性能损耗,并丢失部分包。

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

插件功能

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

通过wireshark抓包,分析rtp,然后看一下大概多少个包可以有序

接口API

罗列所有的gb28181协议的设备

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

type Device struct {
*transaction.Core `json:"-"`
ID                string
RegisterTime      time.Time
UpdateTime        time.Time
Status            string
Channels          []*Channel
queryChannel      bool
sn                int
from              *sip.Contact
to                *sip.Contact
Addr              string
SipIP             string //暴露的IP
channelMap        map[string]*Channel
channelMutex      sync.RWMutex
}

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

从设备拉取视频流

/api/gb28181/invite

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

返回200代表成功

停止从设备拉流

/api/gb28181/bye

参数名 必传 含义
id 设备ID
channel 通道编号
发送控制命令

/api/gb28181/control

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

/api/gb28181/query/records

参数名 必传 含义
id 设备ID
channel 通道编号
startTime 开始时间(字符串,格式:2021-7-23T12:00:00)
endTime 结束时间(字符串格式同上)

Documentation

Index

Constants

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 (
	Ignores = make(map[string]struct{})
)

Functions

func OnMessage added in v3.0.4

func OnMessage(req *sip.Request, tx *transaction.GBTx)

func OnRegister added in v3.0.4

func OnRegister(req *sip.Request, tx *transaction.GBTx)

Types

type Channel

type Channel struct {
	DeviceID     string
	ParentID     string
	Name         string
	Manufacturer string
	Model        string
	Owner        string
	CivilCode    string
	Address      string
	Parental     int
	SafetyWay    int
	RegisterWay  int
	Secrecy      int
	Status       string
	Children     []*Channel `json:"-"`
	*ChannelEx              //自定义属性
}

Channel 通道

func FindChannel

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

func (*Channel) Bye

func (channel *Channel) Bye(live bool) int

func (*Channel) ByeBye

func (c *Channel) ByeBye(res *Request) *Response

func (*Channel) Control

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

func (*Channel) CreateRequst added in v3.0.4

func (c *Channel) CreateRequst(Method Method) (request *Request)

func (*Channel) Invite

func (channel *Channel) Invite(start, end string) (code int)

f字段: f = v/编码格式/分辨率/帧率/码率类型/码率大小a/编码格式/码率大小/采样率 各项具体含义:

v:后续参数为视频的参数;各参数间以 “/”分割;

编码格式:十进制整数字符串表示 1 –MPEG-4 2 –H.264 3 – SVAC 4 –3GP

分辨率:十进制整数字符串表示

1 – QCIF 2 – CIF 3 – 4CIF 4 – D1 5 –720P 6 –1080P/I 帧率:十进制整数字符串表示 0~99 码率类型:十进制整数字符串表示 1 – 固定码率(CBR) 2 – 可变码率(VBR) 码率大小:十进制整数字符串表示 0~100000(如 1表示1kbps)

a:后续参数为音频的参数;各参数间以 “/”分割;

编码格式:十进制整数字符串表示 1 – G.711 2 – G.723.1 3 – G.729 4 – G.722.1 码率大小:十进制整数字符串 音频编码码率: 1 — 5.3 kbps (注:G.723.1中使用)

2 — 6.3 kbps (注:G.723.1中使用)
3 — 8 kbps (注:G.729中使用)
4 — 16 kbps (注:G.722.1中使用)
5 — 24 kbps (注:G.722.1中使用)
6 — 32 kbps (注:G.722.1中使用)
7 — 48 kbps (注:G.722.1中使用)
8 — 64 kbps(注:G.711中使用)

采样率:十进制整数字符串表示

1 — 8 kHz(注:G.711/ G.723.1/ G.729中使用)
2—14 kHz(注:G.722.1中使用)
3—16 kHz(注:G.722.1中使用)
4—32 kHz(注:G.722.1中使用)
注1:字符串说明

本节中使用的“十进制整数字符串”的含义为“0”~“4294967296” 之间的十进制数字字符串。 注2:参数分割标识 各参数间以“/”分割,参数间的分割符“/”不能省略; 若两个分割符 “/”间的某参数为空时(即两个分割符 “/”直接将相连时)表示无该参数值; 注3:f字段说明 使用f字段时,应保证视频和音频参数的结构完整性,即在任何时候,f字段的结构都应是完整的结构: f = v/编码格式/分辨率/帧率/码率类型/码率大小a/编码格式/码率大小/采样率 若只有视频时,音频中的各参数项可以不填写,但应保持 “a///”的结构: f = v/编码格式/分辨率/帧率/码率类型/码率大小a/// 若只有音频时也类似处理,视频中的各参数项可以不填写,但应保持 “v/”的结构: f = v/a/编码格式/码率大小/采样率 f字段中视、音频参数段之间不需空格分割。 可使用f字段中的分辨率参数标识同一设备不同分辨率的码流。

func (*Channel) QueryRecord

func (channel *Channel) QueryRecord(startTime, endTime string) int

type ChannelEx

type ChannelEx struct {
	RecordPublisher *Publisher
	LivePublisher   *Publisher
	LiveSubSP       string //实时子码流
	Records         []*Record
	RecordStartTime string
	RecordEndTime   string
	// contains filtered or unexported fields
}

type Device

type Device struct {
	*transaction.Core `json:"-"`
	ID                string
	Name              string
	Manufacturer      string
	Model             string
	Owner             string
	RegisterTime      time.Time
	UpdateTime        time.Time
	LastKeepaliveAt   time.Time
	Status            string
	Channels          []*Channel

	Addr  string
	SipIP string //暴露的IP
	// contains filtered or unexported fields
}

func (*Device) Catalog added in v3.0.6

func (d *Device) Catalog() int

func (*Device) CheckSubStream

func (d *Device) CheckSubStream()

func (*Device) CreateMessage

func (d *Device) CreateMessage(Method sip.Method) (requestMsg *sip.Message)

func (*Device) QueryDeviceInfo added in v3.0.6

func (d *Device) QueryDeviceInfo(req *sip.Request)

func (*Device) Subscribe

func (d *Device) Subscribe() int

func (*Device) UpdateChannels

func (d *Device) UpdateChannels(list []*Channel)

func (*Device) UpdateRecord

func (d *Device) UpdateRecord(channelId string, list []*Record)

type Publisher

type Publisher struct {
	*engine.Stream
	// contains filtered or unexported fields
}

func (*Publisher) Publish

func (p *Publisher) Publish() (result bool)

func (*Publisher) PushAudio

func (p *Publisher) PushAudio(ts uint32, payload []byte)

func (*Publisher) PushPS

func (p *Publisher) PushPS(rtp *rtp.Packet)

func (*Publisher) PushVideo

func (p *Publisher) PushVideo(ts uint32, cts uint32, payload []byte)

type Publishers

type Publishers struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

func (*Publishers) Add

func (p *Publishers) Add(key uint32, pp *Publisher)

func (*Publishers) Get

func (p *Publishers) Get(key uint32) *Publisher

func (*Publishers) Remove

func (p *Publishers) Remove(key uint32)

type Record

type Record struct {
	//channel   *Channel
	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