Merge remote-tracking branch 'origin/结构优化' into 结构优化

# Conflicts:
#	src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
结构优化
648540858 2024-03-11 23:07:00 +08:00
commit bc7e1ecb89
20 changed files with 191 additions and 292 deletions

View File

@ -347,7 +347,7 @@ public class GB28181ResourceServiceImpl implements IResourceService {
DateUtil.urlFormatter.format(startTime) + "_" + DateUtil.urlFormatter.format(stopTime); DateUtil.urlFormatter.format(startTime) + "_" + DateUtil.urlFormatter.format(stopTime);
MediaServerItem mediaServerItem = playService.getNewMediaServerItem(checkResult.device); MediaServerItem mediaServerItem = playService.getNewMediaServerItem(checkResult.device);
SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, stream, null, SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, stream, null,
checkResult.device.isSsrcCheck(), true, 0, false, checkResult.device.getStreamModeForParam()); checkResult.device.isSsrcCheck(), true, 0, false, false, checkResult.device.getStreamModeForParam());
playService.playBack(mediaServerItem, ssrcInfo, checkResult.channel.getDeviceId(), checkResult.channel.getChannelId(), playService.playBack(mediaServerItem, ssrcInfo, checkResult.channel.getDeviceId(), checkResult.channel.getChannelId(),
startTimeStr, endTimeStr, (code, msg, data) -> { startTimeStr, endTimeStr, (code, msg, data) -> {
if (code == InviteErrorCode.SUCCESS.getCode()) { if (code == InviteErrorCode.SUCCESS.getCode()) {
@ -378,7 +378,7 @@ public class GB28181ResourceServiceImpl implements IResourceService {
DateUtil.urlFormatter.format(startTime) + "_" + DateUtil.urlFormatter.format(stopTime); DateUtil.urlFormatter.format(startTime) + "_" + DateUtil.urlFormatter.format(stopTime);
MediaServerItem mediaServerItem = playService.getNewMediaServerItem(checkResult.device); MediaServerItem mediaServerItem = playService.getNewMediaServerItem(checkResult.device);
SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, stream, null, SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, stream, null,
checkResult.device.isSsrcCheck(), true, 0, false, checkResult.device.getStreamModeForParam()); checkResult.device.isSsrcCheck(), true, 0, false, false, checkResult.device.getStreamModeForParam());
playService.download(mediaServerItem, ssrcInfo, checkResult.channel.getDeviceId(), checkResult.channel.getChannelId(), playService.download(mediaServerItem, ssrcInfo, checkResult.channel.getDeviceId(), checkResult.channel.getChannelId(),
startTimeStr, endTimeStr, downloadSpeed, (code, msg, data) -> { startTimeStr, endTimeStr, downloadSpeed, (code, msg, data) -> {
if (code == InviteErrorCode.SUCCESS.getCode()) { if (code == InviteErrorCode.SUCCESS.getCode()) {

View File

@ -45,6 +45,12 @@ public class AudioBroadcastCatch {
*/ */
private String channelId; private String channelId;
/**
* callId
*/
private String callId;
/** /**
* *
*/ */
@ -156,4 +162,12 @@ public class AudioBroadcastCatch {
public void setSipTransactionInfoByRequset(SIPResponse sipResponse) { public void setSipTransactionInfoByRequset(SIPResponse sipResponse) {
this.sipTransactionInfo = new SipTransactionInfo(sipResponse); this.sipTransactionInfo = new SipTransactionInfo(sipResponse);
} }
public String getCallId() {
return callId;
}
public void setCallId(String callId) {
this.callId = callId;
}
} }

View File

@ -7,10 +7,6 @@ import com.genersoft.iot.vmp.conf.UserSetting;
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
import com.genersoft.iot.vmp.gb28181.SipLayer; import com.genersoft.iot.vmp.gb28181.SipLayer;
import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.bean.*;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm;
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
import com.genersoft.iot.vmp.gb28181.bean.command.PTZCommand; import com.genersoft.iot.vmp.gb28181.bean.command.PTZCommand;
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
@ -38,11 +34,13 @@ import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import javax.sip.*; import javax.sip.InvalidArgumentException;
import javax.sip.ResponseEvent;
import javax.sip.SipException;
import javax.sip.SipFactory;
import javax.sip.header.CallIdHeader; import javax.sip.header.CallIdHeader;
import javax.sip.message.Request; import javax.sip.message.Request;
import java.text.ParseException; import java.text.ParseException;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@ -85,8 +83,8 @@ public class SIPCommander implements ISIPCommander {
@Override @Override
public void ptzZoomCmd(Device device, String channelId, int inOut, int zoomSpeed) throws InvalidArgumentException, ParseException, SipException { public void ptzCmd(Device device, String channelId, PTZCommand ptzCommand) throws InvalidArgumentException, SipException, ParseException {
ptzCmd(device, channelId, 0, 0, inOut, 0, zoomSpeed);
} }
/** /**
@ -120,39 +118,6 @@ public class SIPCommander implements ISIPCommander {
return builder.toString(); return builder.toString();
} }
/**
*
*
* @param device
* @param channelId
* @param leftRight 0: 1: 2:
* @param upDown 0: 1: 2:
* @param inOut 0: 1: 2:
* @param moveSpeed
* @param zoomSpeed
*/
@Override
public void ptzCmd(Device device, String channelId, int leftRight, int upDown, int inOut, int moveSpeed,
int zoomSpeed) throws InvalidArgumentException, SipException, ParseException {
String cmdStr = SipUtils.cmdString(leftRight, upDown, inOut, moveSpeed, zoomSpeed);
StringBuilder ptzXml = new StringBuilder(200);
String charset = device.getCharset();
ptzXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
ptzXml.append("<Control>\r\n");
ptzXml.append("<CmdType>DeviceControl</CmdType>\r\n");
ptzXml.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n");
ptzXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
ptzXml.append("<PTZCmd>" + cmdStr + "</PTZCmd>\r\n");
ptzXml.append("<Info>\r\n");
ptzXml.append("<ControlPriority>5</ControlPriority>\r\n");
ptzXml.append("</Info>\r\n");
ptzXml.append("</Control>\r\n");
Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()));
sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()),request);
}
/** /**
* PTZFI * PTZFI
* *
@ -634,28 +599,7 @@ public class SIPCommander implements ISIPCommander {
* @param device * @param device
*/ */
@Override @Override
public void audioBroadcastCmd(Device device) throws InvalidArgumentException, SipException, ParseException { public void audioBroadcastCmd(Device device, String channelId, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException {
StringBuffer broadcastXml = new StringBuffer(200);
String charset = device.getCharset();
broadcastXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
broadcastXml.append("<Notify>\r\n");
broadcastXml.append("<CmdType>Broadcast</CmdType>\r\n");
broadcastXml.append("<SN>" + SipUtils.getNewSn() + "</SN>\r\n");
broadcastXml.append("<SourceID>" + sipConfig.getId() + "</SourceID>\r\n");
broadcastXml.append("<TargetID>" + device.getDeviceId() + "</TargetID>\r\n");
broadcastXml.append("</Notify>\r\n");
Request request = headerProvider.createMessageRequest(device, broadcastXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()));
sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request);
}
@Override
public void audioBroadcastCmd(Device device, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException {
StringBuffer broadcastXml = new StringBuffer(200); StringBuffer broadcastXml = new StringBuffer(200);
String charset = device.getCharset(); String charset = device.getCharset();
broadcastXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n"); broadcastXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");

View File

@ -93,6 +93,9 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
@Autowired @Autowired
private GitUtil gitUtil; private GitUtil gitUtil;
@Autowired
private SipLayer sipLayer;
@Override @Override
public void register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException { public void register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException {
register(parentPlatform, null, null, errorEvent, okEvent, true); register(parentPlatform, null, null, errorEvent, okEvent, true);

View File

@ -11,7 +11,6 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
import com.genersoft.iot.vmp.media.zlm.IStreamSendManager; import com.genersoft.iot.vmp.media.zlm.IStreamSendManager;
import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.service.IDeviceService;
import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.service.IMediaServerService;
@ -20,6 +19,7 @@ import com.genersoft.iot.vmp.service.bean.RequestPushStreamMsg;
import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener; import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
import gov.nist.javax.sip.message.SIPRequest;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
@ -29,9 +29,6 @@ import org.springframework.stereotype.Component;
import javax.sip.RequestEvent; import javax.sip.RequestEvent;
import javax.sip.address.SipURI; import javax.sip.address.SipURI;
import javax.sip.header.CallIdHeader; import javax.sip.header.CallIdHeader;
import javax.sip.header.FromHeader;
import javax.sip.header.HeaderAddress;
import javax.sip.header.ToHeader;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -92,7 +89,10 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
public void process(RequestEvent evt) { public void process(RequestEvent evt) {
CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME); CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME);
dynamicTask.stop(callIdHeader.getCallId()); dynamicTask.stop(callIdHeader.getCallId());
String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser(); SIPRequest sipRequest = (SIPRequest) evt.getRequest();
String toUserId = ((SipURI) sipRequest.getToHeader().getAddress().getURI()).getUser();
String fromUserId = ((SipURI) sipRequest.getFromHeader().getAddress().getURI()).getUser();
SendRtpItem sendRtpItem = streamSendManager.getByCallId(callIdHeader.getCallId()); SendRtpItem sendRtpItem = streamSendManager.getByCallId(callIdHeader.getCallId());
if (sendRtpItem == null) { if (sendRtpItem == null) {
logger.warn("[收到ACK]:未找到来自{},目标为({})的推流信息",fromUserId, toUserId); logger.warn("[收到ACK]:未找到来自{},目标为({})的推流信息",fromUserId, toUserId);

View File

@ -123,7 +123,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
SendRtpItem sendRtpItem = streamSendManager.getByCallId(callIdHeader.getCallId()); SendRtpItem sendRtpItem = streamSendManager.getByCallId(callIdHeader.getCallId());
if (sendRtpItem != null){ if (sendRtpItem != null){
logger.info("[收到bye] 来自{} 停止通道:{}", sendRtpItem.getDestId(), sendRtpItem.getChannelId()); logger.info("[收到bye] 来自{} 停止通道:{}", sendRtpItem.getDestId(), sendRtpItem.getChannelId());
String streamId = sendRtpItem.getStreamId(); String streamId = sendRtpItem.getStream();
Map<String, Object> param = new HashMap<>(); Map<String, Object> param = new HashMap<>();
param.put("vhost","__defaultVhost__"); param.put("vhost","__defaultVhost__");
param.put("app",sendRtpItem.getApp()); param.put("app",sendRtpItem.getApp());
@ -145,32 +145,32 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
ParentPlatform platform = platformService.queryPlatformByServerGBId(sendRtpItem.getDestId()); ParentPlatform platform = platformService.queryPlatformByServerGBId(sendRtpItem.getDestId());
if (platform != null) { if (platform != null) {
MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0, MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0,
sendRtpItem.getApp(), sendRtpItem.getStreamId(), sendRtpItem.getChannelId(), sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getChannelId(),
sendRtpItem.getDestId(), platform.getName(), userSetting.getServerId(), sendRtpItem.getMediaServerId()); sendRtpItem.getDestId(), platform.getName(), userSetting.getServerId(), sendRtpItem.getMediaServerId());
messageForPushChannel.setPlatFormIndex(platform.getId()); messageForPushChannel.setPlatFormIndex(platform.getId());
redisCatchStorage.sendPlatformStopPlayMsg(messageForPushChannel); redisCatchStorage.sendPlatformStopPlayMsg(messageForPushChannel);
}else { }else {
logger.info("[上级平台停止观看] 未找到平台{}的信息发送redis消息失败", sendRtpItem.getPlatformId()); logger.info("[上级平台停止观看] 未找到平台{}的信息发送redis消息失败", sendRtpItem.getDestId());
} }
} }
AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getSourceId(), sendRtpItem.getChannelId());
if (audioBroadcastCatch != null && audioBroadcastCatch.getSipTransactionInfo().getCallId().equals(callIdHeader.getCallId())) { if (audioBroadcastCatch != null && audioBroadcastCatch.getSipTransactionInfo().getCallId().equals(callIdHeader.getCallId())) {
// 来自上级平台的停止对讲 // 来自上级平台的停止对讲
logger.info("[停止对讲] 来自上级,平台:{}, 通道:{}", sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); logger.info("[停止对讲] 来自上级,平台:{}, 通道:{}", sendRtpItem.getSourceId(), sendRtpItem.getChannelId());
audioBroadcastManager.del(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); audioBroadcastManager.del(sendRtpItem.getSourceId(), sendRtpItem.getChannelId());
} }
int totalReaderCount = zlmServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId); int totalReaderCount = zlmServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId);
if (totalReaderCount <= 0) { if (totalReaderCount <= 0) {
logger.info("[收到bye] {} 无其它观看者,通知设备停止推流", streamId); logger.info("[收到bye] {} 无其它观看者,通知设备停止推流", streamId);
if (sendRtpItem.getPlayType().equals(InviteStreamType.PLAY)) { if (sendRtpItem.getPlayType().equals(InviteStreamType.PLAY)) {
Device device = deviceService.getDevice(sendRtpItem.getDeviceId()); Device device = deviceService.getDevice(sendRtpItem.getSourceId());
if (device == null) { if (device == null) {
logger.info("[收到bye] {} 通知设备停止推流时未找到设备信息", streamId); logger.info("[收到bye] {} 通知设备停止推流时未找到设备信息", streamId);
} }
try { try {
logger.info("[停止点播] {}/{}", sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); logger.info("[停止点播] {}/{}", sendRtpItem.getSourceId(), sendRtpItem.getChannelId());
cmder.streamByeCmd(device, sendRtpItem.getChannelId(), streamId, null); cmder.streamByeCmd(device, sendRtpItem.getChannelId(), streamId, null);
} catch (InvalidArgumentException | ParseException | SipException | } catch (InvalidArgumentException | ParseException | SipException |
SsrcTransactionNotFoundException e) { SsrcTransactionNotFoundException e) {

View File

@ -932,7 +932,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
sipResponse = responseSdpAck(request, content.toString(), parentPlatform); sipResponse = responseSdpAck(request, content.toString(), parentPlatform);
AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(device.getDeviceId(), sendRtpItem.getChannelId()); AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(device.getDeviceId(), sendRtpItem.getChannelId());
audioBroadcastCatch.setCallId(request.getCallIdHeader().getCallId());
audioBroadcastCatch.setStatus(AudioBroadcastCatchStatus.Ok); audioBroadcastCatch.setStatus(AudioBroadcastCatchStatus.Ok);
audioBroadcastCatch.setSipTransactionInfoByRequset(sipResponse); audioBroadcastCatch.setSipTransactionInfoByRequset(sipResponse);
audioBroadcastManager.update(audioBroadcastCatch); audioBroadcastManager.update(audioBroadcastCatch);

View File

@ -114,7 +114,7 @@ public class InfoRequestProcessor extends SIPRequestProcessorParent implements I
if ("Application".equalsIgnoreCase(contentType) && "MANSRTSP".equalsIgnoreCase(contentSubType)) { if ("Application".equalsIgnoreCase(contentType) && "MANSRTSP".equalsIgnoreCase(contentSubType)) {
SendRtpItem sendRtpItem = streamSendManager.getByCallId(callIdHeader.getCallId()); SendRtpItem sendRtpItem = streamSendManager.getByCallId(callIdHeader.getCallId());
String streamId = sendRtpItem.getStreamId(); String streamId = sendRtpItem.getStream();
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(InviteSessionType.PLAYBACK, streamId); InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(InviteSessionType.PLAYBACK, streamId);
if (null == inviteInfo) { if (null == inviteInfo) {
responseAck(request, Response.NOT_FOUND, "stream " + streamId + " not found"); responseAck(request, Response.NOT_FOUND, "stream " + streamId + " not found");

View File

@ -1,7 +1,6 @@
package com.genersoft.iot.vmp.media.zlm; package com.genersoft.iot.vmp.media.zlm;
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import java.util.List; import java.util.List;
@ -30,5 +29,4 @@ public interface IStreamSendManager {
void remove(SendRtpItem sendRtpItem); void remove(SendRtpItem sendRtpItem);
void remove(List<SendRtpItem> sendRtpItemList); void remove(List<SendRtpItem> sendRtpItemList);
} }

View File

@ -18,6 +18,9 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
import com.genersoft.iot.vmp.media.zlm.dto.*; import com.genersoft.iot.vmp.media.zlm.dto.*;
import com.genersoft.iot.vmp.media.zlm.dto.HookType;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
import com.genersoft.iot.vmp.media.zlm.dto.hook.*; import com.genersoft.iot.vmp.media.zlm.dto.hook.*;
import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.service.*;
import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
@ -392,9 +395,7 @@ public class ZLMHttpHookListener {
mediaServerService.removeCount(param.getMediaServerId()); mediaServerService.removeCount(param.getMediaServerId());
} }
int updateStatusResult = streamProxyService.updateStatus(param.isRegist(), param.getApp(), param.getStream()); streamProxyService.updatePullingStatus(param.isRegist(), param.getApp(), param.getStream());
if (updateStatusResult > 0) {
}
if ("rtp".equals(param.getApp())) { if ("rtp".equals(param.getApp())) {
if (!param.isRegist()) { if (!param.isRegist()) {
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, param.getStream()); InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, param.getStream());
@ -533,11 +534,11 @@ public class ZLMHttpHookListener {
cmder.streamByeCmd(device, sendRtpItem.getChannelId(), param.getStream(), sendRtpItem.getCallId()); cmder.streamByeCmd(device, sendRtpItem.getChannelId(), param.getStream(), sendRtpItem.getCallId());
if (sendRtpItem.getPlayType().equals(InviteStreamType.BROADCAST) if (sendRtpItem.getPlayType().equals(InviteStreamType.BROADCAST)
|| sendRtpItem.getPlayType().equals(InviteStreamType.TALK)) { || sendRtpItem.getPlayType().equals(InviteStreamType.TALK)) {
AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDestId(), sendRtpItem.getChannelId());
if (audioBroadcastCatch != null) { if (audioBroadcastCatch != null) {
// 来自上级平台的停止对讲 // 来自上级平台的停止对讲
logger.info("[停止对讲] 来自上级,平台:{}, 通道:{}", sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); logger.info("[停止对讲] 来自上级,平台:{}, 通道:{}", sendRtpItem.getDestId(), sendRtpItem.getChannelId());
audioBroadcastManager.del(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); audioBroadcastManager.del(sendRtpItem.getDestId(), sendRtpItem.getChannelId());
} }
} }
} }
@ -590,7 +591,7 @@ public class ZLMHttpHookListener {
streamSendManager.remove(sendRtpItem); streamSendManager.remove(sendRtpItem);
if (InviteStreamType.PUSH == sendRtpItem.getPlayType()) { if (InviteStreamType.PUSH == sendRtpItem.getPlayType()) {
MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0, MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0,
sendRtpItem.getApp(), sendRtpItem.getStreamId(), sendRtpItem.getChannelId(), sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getChannelId(),
sendRtpItem.getDestId(), parentPlatform.getName(), userSetting.getServerId(), sendRtpItem.getMediaServerId()); sendRtpItem.getDestId(), parentPlatform.getName(), userSetting.getServerId(), sendRtpItem.getMediaServerId());
messageForPushChannel.setPlatFormIndex(parentPlatform.getId()); messageForPushChannel.setPlatFormIndex(parentPlatform.getId());
redisCatchStorage.sendPlatformStopPlayMsg(messageForPushChannel); redisCatchStorage.sendPlatformStopPlayMsg(messageForPushChannel);
@ -622,11 +623,15 @@ public class ZLMHttpHookListener {
storager.stopPlay(inviteInfo.getDeviceId(), inviteInfo.getChannelId()); storager.stopPlay(inviteInfo.getDeviceId(), inviteInfo.getChannelId());
return ret; return ret;
} }
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, param.getStream(), null); List<SendRtpItem> sendRtpItemList = streamSendManager.getByAppAndStream(param.getApp(), param.getStream());
if (sendRtpItemList != null && !sendRtpItemList.isEmpty()) {
for (SendRtpItem sendRtpItem : sendRtpItemList) {
if (sendRtpItem != null && "talk".equals(sendRtpItem.getApp())) { if (sendRtpItem != null && "talk".equals(sendRtpItem.getApp())) {
ret.put("close", false); ret.put("close", false);
return ret; return ret;
} }
}
}
} else if ("talk".equals(param.getApp()) || "broadcast".equals(param.getApp())) { } else if ("talk".equals(param.getApp()) || "broadcast".equals(param.getApp())) {
ret.put("close", false); ret.put("close", false);
} else { } else {

View File

@ -1,11 +1,8 @@
package com.genersoft.iot.vmp.media.zlm.impl; package com.genersoft.iot.vmp.media.zlm.impl;
import com.genersoft.iot.vmp.common.VideoManagerConstants;
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
import com.genersoft.iot.vmp.media.zlm.IStreamSendManager; import com.genersoft.iot.vmp.media.zlm.IStreamSendManager;
import com.genersoft.iot.vmp.utils.redis.RedisUtil; import com.genersoft.iot.vmp.utils.redis.RedisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -39,8 +36,8 @@ public class StreamSendManagerImpl implements IStreamSendManager {
if (sendRtpItem.getCallId() != null) { if (sendRtpItem.getCallId() != null) {
redisTemplate.opsForValue().set(getCallIdKey(sendRtpItem.getCallId()), dateId); redisTemplate.opsForValue().set(getCallIdKey(sendRtpItem.getCallId()), dateId);
} }
if (sendRtpItem.getApp() != null && sendRtpItem.getStreamId() != null) { if (sendRtpItem.getApp() != null && sendRtpItem.getStream() != null) {
redisTemplate.opsForSet().add(getAppAndStreamKey(sendRtpItem.getApp(), sendRtpItem.getStreamId()), dateId); redisTemplate.opsForSet().add(getAppAndStreamKey(sendRtpItem.getApp(), sendRtpItem.getStream()), dateId);
} }
if (sendRtpItem.getMediaServerId() != null) { if (sendRtpItem.getMediaServerId() != null) {
redisTemplate.opsForSet().add(getMediaServerIdKey(sendRtpItem.getMediaServerId()), dateId); redisTemplate.opsForSet().add(getMediaServerIdKey(sendRtpItem.getMediaServerId()), dateId);
@ -156,8 +153,8 @@ public class StreamSendManagerImpl implements IStreamSendManager {
if (sendRtpItem.getCallId() != null) { if (sendRtpItem.getCallId() != null) {
redisTemplate.delete(getCallIdKey(sendRtpItem.getCallId())); redisTemplate.delete(getCallIdKey(sendRtpItem.getCallId()));
} }
if (sendRtpItem.getApp() != null && sendRtpItem.getStreamId() != null) { if (sendRtpItem.getApp() != null && sendRtpItem.getStream() != null) {
redisTemplate.opsForSet().remove(getAppAndStreamKey(sendRtpItem.getApp(), sendRtpItem.getStreamId()), dateId); redisTemplate.opsForSet().remove(getAppAndStreamKey(sendRtpItem.getApp(), sendRtpItem.getStream()), dateId);
} }
if (sendRtpItem.getMediaServerId() != null) { if (sendRtpItem.getMediaServerId() != null) {
redisTemplate.opsForSet().remove(getMediaServerIdKey(sendRtpItem.getMediaServerId()), dateId); redisTemplate.opsForSet().remove(getMediaServerIdKey(sendRtpItem.getMediaServerId()), dateId);

View File

@ -1,6 +1,5 @@
package com.genersoft.iot.vmp.service; package com.genersoft.iot.vmp.service;
import com.alibaba.fastjson2.JSONArray;
import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
@ -34,14 +33,6 @@ public interface IMediaService {
*/ */
StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaServerItem, String app, String stream, Object tracks, String callId); StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaServerItem, String app, String stream, Object tracks, String callId);
/**
* ID, ip使访ipzlmwvp
* @param app
* @param stream
* @return
*/
StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Object tracks, String addr, String callId);
/** /**
* *
*/ */

View File

@ -12,16 +12,11 @@ import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask;
import com.genersoft.iot.vmp.gb28181.task.impl.CatalogSubscribeTask; import com.genersoft.iot.vmp.gb28181.task.impl.CatalogSubscribeTask;
import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeTask; import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeTask;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd.CatalogResponseMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd.CatalogResponseMessageHandler;
import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.media.zlm.IStreamSendManager;
import com.genersoft.iot.vmp.service.bean.Group;
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.service.IDeviceChannelService; import com.genersoft.iot.vmp.service.*;
import com.genersoft.iot.vmp.service.IDeviceService;
import com.genersoft.iot.vmp.service.IInviteStreamService;
import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
import com.genersoft.iot.vmp.storager.dao.DeviceMapper; import com.genersoft.iot.vmp.storager.dao.DeviceMapper;
@ -36,7 +31,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
@ -56,8 +50,6 @@ public class DeviceServiceImpl implements IDeviceService {
private final static Logger logger = LoggerFactory.getLogger(DeviceServiceImpl.class); private final static Logger logger = LoggerFactory.getLogger(DeviceServiceImpl.class);
@Autowired
private SIPCommander cmder;
@Autowired @Autowired
private DynamicTask dynamicTask; private DynamicTask dynamicTask;
@ -110,6 +102,9 @@ public class DeviceServiceImpl implements IDeviceService {
@Autowired @Autowired
private ZLMRESTfulUtils zlmresTfulUtils; private ZLMRESTfulUtils zlmresTfulUtils;
@Autowired
private IStreamSendManager streamSendManager;
@Override @Override
public void online(Device device, SipTransactionInfo sipTransactionInfo) { public void online(Device device, SipTransactionInfo sipTransactionInfo) {
logger.info("[设备上线] deviceId{}->{}:{}", device.getDeviceId(), device.getIp(), device.getPort()); logger.info("[设备上线] deviceId{}->{}:{}", device.getDeviceId(), device.getIp(), device.getPort());
@ -250,13 +245,17 @@ public class DeviceServiceImpl implements IDeviceService {
removeCatalogSubscribe(device, null); removeCatalogSubscribe(device, null);
removeMobilePositionSubscribe(device, null); removeMobilePositionSubscribe(device, null);
// 清理语音对讲
List<AudioBroadcastCatch> audioBroadcastCatches = audioBroadcastManager.get(deviceId); List<AudioBroadcastCatch> audioBroadcastCatches = audioBroadcastManager.get(deviceId);
if (audioBroadcastCatches.size() > 0) { if (!audioBroadcastCatches.isEmpty()) {
for (AudioBroadcastCatch audioBroadcastCatch : audioBroadcastCatches) { for (AudioBroadcastCatch audioBroadcastCatch : audioBroadcastCatches) {
if (ObjectUtils.isEmpty(audioBroadcastCatch.getCallId())) {
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(deviceId, audioBroadcastCatch.getChannelId(), null, null); audioBroadcastManager.del(deviceId, audioBroadcastCatch.getChannelId());
continue;
}
SendRtpItem sendRtpItem = streamSendManager.getByCallId(audioBroadcastCatch.getCallId());
if (sendRtpItem != null) { if (sendRtpItem != null) {
redisCatchStorage.deleteSendRTPServer(deviceId, sendRtpItem.getChannelId(), null, null); streamSendManager.remove(sendRtpItem);
MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
Map<String, Object> param = new HashMap<>(); Map<String, Object> param = new HashMap<>();
param.put("vhost", "__defaultVhost__"); param.put("vhost", "__defaultVhost__");
@ -264,8 +263,8 @@ public class DeviceServiceImpl implements IDeviceService {
param.put("stream", sendRtpItem.getStream()); param.put("stream", sendRtpItem.getStream());
zlmresTfulUtils.stopSendRtp(mediaInfo, param); zlmresTfulUtils.stopSendRtp(mediaInfo, param);
} }
audioBroadcastManager.del(deviceId, audioBroadcastCatch.getChannelId()); audioBroadcastManager.del(deviceId, audioBroadcastCatch.getChannelId());
} }
} }
} }

View File

@ -1,6 +1,5 @@
package com.genersoft.iot.vmp.service.impl; package com.genersoft.iot.vmp.service.impl;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.common.StreamInfo;
@ -13,8 +12,6 @@ import com.genersoft.iot.vmp.media.zlm.dto.StreamPush;
import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.service.IMediaService; import com.genersoft.iot.vmp.service.IMediaService;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
import com.genersoft.iot.vmp.service.IMediaService;
import com.genersoft.iot.vmp.storager.dao.StreamProxyMapper; import com.genersoft.iot.vmp.storager.dao.StreamProxyMapper;
import com.genersoft.iot.vmp.storager.dao.StreamPushMapper; import com.genersoft.iot.vmp.storager.dao.StreamPushMapper;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -142,3 +139,4 @@ public class MediaServiceImpl implements IMediaService {
return result; return result;
} }
} }

View File

@ -1,12 +1,8 @@
package com.genersoft.iot.vmp.service.impl; package com.genersoft.iot.vmp.service.impl;
import com.genersoft.iot.vmp.common.CommonGbChannel;
import com.genersoft.iot.vmp.common.VideoManagerConstants;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.genersoft.iot.vmp.common.InviteInfo;
import com.genersoft.iot.vmp.common.InviteSessionStatus;
import com.genersoft.iot.vmp.common.InviteSessionType;
import com.baomidou.dynamic.datasource.annotation.DS; import com.baomidou.dynamic.datasource.annotation.DS;
import com.genersoft.iot.vmp.common.*;
import com.genersoft.iot.vmp.conf.DynamicTask; import com.genersoft.iot.vmp.conf.DynamicTask;
import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.UserSetting;
import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.exception.ControllerException;
@ -19,26 +15,19 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
import com.genersoft.iot.vmp.gb28181.utils.SipUtils; import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
import com.genersoft.iot.vmp.media.zlm.IStreamSendManager; import com.genersoft.iot.vmp.media.zlm.IStreamSendManager;
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;
import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange;
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
import com.genersoft.iot.vmp.service.IInviteStreamService; import com.genersoft.iot.vmp.service.*;
import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.service.IPlatformChannelService;
import com.genersoft.iot.vmp.service.IPlatformService;
import com.genersoft.iot.vmp.service.IPlayService;
import com.genersoft.iot.vmp.service.bean.*; import com.genersoft.iot.vmp.service.bean.*;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.dao.*; import com.genersoft.iot.vmp.storager.dao.CommonChannelMapper;
import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper;
import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.utils.DateUtil;
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import gov.nist.javax.sip.message.SIPRequest;
import gov.nist.javax.sip.message.SIPResponse; import gov.nist.javax.sip.message.SIPResponse;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -48,17 +37,8 @@ import org.springframework.stereotype.Service;
import javax.sdp.*; import javax.sdp.*;
import javax.sip.InvalidArgumentException; import javax.sip.InvalidArgumentException;
import javax.sip.ResponseEvent; import javax.sip.ResponseEvent;
import javax.sip.PeerUnavailableException;
import javax.sip.SipException; import javax.sip.SipException;
import java.text.ParseException; import java.text.ParseException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.*; import java.util.*;
/** /**
@ -86,8 +66,6 @@ public class PlatformServiceImpl implements IPlatformService {
@Autowired @Autowired
private IStreamSendManager streamSendManager; private IStreamSendManager streamSendManager;
@Autowired
private IRedisCatchStorage redisCatchStorage;
@Autowired @Autowired
private SSRCFactory ssrcFactory; private SSRCFactory ssrcFactory;

View File

@ -18,51 +18,25 @@ import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager;
import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; import com.genersoft.iot.vmp.gb28181.session.SSRCFactory;
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
import com.genersoft.iot.vmp.gb28181.utils.SipUtils; import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
import com.genersoft.iot.vmp.media.zlm.IStreamSendManager;
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
import com.genersoft.iot.vmp.media.zlm.dto.*;
import com.genersoft.iot.vmp.media.zlm.*; import com.genersoft.iot.vmp.media.zlm.*;
import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;
import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;
import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRecordMp4; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRecordMp4;
import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam;
import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam;
import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
import com.genersoft.iot.vmp.service.IInviteStreamService;
import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.service.IMediaService;
import com.genersoft.iot.vmp.service.IPlayService;
import com.genersoft.iot.vmp.service.bean.DownloadFileInfo;
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.service.*;
import com.genersoft.iot.vmp.service.bean.*; import com.genersoft.iot.vmp.service.bean.*;
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
import com.genersoft.iot.vmp.service.bean.RequestPushStreamMsg;
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener; import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener;
import com.genersoft.iot.vmp.service.bean.DownloadFileInfo;
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
import com.genersoft.iot.vmp.storager.dao.CloudRecordServiceMapper;
import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
import com.genersoft.iot.vmp.storager.dao.DeviceMapper; import com.genersoft.iot.vmp.storager.dao.DeviceMapper;
import com.genersoft.iot.vmp.storager.dao.CloudRecordServiceMapper;
import com.genersoft.iot.vmp.utils.CloudRecordUtils; import com.genersoft.iot.vmp.utils.CloudRecordUtils;
import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.utils.DateUtil;
import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult; import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult;
@ -265,8 +239,8 @@ public class PlayServiceImpl implements IPlayService {
sendRtpItem.setApp("talk"); sendRtpItem.setApp("talk");
sendRtpItem.setStream(stream); sendRtpItem.setStream(stream);
sendRtpItem.setSsrc(playSsrc); sendRtpItem.setSsrc(playSsrc);
sendRtpItem.setDeviceId(device.getDeviceId()); sendRtpItem.setDestId(device.getDeviceId());
sendRtpItem.setPlatformId(device.getDeviceId()); sendRtpItem.setSourceId(sipConfig.getId());
sendRtpItem.setChannelId(channelId); sendRtpItem.setChannelId(channelId);
sendRtpItem.setRtcp(false); sendRtpItem.setRtcp(false);
sendRtpItem.setMediaServerId(mediaServerItem.getId()); sendRtpItem.setMediaServerId(mediaServerItem.getId());
@ -352,7 +326,7 @@ public class PlayServiceImpl implements IPlayService {
sendRtpItem.setFromTag(response.getFromTag()); sendRtpItem.setFromTag(response.getFromTag());
sendRtpItem.setToTag(response.getToTag()); sendRtpItem.setToTag(response.getToTag());
sendRtpItem.setCallId(response.getCallIdHeader().getCallId()); sendRtpItem.setCallId(response.getCallIdHeader().getCallId());
redisCatchStorage.updateSendRTPSever(sendRtpItem); streamSendManager.update(sendRtpItem);
streamSession.put(device.getDeviceId(), channelId, "talk", streamSession.put(device.getDeviceId(), channelId, "talk",
sendRtpItem.getStream(), sendRtpItem.getSsrc(), sendRtpItem.getMediaServerId(), sendRtpItem.getStream(), sendRtpItem.getSsrc(), sendRtpItem.getMediaServerId(),
@ -453,8 +427,8 @@ public class PlayServiceImpl implements IPlayService {
streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream());
mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream()); mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
// 取消订阅消息监听 // 取消订阅消息监听
HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId()); HookSubscribeForStreamChange hookSubscribeForStreamChange = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId());
subscribe.removeSubscribe(hookSubscribe); subscribe.removeSubscribe(hookSubscribeForStreamChange);
} }
}else { }else {
logger.info("[点播超时] 收流超时 deviceId: {}, channelId: {},码流:{},端口:{}, SSRC: {}", logger.info("[点播超时] 收流超时 deviceId: {}, channelId: {},码流:{},端口:{}, SSRC: {}",
@ -517,8 +491,8 @@ public class PlayServiceImpl implements IPlayService {
// 释放ssrc // 释放ssrc
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream());
inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId); inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channel.getChannelId());
try { try {
callback.run(InviteErrorCode.ERROR_FOR_SIGNALLING_ERROR.getCode(), callback.run(InviteErrorCode.ERROR_FOR_SIGNALLING_ERROR.getCode(),
@ -527,7 +501,7 @@ public class PlayServiceImpl implements IPlayService {
logger.warn("[invite] 发送回调失败", e); logger.warn("[invite] 发送回调失败", e);
} }
try { try {
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null, inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channel.getChannelId(), null,
InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(), InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(),
String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg), null); String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg), null);
}catch (Exception e) { }catch (Exception e) {
@ -551,7 +525,7 @@ public class PlayServiceImpl implements IPlayService {
logger.warn("[invite] 发送回调失败", exception); logger.warn("[invite] 发送回调失败", exception);
} }
try { try {
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null, inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channel.getChannelId(), null,
InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getCode(), InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getCode(),
InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getMsg(), null); InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getMsg(), null);
}catch (Exception exception) { }catch (Exception exception) {
@ -1236,9 +1210,10 @@ public class PlayServiceImpl implements IPlayService {
event.call("开启语音广播的时候未找到通道"); event.call("开启语音广播的时候未找到通道");
return false; return false;
} }
AudioBroadcastCatch audioBroadcastCatchInCatch = audioBroadcastManager.get(device.getDeviceId(), channelId);
// 查询通道使用状态 // 查询通道使用状态
if (audioBroadcastManager.exit(device.getDeviceId(), channelId)) { if (audioBroadcastCatchInCatch != null && audioBroadcastCatchInCatch.getCallId() != null) {
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(device.getDeviceId(), channelId, null, null); SendRtpItem sendRtpItem = streamSendManager.getByCallId(audioBroadcastCatchInCatch.getCallId());
if (sendRtpItem != null && sendRtpItem.isOnlyAudio()) { if (sendRtpItem != null && sendRtpItem.isOnlyAudio()) {
// 查询流是否存在,不存在则认为是异常状态 // 查询流是否存在,不存在则认为是异常状态
Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, sendRtpItem.getApp(), sendRtpItem.getStream()); Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, sendRtpItem.getApp(), sendRtpItem.getStream());
@ -1280,8 +1255,9 @@ public class PlayServiceImpl implements IPlayService {
@Override @Override
public boolean audioBroadcastInUse(Device device, String channelId) { public boolean audioBroadcastInUse(Device device, String channelId) {
if (audioBroadcastManager.exit(device.getDeviceId(), channelId)) { AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(device.getDeviceId(), channelId);
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(device.getDeviceId(), channelId, null, null); if (audioBroadcastCatch != null) {
SendRtpItem sendRtpItem = streamSendManager.getByCallId(audioBroadcastCatch.getCallId());
if (sendRtpItem != null && sendRtpItem.isOnlyAudio()) { if (sendRtpItem != null && sendRtpItem.isOnlyAudio()) {
// 查询流是否存在,不存在则认为是异常状态 // 查询流是否存在,不存在则认为是异常状态
MediaServerItem mediaServerServiceOne = mediaServerService.getOne(sendRtpItem.getMediaServerId()); MediaServerItem mediaServerServiceOne = mediaServerService.getOne(sendRtpItem.getMediaServerId());
@ -1300,20 +1276,24 @@ public class PlayServiceImpl implements IPlayService {
public void stopAudioBroadcast(String deviceId, String channelId) { public void stopAudioBroadcast(String deviceId, String channelId) {
logger.info("[停止对讲] 设备:{}, 通道:{}", deviceId, channelId); logger.info("[停止对讲] 设备:{}, 通道:{}", deviceId, channelId);
List<AudioBroadcastCatch> audioBroadcastCatchList = new ArrayList<>(); List<AudioBroadcastCatch> audioBroadcastCatchList = new ArrayList<>();
Device device = deviceService.getDevice(deviceId);
if (device == null) {
return;
}
if (channelId == null) { if (channelId == null) {
audioBroadcastCatchList.addAll(audioBroadcastManager.get(deviceId)); audioBroadcastCatchList.addAll(audioBroadcastManager.get(deviceId));
} else { } else {
audioBroadcastCatchList.add(audioBroadcastManager.get(deviceId, channelId)); audioBroadcastCatchList.add(audioBroadcastManager.get(deviceId, channelId));
} }
if (audioBroadcastCatchList.size() > 0) { if (!audioBroadcastCatchList.isEmpty()) {
for (AudioBroadcastCatch audioBroadcastCatch : audioBroadcastCatchList) { for (AudioBroadcastCatch audioBroadcastCatch : audioBroadcastCatchList) {
Device device = deviceService.getDevice(deviceId); if (audioBroadcastCatch == null) {
if (device == null || audioBroadcastCatch == null) { continue;
return;
} }
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(deviceId, audioBroadcastCatch.getChannelId(), null, null); if (audioBroadcastCatch.getCallId() != null) {
SendRtpItem sendRtpItem = streamSendManager.getByCallId(audioBroadcastCatch.getCallId());
if (sendRtpItem != null) { if (sendRtpItem != null) {
redisCatchStorage.deleteSendRTPServer(deviceId, sendRtpItem.getChannelId(), null, null); streamSendManager.remove(sendRtpItem);
MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
Map<String, Object> param = new HashMap<>(); Map<String, Object> param = new HashMap<>();
param.put("vhost", "__defaultVhost__"); param.put("vhost", "__defaultVhost__");
@ -1327,7 +1307,7 @@ public class PlayServiceImpl implements IPlayService {
logger.error("[消息发送失败] 发送语音喊话BYE失败"); logger.error("[消息发送失败] 发送语音喊话BYE失败");
} }
} }
}
audioBroadcastManager.del(deviceId, channelId); audioBroadcastManager.del(deviceId, channelId);
} }
} }
@ -1513,8 +1493,8 @@ public class PlayServiceImpl implements IPlayService {
} else { } else {
logger.error("RTP推流失败: {}, 参数:{}", jsonObject.getString("msg"), JSONObject.toJSONString(param)); logger.error("RTP推流失败: {}, 参数:{}", jsonObject.getString("msg"), JSONObject.toJSONString(param));
if (sendRtpItem.isOnlyAudio()) { if (sendRtpItem.isOnlyAudio()) {
Device device = deviceService.getDevice(sendRtpItem.getDeviceId()); Device device = deviceService.getDevice(sendRtpItem.getDestId());
AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDestId(), sendRtpItem.getChannelId());
if (audioBroadcastCatch != null) { if (audioBroadcastCatch != null) {
try { try {
cmder.streamByeCmd(device, sendRtpItem.getChannelId(), audioBroadcastCatch.getSipTransactionInfo(), null); cmder.streamByeCmd(device, sendRtpItem.getChannelId(), audioBroadcastCatch.getSipTransactionInfo(), null);
@ -1551,8 +1531,9 @@ public class PlayServiceImpl implements IPlayService {
return; return;
} }
// 查询通道使用状态 // 查询通道使用状态
if (audioBroadcastManager.exit(device.getDeviceId(), channelId)) { AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(device.getDeviceId(), channelId);
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(device.getDeviceId(), channelId, null, null); if (audioBroadcastCatch != null && audioBroadcastCatch.getCallId() != null) {
SendRtpItem sendRtpItem = streamSendManager.getByCallId(audioBroadcastCatch.getCallId());
if (sendRtpItem != null && sendRtpItem.isOnlyAudio()) { if (sendRtpItem != null && sendRtpItem.isOnlyAudio()) {
// 查询流是否存在,不存在则认为是异常状态 // 查询流是否存在,不存在则认为是异常状态
MediaServerItem mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId()); MediaServerItem mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId());
@ -1567,19 +1548,6 @@ public class PlayServiceImpl implements IPlayService {
} }
} }
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(device.getDeviceId(), channelId, stream, null);
if (sendRtpItem != null) {
MediaServerItem mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId());
Boolean streamReady = zlmServerFactory.isStreamReady(mediaServer, "rtp", sendRtpItem.getReceiveStream());
if (streamReady) {
logger.warn("[语音对讲] 进行中: {}", channelId);
event.call("语音对讲进行中");
return;
} else {
stopTalk(device, channelId);
}
}
talk(mediaServerItem, device, channelId, stream, (mediaServerItem1, hookParam) -> { talk(mediaServerItem, device, channelId, stream, (mediaServerItem1, hookParam) -> {
logger.info("[语音对讲] 收到设备发来的流"); logger.info("[语音对讲] 收到设备发来的流");
}, eventResult -> { }, eventResult -> {
@ -1603,7 +1571,11 @@ public class PlayServiceImpl implements IPlayService {
@Override @Override
public void stopTalk(Device device, String channelId, Boolean streamIsReady) { public void stopTalk(Device device, String channelId, Boolean streamIsReady) {
logger.info("[语音对讲] 停止, {}/{}", device.getDeviceId(), channelId); logger.info("[语音对讲] 停止, {}/{}", device.getDeviceId(), channelId);
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(device.getDeviceId(), channelId, null, null); AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(device.getDeviceId(), channelId);
if (audioBroadcastCatch == null || audioBroadcastCatch.getCallId() == null) {
return;
}
SendRtpItem sendRtpItem = streamSendManager.getByCallId(audioBroadcastCatch.getCallId());
if (sendRtpItem == null) { if (sendRtpItem == null) {
logger.info("[语音对讲] 停止失败, 未找到发送信息,可能已经停止"); logger.info("[语音对讲] 停止失败, 未找到发送信息,可能已经停止");
return; return;
@ -1635,7 +1607,7 @@ public class PlayServiceImpl implements IPlayService {
logger.info("[语音对讲] 停止消息发送失败,可能已经停止"); logger.info("[语音对讲] 停止消息发送失败,可能已经停止");
} }
} }
redisCatchStorage.deleteSendRTPServer(device.getDeviceId(), channelId,null, null); streamSendManager.remove(sendRtpItem);
} }
@Override @Override

View File

@ -103,7 +103,7 @@ public class RedisPushStreamCloseResponseListener implements MessageListener {
zlmServerFactory.stopSendRtpStream(mediaInfo, param); zlmServerFactory.stopSendRtpStream(mediaInfo, param);
if (InviteStreamType.PUSH == sendRtpItem.getPlayType()) { if (InviteStreamType.PUSH == sendRtpItem.getPlayType()) {
MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0, MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0,
sendRtpItem.getApp(), sendRtpItem.getStreamId(), sendRtpItem.getChannelId(), sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getChannelId(),
sendRtpItem.getDestId(), parentPlatform.getName(), userSetting.getServerId(), sendRtpItem.getMediaServerId()); sendRtpItem.getDestId(), parentPlatform.getName(), userSetting.getServerId(), sendRtpItem.getMediaServerId());
messageForPushChannel.setPlatFormIndex(parentPlatform.getId()); messageForPushChannel.setPlatFormIndex(parentPlatform.getId());
redisCatchStorage.sendPlatformStopPlayMsg(messageForPushChannel); redisCatchStorage.sendPlatformStopPlayMsg(messageForPushChannel);

View File

@ -380,62 +380,62 @@ public class CommonChannelController {
@RequestMapping(value = "/fi", method = {RequestMethod.GET, RequestMethod.POST}) @RequestMapping(value = "/fi", method = {RequestMethod.GET, RequestMethod.POST})
public void fi(String channelDeviceId, String command, int speed){ public void fi(String channelDeviceId, String command, int speed){
if (logger.isDebugEnabled()) { // if (logger.isDebugEnabled()) {
logger.debug("通用通道光圈控制和聚焦控制 API调用channelDeviceId{} command{} speed{}", channelDeviceId, command, speed); // logger.debug("通用通道光圈控制和聚焦控制 API调用channelDeviceId{} command{} speed{}", channelDeviceId, command, speed);
} // }
assert !ObjectUtils.isEmpty(channelDeviceId); // assert !ObjectUtils.isEmpty(channelDeviceId);
//
CommonGbChannel channel = commonGbChannelService.getChannel(channelDeviceId); // CommonGbChannel channel = commonGbChannelService.getChannel(channelDeviceId);
assert channel != null; // assert channel != null;
//
PTZCommand ptzCommand = new PTZCommand(); // PTZCommand ptzCommand = new PTZCommand();
ptzCommand.setzSpeed(zoomSpeed); // ptzCommand.setzSpeed(zoomSpeed);
ptzCommand.setxSpeed(horizonSpeed); // ptzCommand.setxSpeed(horizonSpeed);
ptzCommand.setySpeed(verticalSpeed); // ptzCommand.setySpeed(verticalSpeed);
switch (command){ // switch (command){
case "left": // case "left":
ptzCommand.setLeft(true); // ptzCommand.setLeft(true);
break; // break;
case "right": // case "right":
ptzCommand.setRight(true); // ptzCommand.setRight(true);
break; // break;
case "up": // case "up":
ptzCommand.setUp(true); // ptzCommand.setUp(true);
break; // break;
case "down": // case "down":
ptzCommand.setDown(true); // ptzCommand.setDown(true);
break; // break;
case "upleft": // case "upleft":
ptzCommand.setUp(true); // ptzCommand.setUp(true);
ptzCommand.setLeft(true); // ptzCommand.setLeft(true);
break; // break;
case "upright": // case "upright":
ptzCommand.setUp(true); // ptzCommand.setUp(true);
ptzCommand.setRight(true); // ptzCommand.setRight(true);
break; // break;
case "downleft": // case "downleft":
ptzCommand.setDown(true); // ptzCommand.setDown(true);
ptzCommand.setLeft(true); // ptzCommand.setLeft(true);
break; // break;
case "downright": // case "downright":
ptzCommand.setDown(true); // ptzCommand.setDown(true);
ptzCommand.setRight(true); // ptzCommand.setRight(true);
break; // break;
case "zoomin": // case "zoomin":
ptzCommand.setIn(true); // ptzCommand.setIn(true);
break; // break;
case "zoomout": // case "zoomout":
ptzCommand.setOut(true); // ptzCommand.setOut(true);
break; // break;
case "stop": // case "stop":
ptzCommand.setzSpeed(0); // ptzCommand.setzSpeed(0);
ptzCommand.setxSpeed(0); // ptzCommand.setxSpeed(0);
ptzCommand.setySpeed(0); // ptzCommand.setySpeed(0);
break; // break;
default: // default:
break; // break;
} // }
commonGbChannelService.ptzControl(channel, ptzCommand); // commonGbChannelService.ptzControl(channel, ptzCommand);
} }
// 获取通用通道对应的原始资源信息 // 获取通用通道对应的原始资源信息

View File

@ -31,7 +31,6 @@ create table wvp_device (
password character varying(255), password character varying(255),
as_message_channel bool default false, as_message_channel bool default false,
keepalive_interval_time integer, keepalive_interval_time integer,
switch_primary_sub_stream bool default false,
broadcast_push_after_ack bool default false, broadcast_push_after_ack bool default false,
constraint uk_device_device unique (device_id) constraint uk_device_device unique (device_id)
); );
@ -92,6 +91,7 @@ create table wvp_device_channel (
latitude_wgs84 double precision, latitude_wgs84 double precision,
business_group_id character varying(50), business_group_id character varying(50),
gps_time character varying(50), gps_time character varying(50),
stream_identification character varying(50),
constraint uk_wvp_device_channel_unique_device_channel unique (device_id, channel_id) constraint uk_wvp_device_channel_unique_device_channel unique (device_id, channel_id)
); );

View File

@ -31,7 +31,6 @@ create table wvp_device (
password character varying(255), password character varying(255),
as_message_channel bool default false, as_message_channel bool default false,
keepalive_interval_time integer, keepalive_interval_time integer,
switch_primary_sub_stream bool default false,
broadcast_push_after_ack bool default false, broadcast_push_after_ack bool default false,
constraint uk_device_device unique (device_id) constraint uk_device_device unique (device_id)
); );
@ -92,6 +91,7 @@ create table wvp_device_channel (
latitude_wgs84 double precision, latitude_wgs84 double precision,
business_group_id character varying(50), business_group_id character varying(50),
gps_time character varying(50), gps_time character varying(50),
stream_identification character varying(50),
common_gb_channel_id integer, common_gb_channel_id integer,
constraint uk_wvp_device_channel_unique_device_channel unique (device_id, channel_id) constraint uk_wvp_device_channel_unique_device_channel unique (device_id, channel_id)
); );