国标GB28181流媒体协议视频平台EasyGBS级联上级平台语音重复问题解决

国标GB28181协议视频平台EasyGBS可以通过GB28181协议进行级联,除了能够与海康、宇视等视频平台进行级联外,也能同开发者自己的视频平台级联(EasyGBS如何实现视频流的向上级联)。

GBS产品架构3平面 定.png

EasyGBS视频平台也可以级联到上级平台的语音,但是再级联语音的测试过程中,我们发现上级发语音第一次正常,但是第二次之后发送的语音都是前一次的语音。

于是我们通过抓包来分析一下该问题的原因,从抓包结果可以看到第一次和第二次的音频是一致的。

65.png

但是第二次收集音频的时候,上级平台发送的是新采集的音频,而下级平台向设备发送的却是上次的音频。

66.png

排查代码发现,因为每次建立的udp链接读取过后都放在了一个缓存的buf数组里,并且udp的监听链接也是没有关闭的,所以会导致数据错乱,发送上次数据的情况。

case audioOnOff := <-Server.UacAudioOnOff[key]:
				if dataConn != nil {
					Server.UacAudioUdpConn[key] = nil
					bufUDP := make([]byte, 102400)
					//err := dataConn.SetReadDeadline(time.Now().Add(time.Second * 5))
					//if err != nil {
					//	Server.UacAudioUdpConn[key].Close()
					//	log.Println("超时处理")
					//	return
					//}
					time.Sleep(time.Second * 1)
					for audioOnOff {
						n, _, err := dataConn.ReadFromUDP(bufUDP)
						if err != nil {
							//Server.UacAudioUdpConn[key].Close()
							log.Printf("udp read error, %v", err)
							continue
						}
						rtpBuf := make([]byte, n)
						copy(rtpBuf, bufUDP[:n])
						tempint, err := transportMS.UDPConn.Write(rtpBuf)
						if err != nil {
							log.Printf("发送rtperr : %s  ,tempint :%d", err, tempint)
							return
						}
						time.Sleep(80 * time.Millisecond)
						log.Println("发送tempint", tempint)
					}

				}

需要添加以下代码

Server.UacAudioUdpConn[key] = nil

在每次获取到udp连接的时候,将本次使用的链接置空:

case audioOnOff := <-Server.UacAudioOnOff[key]:
				if dataConn != nil {
					Server.UacAudioUdpConn[key] = nil
					bufUDP := make([]byte, 102400)
					//err := dataConn.SetReadDeadline(time.Now().Add(time.Second * 5))
					//if err != nil {
					//	Server.UacAudioUdpConn[key].Close()
					//	log.Println("超时处理")
					//	return
					//}
					time.Sleep(time.Second * 1)
					for audioOnOff {
						n, _, err := dataConn.ReadFromUDP(bufUDP)
						if err != nil {
							//Server.UacAudioUdpConn[key].Close()
							log.Printf("udp read error, %v", err)
							continue
						}
						rtpBuf := make([]byte, n)
						copy(rtpBuf, bufUDP[:n])
						tempint, err := transportMS.UDPConn.Write(rtpBuf)
						if err != nil {
							log.Printf("发送rtperr : %s  ,tempint :%d", err, tempint)
							return
						}
						time.Sleep(80 * time.Millisecond)
						log.Println("发送tempint", tempint)
					}

				}

再次使用则每次发送的语音是和上级发送的语音是一致的。

注:摄像头设备支持语音的时候,通过EasyGBS级联则可以接收语音,摄像头设备不支持语音则无法接收。

EasyGBS视频平台能够支持云台控制,基于动态组网服务创建智能网络,按需选择需要组网的网络成员实现点点互联,并且能够提供多种流输出,包括RTSP、RTMP、HTTP-FLV、HLS等多种协议流,用户可以根据自身项目需求来选择合适的视频流。

GBS6.png

除了EasyGBS外,TSINGSEE青犀视频还有其他视频解决方案,比如支持RTSP协议的EasyNVR、支持RTMP协议的EasyDSS视频平台等。更多视频相关解决方案,欢迎联系我们了解。

猜你喜欢

转载自blog.csdn.net/EasyGBS/article/details/108659313