Compare commits

...

5 Commits

Author SHA1 Message Date
dexter
ecd97c8439 🐛 FIX: tcp解析 2022-10-25 15:35:00 +08:00
dexter
bfd71a72d8 Merge pull request #74 from hongri8488/v4
添加28181 bye接口调用时将流关闭
2022-10-25 14:44:39 +08:00
dexter
c6bef8ccd8 🐛 FIX: udp范围端口增加超时功能 2022-10-25 14:44:03 +08:00
hongri8488
20c0ac52cb 添加28181 bye接口调用时将流关闭 2022-10-25 13:51:31 +08:00
dexter
34f5b7da79 🐛 FIX: 推测h264的时候取的下标错误 2022-10-24 10:54:03 +08:00
4 changed files with 33 additions and 17 deletions

View File

@@ -22,7 +22,7 @@ gb28181:
prefetchrecord: false
udpcachesize: 0
sipnetwork: udp
sipip:
sipip: ""
sipport: 5060
serial: "34020000002000000001"
realm: "3402000000"
@@ -35,14 +35,15 @@ gb28181:
heartbeatinterval: 60
heartbeatretry: 3
mediaip:
mediaip: ""
mediaport: 58200
mediaidletimeout: 30
medianetwork: udp
mediaportmin: 0
meidaportmax: 0
removebaninterval: 600
loglevel: info
audioenable: true
```
- `AutoInvite` bool 表示自动发起invite当ServerSIP接收到设备信息时立即向设备发送invite命令获取流
@@ -68,12 +69,15 @@ gb28181:
- `MediaPort` uint16 媒体服务器端口
- `MediaNetwork` string 媒体传输协议默认UDP可选TCP
- `MediaIdleTimeout` uint16 推流超时时间,超过则断开链接,让设备重连
- `MediaPortMin` uint16 媒体服务器端口范围最小值
- `MediaPortMax` uint16 媒体服务器端口范围最大值
- `AudioEnable` bool 是否开启音频
- `LogLevel` string 日志级别,默认 infotracedebuginfowarnerrorfatal, panic
- `RemoveBanInterval` int 定时移除注册失败的设备黑名单单位秒默认10分钟600秒
- `UdpCacheSize` int 表示UDP缓存大小默认为0不开启。仅当TCP关闭切缓存大于0时才开启会最多缓存最多N个包并排序修复乱序造成的无法播放问题注意开启后会有一定的性能损耗并丢失部分包。
**如果配置了端口范围,将采用范围端口机制,每一个流对应一个端口
**注意某些摄像机没有设置用户名的地方摄像机会以自身的国标id作为用户名这个时候m7s会忽略使用摄像机的用户名忽略配置的用户名**
如果设备配置了错误的用户名和密码连续三次上报错误后m7s会记录设备id并在10分钟内禁止设备注册

View File

@@ -10,6 +10,7 @@ import (
"sync"
"time"
. "m7s.live/engine/v4"
"github.com/ghettovoice/gosip/sip"
"go.uber.org/zap"
"m7s.live/plugin/gb28181/v4/utils"
@@ -393,6 +394,11 @@ func (channel *Channel) Invite(opt InviteOptions) (code int, err error) {
}
func (channel *Channel) Bye(live bool) int {
d := channel.device
streamPath := fmt.Sprintf("%s/%s", d.ID, channel.DeviceID)
if s := Streams.Get(streamPath); s != nil {
s.Close()
}
if live && channel.LivePublisher != nil {
return channel.LivePublisher.Bye()
}

View File

@@ -116,9 +116,9 @@ func (p *GBPublisher) PushVideo(pts uint32, dts uint32, payload []byte) {
default:
//推测编码类型
var maybe264 H264NALUType
maybe264 = maybe264.Parse(payload[5])
maybe264 = maybe264.Parse(payload[4])
switch maybe264 {
case NALU_Non_IDR_Picture, NALU_IDR_Picture, NALU_SEI, NALU_SPS, NALU_PPS:
case NALU_Non_IDR_Picture, NALU_IDR_Picture, NALU_SEI, NALU_SPS, NALU_PPS, NALU_Access_Unit_Delimiter:
p.VideoTrack = NewH264(p.Publisher.Stream)
default:
p.VideoTrack = NewH265(p.Publisher.Stream)
@@ -161,21 +161,20 @@ func (p *GBPublisher) PushAudio(ts uint32, payload []byte) {
// 解析rtp封装 https://www.ietf.org/rfc/rfc2250.txt
func (p *GBPublisher) PushPS(rtp *rtp.Packet) {
if !conf.IsMediaNetworkTCP() {
rtp = p.reorder.Push(rtp.SequenceNumber, rtp)
} else {
p.lastSeq = rtp.SequenceNumber
}
if p.parser == nil {
p.parser = utils.NewDecPSPackage(p)
}
for rtp != nil {
if rtp.SequenceNumber != p.lastSeq+1 {
p.parser.Drop()
}
if conf.IsMediaNetworkTCP() {
p.parser.Feed(rtp.Payload)
p.lastSeq = rtp.SequenceNumber
rtp = p.reorder.Pop()
} else {
for rtp = p.reorder.Push(rtp.SequenceNumber, rtp); rtp != nil; rtp = p.reorder.Pop() {
if rtp.SequenceNumber != p.lastSeq+1 {
p.parser.Drop()
}
p.parser.Feed(rtp.Payload)
p.lastSeq = rtp.SequenceNumber
}
}
}
@@ -222,16 +221,19 @@ func (p *GBPublisher) ListenUDP() (port uint16, err error) {
mediaAddr, _ := net.ResolveUDPAddr("udp", addr)
conn, err := net.ListenUDP("udp", mediaAddr)
if err != nil {
conf.udpPorts.Recycle(port)
plugin.Error("listen media server udp err", zap.String("addr", addr), zap.Error(err))
return 0, err
}
p.SetIO(conn)
go func() {
defer conn.Close()
bufUDP := make([]byte, networkBuffer)
plugin.Info("Media udp server start.", zap.Uint16("port", port))
defer plugin.Info("Media udp server stop", zap.Uint16("port", port))
defer conf.udpPorts.Recycle(port)
dumpLen := make([]byte, 6)
conn.SetReadDeadline(time.Now().Add(time.Second * 10))
for n, _, err := conn.ReadFromUDP(bufUDP); err == nil; n, _, err = conn.ReadFromUDP(bufUDP) {
ps := bufUDP[:n]
if err := rtpPacket.Unmarshal(ps); err != nil {
@@ -249,6 +251,7 @@ func (p *GBPublisher) ListenUDP() (port uint16, err error) {
p.dumpFile.Write(ps)
}
p.PushPS(&rtpPacket)
conn.SetReadDeadline(time.Now().Add(time.Second * 10))
}
}()
return
@@ -263,6 +266,7 @@ func (p *GBPublisher) ListenTCP() (port uint16, err error) {
mediaAddr, _ := net.ResolveTCPAddr("tcp", addr)
listen, err := net.ListenTCP("tcp", mediaAddr)
if err != nil {
defer conf.tcpPorts.Recycle(port)
plugin.Error("listen media server tcp err", zap.String("addr", addr), zap.Error(err))
return 0, err
}

View File

@@ -164,6 +164,8 @@ func (dec *DecPSPackage) Feed(ps []byte) (err error) {
if dec.Len() >= 4 {
//说明需要处理PS包处理完后清空缓存
defer dec.Reset()
} else {
return
}
} else {
// 说明是中间数据,直接写入缓存,否则数据不合法需要丢弃