合并主线

结构优化
648540858 2022-11-18 21:52:02 +08:00
parent f223aad705
commit ecf84bb0f1
28 changed files with 231 additions and 350 deletions

View File

@ -223,8 +223,8 @@ public class StreamInfo implements Serializable, Cloneable{
}
}
public void setRtc(String host, int port, int sslPort, String app, String stream, String callIdParam) {
String file = String.format("index/api/webrtc?app=%s&stream=%s&type=play%s", app, stream, callIdParam);
public void setRtc(String host, int port, int sslPort, String app, String stream, String callIdParam, boolean isPlay) {
String file = String.format("index/api/webrtc?app=%s&stream=%s&type=%s%s", app, stream, callIdParam, isPlay?"play":"push");
this.rtc = new StreamURL("http", host, port, file);
if (sslPort != 0) {
this.rtcs = new StreamURL("https", host, sslPort, file);

View File

@ -94,9 +94,4 @@ public class SipConfig {
this.alarm = alarm;
}
public void getLocalIp(String deviceLocalIp) {
if (ObjectUtils.isEmpty(deviceLocalIp)) {
}
}
}

View File

@ -31,7 +31,7 @@ public class UserSetting {
private Boolean logInDatebase = Boolean.TRUE;
private Boolean usePushingAsStatus = Boolean.TRUE;
private Boolean usePushingAsStatus = Boolean.FALSE;
private Boolean useSourceIpAsStreamIp = Boolean.FALSE;

View File

@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181.session;
import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.gb28181.bean.AudioBroadcastCatch;
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -27,11 +28,20 @@ public class AudioBroadcastManager {
}
public void update(AudioBroadcastCatch audioBroadcastCatch) {
data.put(audioBroadcastCatch.getDeviceId() + audioBroadcastCatch.getChannelId(), audioBroadcastCatch);
if (SipUtils.isFrontEnd(audioBroadcastCatch.getDeviceId())) {
data.put(audioBroadcastCatch.getDeviceId(), audioBroadcastCatch);
}else {
data.put(audioBroadcastCatch.getDeviceId() + audioBroadcastCatch.getChannelId(), audioBroadcastCatch);
}
}
public void del(String deviceId, String channelId) {
data.remove(deviceId + channelId);
if (SipUtils.isFrontEnd(deviceId)) {
data.remove(deviceId);
}else {
data.remove(deviceId + channelId);
}
}
public void delByDeviceId(String deviceId) {
@ -50,15 +60,22 @@ public class AudioBroadcastManager {
public boolean exit(String deviceId, String channelId) {
for (String key : data.keySet()) {
if (key.equals(deviceId + channelId)) {
return true;
if (SipUtils.isFrontEnd(deviceId)) {
return key.equals(deviceId);
}else {
return key.equals(deviceId + channelId);
}
}
return false;
}
public AudioBroadcastCatch get(String deviceId, String channelId) {
AudioBroadcastCatch audioBroadcastCatch = data.get(deviceId + channelId);
AudioBroadcastCatch audioBroadcastCatch;
if (SipUtils.isFrontEnd(deviceId)) {
audioBroadcastCatch = data.get(deviceId);
}else {
audioBroadcastCatch = data.get(deviceId + channelId);
}
if (audioBroadcastCatch == null) {
Stream<AudioBroadcastCatch> allAudioBroadcastCatchStreamForDevice = data.values().stream().filter(
audioBroadcastCatchItem -> Objects.equals(audioBroadcastCatchItem.getDeviceId(), deviceId));

View File

@ -15,6 +15,7 @@ import javax.sip.SipException;
import javax.sip.message.Message;
import javax.sip.message.Request;
import java.text.ParseException;
import javax.sip.message.Message;
import javax.sip.message.Request;
/**
@ -361,4 +362,5 @@ public interface ISIPCommander {
*/
void sendAlarmMessage(Device device, DeviceAlarm deviceAlarm) throws InvalidArgumentException, SipException, ParseException;
}

View File

@ -318,32 +318,32 @@ public class SIPRequestHeaderProvider {
public Request createBroadcastMessageRequest(Device device, String channelId, String content, String viaTag, String fromTag, String toTag, CallIdHeader callIdHeader) throws ParseException, InvalidArgumentException, PeerUnavailableException {
Request request = null;
// sipuri
SipURI requestURI = sipFactory.createAddressFactory().createSipURI(channelId, device.getHostAddress());
SipURI requestURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(channelId, device.getHostAddress());
// via
ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(sipConfig.getIp(), sipConfig.getPort(), device.getTransport(), viaTag);
ViaHeader viaHeader = sipLayer.getSipFactory().createHeaderFactory().createViaHeader(sipConfig.getIp(), sipConfig.getPort(), device.getTransport(), viaTag);
viaHeader.setRPort();
viaHeaders.add(viaHeader);
// from
SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getDomain());
Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, fromTag);
SipURI fromSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getDomain());
Address fromAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(fromSipURI);
FromHeader fromHeader = sipLayer.getSipFactory().createHeaderFactory().createFromHeader(fromAddress, fromTag);
// to
SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(channelId, device.getHostAddress());
Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, toTag);
SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(channelId, device.getHostAddress());
Address toAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(toSipURI);
ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress, toTag);
// Forwards
MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70);
// ceq
CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.MESSAGE);
CSeqHeader cSeqHeader = sipLayer.getSipFactory().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.MESSAGE);
ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
ContentTypeHeader contentTypeHeader = sipLayer.getSipFactory().createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
request = sipFactory.createMessageFactory().createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader,
request = sipLayer.getSipFactory().createMessageFactory().createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader,
toHeader, viaHeaders, maxForwards, contentTypeHeader, content);
request.addHeader(SipUtils.createUserAgentHeader(sipFactory, gitUtil));
request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil));
return request;
}

View File

@ -19,15 +19,11 @@ 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.media.zlm.dto.HookSubscribeForStreamPush;
import com.genersoft.iot.vmp.utils.DateUtil;
import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
import com.genersoft.iot.vmp.utils.GitUtil;
import gov.nist.javax.sip.SipProviderImpl;
import com.genersoft.iot.vmp.utils.DateUtil;
import com.genersoft.iot.vmp.utils.GitUtil;
import gov.nist.javax.sip.message.SIPRequest;
import gov.nist.javax.sip.message.SIPResponse;
import org.slf4j.Logger;
@ -41,8 +37,6 @@ import javax.sip.InvalidArgumentException;
import javax.sip.ResponseEvent;
import javax.sip.SipException;
import javax.sip.header.CallIdHeader;
import javax.sip.*;
import javax.sip.header.*;
import javax.sip.message.Request;
import java.text.ParseException;
@ -78,6 +72,9 @@ public class SIPCommander implements ISIPCommander {
@Autowired
private ZlmHttpHookSubscribe subscribe;
@Autowired
private GitUtil gitUtil;
@Autowired
@ -607,8 +604,7 @@ public class SIPCommander implements ISIPCommander {
}
});
CallIdHeader callIdHeader = device.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
: udpSipProvider.getNewCallId();
CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()), device.getTransport());
callIdHeader.setCallId(callId);
HookSubscribeForStreamPush hookSubscribeForStreamPush = HookSubscribeFactory.on_publish("rtp", stream, null, mediaServerItem.getId());
subscribe.addSubscribe(hookSubscribeForStreamPush, (MediaServerItem mediaServerItemInUse, JSONObject json) -> {
@ -633,7 +629,7 @@ public class SIPCommander implements ISIPCommander {
content.append("f=v/////a/1/8/1" + "\r\n");
Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, ssrcInfo.getSsrc(), callIdHeader);
transmitRequest(device.getTransport(), request, (e -> {
sipSender.transmitRequest(device.getTransport(), request, (e -> {
streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
errorEvent.response(e);
@ -675,7 +671,7 @@ public class SIPCommander implements ISIPCommander {
@Override
public synchronized void streamByeCmd(Device device, String channelId, SipTransactionInfo sipTransactionInfo, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException, SsrcTransactionNotFoundException {
Request byteRequest = headerProvider.createByteRequest(device, channelId, sipTransactionInfo);
transmitRequest(device.getTransport(), byteRequest, null, okEvent);
sipSender.transmitRequest(device.getTransport(), byteRequest, null, okEvent);
}
/**
@ -695,10 +691,8 @@ public class SIPCommander implements ISIPCommander {
broadcastXml.append("<TargetID>" + channelId + "</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);
sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent, okEvent);
}
@ -1342,8 +1336,6 @@ public class SIPCommander implements ISIPCommander {
/**
*
*/

View File

@ -1,7 +1,6 @@
package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.genersoft.iot.vmp.gb28181.SipLayer;
import com.genersoft.iot.vmp.gb28181.bean.*;
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
@ -9,13 +8,13 @@ import com.genersoft.iot.vmp.gb28181.transmit.SIPSender;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderPlarformProvider;
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
import com.genersoft.iot.vmp.storager.dao.dto.PlatformRegisterInfo;
import com.genersoft.iot.vmp.utils.DateUtil;
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.dao.dto.PlatformRegisterInfo;
import com.genersoft.iot.vmp.utils.DateUtil;
import gov.nist.javax.sip.message.MessageFactoryImpl;
import gov.nist.javax.sip.message.SIPRequest;
import org.slf4j.Logger;
@ -26,10 +25,10 @@ import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import com.genersoft.iot.vmp.utils.DateUtil;
import javax.sip.*;
import javax.sip.header.*;
import javax.sip.InvalidArgumentException;
import javax.sip.SipException;
import javax.sip.header.CallIdHeader;
import javax.sip.header.WWWAuthenticateHeader;
import javax.sip.message.Request;
import java.text.ParseException;
import java.util.ArrayList;
@ -629,21 +628,21 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
logger.info("[向上级发送BYE] sendRtpItem 为NULL");
return;
}
if (parentPlatform == null) {
if (platform == null) {
logger.info("[向上级发送BYE] platform 为NULL");
return;
}
logger.info("[向上级发送BYE] {}/{}", parentPlatform.getServerGBId(), sendRtpItem.getChannelId());
logger.info("[向上级发送BYE] {}/{}", platform.getServerGBId(), sendRtpItem.getChannelId());
String mediaServerId = sendRtpItem.getMediaServerId();
MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
if (mediaServerItem != null) {
mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc());
zlmrtpServerFactory.closeRtpServer(mediaServerItem, sendRtpItem.getStreamId());
}
SIPRequest byeRequest = headerProviderPlatformProvider.createByeRequest(parentPlatform, sendRtpItem);
SIPRequest byeRequest = headerProviderPlatformProvider.createByeRequest(platform, sendRtpItem);
if (byeRequest == null) {
logger.warn("[向上级发送bye]:无法创建 byeRequest");
}
sipSender.transmitRequest(parentPlatform.getDeviceIp(),byeRequest);
sipSender.transmitRequest(platform.getDeviceIp(),byeRequest);
}
}

View File

@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request;
import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
import com.genersoft.iot.vmp.gb28181.transmit.SIPSender;
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
import gov.nist.javax.sip.SipProviderImpl;
@ -17,6 +18,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.core.parameters.P;
import javax.sip.*;
import javax.sip.address.Address;
@ -93,52 +95,6 @@ public abstract class SIPRequestProcessorParent {
return responseAck(sipRequest, statusCode, msg, null);
}
// public SIPResponse responseAck(ServerTransaction serverTransaction, int statusCode, String msg, ResponseAckExtraParam responseAckExtraParam) throws SipException, InvalidArgumentException, ParseException {
// if (serverTransaction == null) {
// logger.warn("[回复消息] ServerTransaction 为null");
// return null;
// }
// ToHeader toHeader = (ToHeader) serverTransaction.getRequest().getHeader(ToHeader.NAME);
// if (toHeader.getTag() == null) {
// toHeader.setTag(SipUtils.getNewTag());
// }
// SIPResponse response = (SIPResponse)getMessageFactory().createResponse(statusCode, serverTransaction.getRequest());
// if (msg != null) {
// response.setReasonPhrase(msg);
// }
// if (responseAckExtraParam != null) {
// if (responseAckExtraParam.sipURI != null && serverTransaction.getRequest().getMethod().equals(Request.INVITE)) {
// logger.debug("responseSdpAck SipURI: {}:{}", responseAckExtraParam.sipURI.getHost(), responseAckExtraParam.sipURI.getPort());
// Address concatAddress = SipFactory.getInstance().createAddressFactory().createAddress(
// SipFactory.getInstance().createAddressFactory().createSipURI(responseAckExtraParam.sipURI.getUser(), responseAckExtraParam.sipURI.getHost()+":"+responseAckExtraParam.sipURI.getPort()
// ));
// response.addHeader(SipFactory.getInstance().createHeaderFactory().createContactHeader(concatAddress));
// }
// if (responseAckExtraParam.contentTypeHeader != null) {
// response.setContent(responseAckExtraParam.content, responseAckExtraParam.contentTypeHeader);
// }
//
// if (serverTransaction.getRequest().getMethod().equals(Request.SUBSCRIBE)) {
// if (responseAckExtraParam.expires == -1) {
// logger.error("[参数不全] 2xx的SUBSCRIBE回复必须设置Expires header");
// }else {
// ExpiresHeader expiresHeader = SipFactory.getInstance().createHeaderFactory().createExpiresHeader(responseAckExtraParam.expires);
// response.addHeader(expiresHeader);
// }
// }
// }else {
// if (serverTransaction.getRequest().getMethod().equals(Request.SUBSCRIBE)) {
// logger.error("[参数不全] 2xx的SUBSCRIBE回复必须设置Expires header");
// }
// }
// serverTransaction.sendResponse(response);
// if (statusCode >= 200 && !"NOTIFY".equalsIgnoreCase(serverTransaction.getRequest().getMethod())) {
// if (serverTransaction.getDialog() != null) {
// serverTransaction.getDialog().delete();
// }
// }
// return response;
// }
public SIPResponse responseAck(SIPRequest sipRequest, int statusCode, String msg, ResponseAckExtraParam responseAckExtraParam) throws SipException, InvalidArgumentException, ParseException {
if (sipRequest.getToHeader().getTag() == null) {
@ -182,6 +138,8 @@ public abstract class SIPRequestProcessorParent {
return response;
}
/**
* sdp200
*/

View File

@ -152,10 +152,10 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
} else if (jsonObject.getInteger("code") == 0) {
logger.info("RTP推流成功[ {}/{} ]{}->{}:{}, ", param.get("app"), param.get("stream"), jsonObject.getString("local_port"), param.get("dst_url"), param.get("dst_port"));
} else {
logger.error("RTP推流失败: {}, 参数:{}", jsonObject.getString("msg"), JSONObject.toJSON(param));
logger.error("RTP推流失败: {}, 参数:{}", jsonObject.getString("msg"), JSON.toJSON(param));
if (sendRtpItem.isOnlyAudio()) {
// 语音对讲
Device device = deviceService.queryDevice(platformGbId);
Device device = deviceService.getDevice(platformGbId);
if (device != null) {
try {
cmder.streamByeCmd(device, sendRtpItem.getChannelId(), sendRtpItem.getStreamId(), null);

View File

@ -111,7 +111,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
if (totalReaderCount <= 0) {
logger.info("[收到bye] {} 无其它观看者,通知设备停止推流", streamId);
if (sendRtpItem.getPlayType().equals(InviteStreamType.PLAY)) {
Device device = deviceService.queryDevice(sendRtpItem.getDeviceId());
Device device = deviceService.getDevice(sendRtpItem.getDeviceId());
if (device == null) {
logger.info("[收到bye] {} 通知设备停止推流时未找到设备信息", streamId);
}

View File

@ -4,19 +4,14 @@ import com.alibaba.fastjson2.JSONObject;
import com.genersoft.iot.vmp.conf.DynamicTask;
import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.conf.UserSetting;
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
import com.genersoft.iot.vmp.gb28181.bean.*;
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager;
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
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.SIPSender;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
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.utils.SipUtils;
@ -25,11 +20,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
import com.genersoft.iot.vmp.media.zlm.dto.*;
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.IStreamProxyService;
import com.genersoft.iot.vmp.service.IStreamPushService;
import com.genersoft.iot.vmp.service.*;
import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener;
@ -37,8 +28,6 @@ import com.genersoft.iot.vmp.service.redisMsg.RedisPushStreamResponseListener;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
import com.genersoft.iot.vmp.utils.DateUtil;
import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult;
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
import gov.nist.javax.sdp.TimeDescriptionImpl;
import gov.nist.javax.sdp.fields.TimeField;
import gov.nist.javax.sip.message.SIPRequest;
@ -530,10 +519,9 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
// 写入redis 超时时回复
redisCatchStorage.updateSendRTPSever(sendRtpItem);
MediaServerItem finalMediaServerItem = mediaServerItem;
playService.play(mediaServerItem, ssrcInfo, device, channelId, hookEvent, errorEvent, (code, msg) -> {
logger.info("[上级点播]超时, 用户:{} 通道:{}", username, channelId);
redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null);
logger.info("[上级点播]超时, 用户:{} 通道:{}", username, finalChannelId);
redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), finalChannelId, callIdHeader.getCallId(), null);
});
} else {
sendRtpItem.setStreamId(playTransaction.getStream());
@ -908,13 +896,12 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
if (audioBroadcastCatch == null) {
logger.warn("来自设备的Invite请求非语音广播已忽略requesterId {}/{}", requesterId, channelId);
try {
responseAck(serverTransaction, Response.FORBIDDEN);
responseAck(request, Response.FORBIDDEN);
} catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("[命令发送失败] 来自设备的Invite请求非语音广播 FORBIDDEN: {}", e.getMessage());
}
return;
}
Request request = serverTransaction.getRequest();
if (device != null) {
logger.info("收到设备" + requesterId + "的语音广播Invite请求");
try {
@ -985,7 +972,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
if (mediaServerItem == null) {
logger.warn("未找到可用的zlm");
try {
responseAck(serverTransaction, Response.BUSY_HERE);
responseAck(request, Response.BUSY_HERE);
} catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("[命令发送失败] invite 未找到可用的zlm: {}", e.getMessage());
}
@ -997,7 +984,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
if (sendRtpItem == null) {
logger.warn("服务器端口资源不足");
try {
responseAck(serverTransaction, Response.BUSY_HERE);
responseAck(request, Response.BUSY_HERE);
} catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("[命令发送失败] invite 服务器端口资源不足: {}", e.getMessage());
}
@ -1024,7 +1011,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, app, stream);
if (streamReady) {
sendOk(device, sendRtpItem, sdp, serverTransaction, mediaServerItem, mediaTransmissionTCP, ssrc);
sendOk(device, sendRtpItem, sdp, request, mediaServerItem, mediaTransmissionTCP, ssrc);
}else {
logger.warn("[语音通话] 未发现待推送的流,app={},stream={}", app, stream);
playService.stopAudioBroadcast(device.getDeviceId(), audioBroadcastCatch.getChannelId());
@ -1042,7 +1029,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
}
}
void sendOk(Device device, SendRtpItem sendRtpItem, SessionDescription sdp, ServerTransaction serverTransaction, MediaServerItem mediaServerItem, boolean mediaTransmissionTCP, String ssrc){
void sendOk(Device device, SendRtpItem sendRtpItem, SessionDescription sdp, SIPRequest request, MediaServerItem mediaServerItem, boolean mediaTransmissionTCP, String ssrc){
try {
sendRtpItem.setStatus(2);
redisCatchStorage.updateSendRTPSever(sendRtpItem);
@ -1078,7 +1065,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
parentPlatform.setServerPort(device.getPort());
parentPlatform.setServerGBId(device.getDeviceId());
SIPResponse sipResponse = responseSdpAck(serverTransaction, content.toString(), parentPlatform);
SIPResponse sipResponse = responseSdpAck(request, content.toString(), parentPlatform);
AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(device.getDeviceId(), sendRtpItem.getChannelId());

View File

@ -101,33 +101,38 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
if (!taskQueueHandlerRun) {
taskQueueHandlerRun = true;
taskExecutor.execute(()-> {
while (!taskQueue.isEmpty()) {
try {
HandlerCatchData take = taskQueue.poll();
Element rootElement = getRootElement(take.getEvt());
if (rootElement == null) {
logger.error("处理NOTIFY消息时未获取到消息体,{}", take.getEvt().getRequest());
continue;
}
String cmd = XmlUtil.getText(rootElement, "CmdType");
try {
while (!taskQueue.isEmpty()) {
try {
HandlerCatchData take = taskQueue.poll();
Element rootElement = getRootElement(take.getEvt());
if (rootElement == null) {
logger.error("处理NOTIFY消息时未获取到消息体,{}", take.getEvt().getRequest());
continue;
}
String cmd = XmlUtil.getText(rootElement, "CmdType");
if (CmdType.CATALOG.equals(cmd)) {
logger.info("接收到Catalog通知");
processNotifyCatalogList(take.getEvt());
} else if (CmdType.ALARM.equals(cmd)) {
logger.info("接收到Alarm通知");
processNotifyAlarm(take.getEvt());
} else if (CmdType.MOBILE_POSITION.equals(cmd)) {
logger.info("接收到MobilePosition通知");
processNotifyMobilePosition(take.getEvt());
} else {
logger.info("接收到消息:" + cmd);
if (CmdType.CATALOG.equals(cmd)) {
logger.info("接收到Catalog通知");
processNotifyCatalogList(take.getEvt());
} else if (CmdType.ALARM.equals(cmd)) {
logger.info("接收到Alarm通知");
processNotifyAlarm(take.getEvt());
} else if (CmdType.MOBILE_POSITION.equals(cmd)) {
logger.info("接收到MobilePosition通知");
processNotifyMobilePosition(take.getEvt());
} else {
logger.info("接收到消息:" + cmd);
}
} catch (DocumentException e) {
logger.error("处理NOTIFY消息时错误", e);
}
} catch (DocumentException e) {
logger.error("处理NOTIFY消息时错误", e);
}
}catch (Exception e) {
logger.error("处理NOTIFY消息时错误", e);
}finally {
taskQueueHandlerRun = false;
}
taskQueueHandlerRun = false;
});
}
}

View File

@ -120,13 +120,6 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
if (request.getExpires() == null) {
response = getMessageFactory().createResponse(Response.BAD_REQUEST, request);
if (evt.getDialog() != null ) {
if (evt.getDialog().isServer()) {
ServerTransaction serverTransaction = getServerTransaction(evt);
serverTransaction.sendResponse(response);
serverTransaction.getDialog().delete();
}
}
sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response);
return;
}
@ -185,12 +178,4 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
e.printStackTrace();
}
}
private void sendResponse(RequestEvent evt, Response response) throws InvalidArgumentException, SipException {
ServerTransaction serverTransaction = getServerTransaction(evt);
serverTransaction.sendResponse(response);
if (serverTransaction.getDialog() != null) {
serverTransaction.getDialog().delete();
}
}
}

View File

@ -3,15 +3,13 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.AckRequestProcessor;
import gov.nist.javax.sip.message.SIPRequest;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import javax.sip.InvalidArgumentException;
import javax.sip.RequestEvent;
import javax.sip.ServerTransaction;
import javax.sip.SipException;
import javax.sip.message.Response;
import java.text.ParseException;
@ -34,7 +32,11 @@ public abstract class MessageHandlerAbstract extends SIPRequestProcessorParent i
public void handForDevice(RequestEvent evt, Device device, Element element) {
String cmd = getText(element, "CmdType");
if (cmd == null) {
handNullCmd(evt);
try {
responseAck((SIPRequest) evt.getRequest(), Response.OK);
} catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("[命令发送失败] 回复200 OK: {}", e.getMessage());
}
return;
}
IMessageHandler messageHandler = messageHandlerMap.get(cmd);
@ -51,13 +53,4 @@ public abstract class MessageHandlerAbstract extends SIPRequestProcessorParent i
messageHandler.handForPlatform(evt, parentPlatform, element);
}
}
public void handNullCmd(RequestEvent evt){
try {
ServerTransaction serverTransaction = getServerTransaction(evt);
responseAck(serverTransaction, Response.OK);
} catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("[命令发送失败] 回复200 OK: {}", e.getMessage());
}
}
}

View File

@ -1,6 +1,6 @@
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSONObject;
import com.genersoft.iot.vmp.gb28181.bean.AudioBroadcastCatch;
import com.genersoft.iot.vmp.gb28181.bean.AudioBroadcastCatchStatus;
import com.genersoft.iot.vmp.gb28181.bean.Device;

View File

@ -122,4 +122,21 @@ public class SipUtils {
public static String getNewCallId() {
return (int) Math.floor(Math.random() * 10000) + "";
}
public static int getTypeCodeFromGbCode(String deviceId) {
if (ObjectUtils.isEmpty(deviceId)) {
return 0;
}
return Integer.parseInt(deviceId.substring(10, 13));
}
/**
*
* @param deviceId
* @return
*/
public static boolean isFrontEnd(String deviceId) {
int typeCodeFromGbCode = getTypeCodeFromGbCode(deviceId);
return typeCodeFromGbCode > 130 && typeCodeFromGbCode < 199;
}
}

View File

@ -9,21 +9,16 @@ import com.genersoft.iot.vmp.gb28181.bean.*;
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager;
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.impl.SIPCommanderFroPlatform;
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.StreamProxyItem;
import com.genersoft.iot.vmp.media.zlm.dto.hook.*;
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
import com.genersoft.iot.vmp.media.zlm.dto.*;
import com.genersoft.iot.vmp.service.*;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult;
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -294,9 +289,9 @@ public class ZLMHttpHookListener {
JSONObject json = (JSONObject) JSON.toJSON(param);
taskExecutor.execute(()->{
taskExecutor.execute(()-> {
ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_stream_changed, json);
if (subscribe != null ) {
if (subscribe != null) {
MediaServerItem mediaInfo = mediaServerService.getOne(param.getMediaServerId());
if (mediaInfo != null) {
subscribe.response(mediaInfo, json);
@ -312,15 +307,16 @@ public class ZLMHttpHookListener {
StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(param.getApp(), param.getStream());
if (streamAuthorityInfo == null) {
streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(param);
}else {
} else {
streamAuthorityInfo.setOriginType(param.getOriginType());
streamAuthorityInfo.setOriginTypeStr(param.getOriginTypeStr());
}
redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo);
}
}else {
} else {
redisCatchStorage.removeStreamAuthorityInfo(param.getApp(), param.getStream());
}
});
if ("rtsp".equals(param.getSchema())){
logger.info("on_stream_changed注册->{}, app->{}, stream->{}", param.isRegist(), param.getApp(), param.getStream());
@ -329,12 +325,12 @@ public class ZLMHttpHookListener {
}else {
mediaServerService.removeCount(param.getMediaServerId());
}
if (item.getOriginType() == OriginType.PULL.ordinal()
|| item.getOriginType() == OriginType.FFMPEG_PULL.ordinal()) {
if (param.getOriginType() == OriginType.PULL.ordinal()
|| param.getOriginType() == OriginType.FFMPEG_PULL.ordinal()) {
// 设置拉流代理上线/离线
streamProxyService.updateStatus(param.isRegist(), app, param.getStream());
streamProxyService.updateStatus(param.isRegist(), param.getApp(), param.getStream());
}
if ("rtp".equals(app) && !regist ) {
if ("rtp".equals(param.getApp()) && !param.isRegist() ) {
StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(param.getStream());
if (streamInfo!=null){
redisCatchStorage.stopPlay(streamInfo);
@ -346,47 +342,49 @@ public class ZLMHttpHookListener {
streamInfo.getStream(), null);
}
}
}else if ("broadcast".equals(app)){
}else if ("broadcast".equals(param.getApp())){
// 语音对讲推流 stream需要满足格式deviceId_channelId
if (regist && param.getStream().indexOf("_") > 0) {
if (param.isRegist() && param.getStream().indexOf("_") > 0) {
String[] streamArray = param.getStream().split("_");
if (streamArray.length == 2) {
String deviceId = streamArray[0];
String channelId = streamArray[1];
Device device = deviceService.queryDevice(deviceId);
Device device = deviceService.getDevice(deviceId);
if (device != null) {
DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
if (deviceChannel != null) {
if (audioBroadcastManager.exit(deviceId, channelId)) {
// 直接推流
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, stream, null);
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, param.getStream(), null);
if (sendRtpItem == null) {
// TODO 可能数据错误,重新开启语音通道
}else {
String is_Udp = sendRtpItem.isTcp() ? "0" : "1";
MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
logger.info("rtp/{}开始向上级推流, 目标={}:{}SSRC={}", sendRtpItem.getStreamId(), sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc());
Map<String, Object> param = new HashMap<>(12);
param.put("vhost","__defaultVhost__");
param.put("app",sendRtpItem.getApp());
param.put("stream",sendRtpItem.getStreamId());
param.put("ssrc", sendRtpItem.getSsrc());
param.put("src_port", sendRtpItem.getLocalPort());
param.put("pt", sendRtpItem.getPt());
param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0");
param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0");
Map<String, Object> sendParam = new HashMap<>(12);
sendParam.put("vhost","__defaultVhost__");
sendParam.put("app",sendRtpItem.getApp());
sendParam.put("stream",sendRtpItem.getStreamId());
sendParam.put("ssrc", sendRtpItem.getSsrc());
sendParam.put("src_port", sendRtpItem.getLocalPort());
sendParam.put("pt", sendRtpItem.getPt());
sendParam.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0");
sendParam.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0");
JSONObject jsonObject;
if (sendRtpItem.isTcpActive()) {
jsonObject = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, param);
jsonObject = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, sendParam);
} else {
param.put("is_udp", is_Udp);
param.put("dst_url", sendRtpItem.getIp());
param.put("dst_port", sendRtpItem.getPort());
jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
sendParam.put("is_udp", is_Udp);
sendParam.put("dst_url", sendRtpItem.getIp());
sendParam.put("dst_port", sendRtpItem.getPort());
jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaInfo, sendParam);
}
if (jsonObject != null && jsonObject.getInteger("code") == 0) {
logger.info("[语音对讲] 自动推流成功, device: {}, channel: {}", deviceId, channelId);
}else {
logger.info("[语音对讲] 推流失败, 结果: {}", jsonObject);
}
}
@ -406,43 +404,43 @@ public class ZLMHttpHookListener {
}
}
}else if ("talk".equals(app)){
}else if ("talk".equals(param.getApp())){
// 语音对讲推流 stream需要满足格式deviceId_channelId
if (regist && stream.indexOf("_") > 0) {
String[] streamArray = stream.split("_");
if (param.isRegist() && param.getStream().indexOf("_") > 0) {
String[] streamArray = param.getStream().split("_");
if (streamArray.length == 2) {
String deviceId = streamArray[0];
String channelId = streamArray[1];
Device device = deviceService.queryDevice(deviceId);
Device device = deviceService.getDevice(deviceId);
if (device != null) {
DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
if (deviceChannel != null) {
if (audioBroadcastManager.exit(deviceId, channelId)) {
// 直接推流
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, stream, null);
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, param.getStream(), null);
if (sendRtpItem == null) {
// TODO 可能数据错误,重新开启语音通道
}else {
MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
logger.info("rtp/{}开始向上级推流, 目标={}:{}SSRC={}", sendRtpItem.getStreamId(), sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc());
Map<String, Object> param = new HashMap<>(12);
param.put("vhost","__defaultVhost__");
param.put("app",sendRtpItem.getApp());
param.put("stream",sendRtpItem.getStreamId());
param.put("ssrc", sendRtpItem.getSsrc());
param.put("src_port", sendRtpItem.getLocalPort());
param.put("pt", sendRtpItem.getPt());
param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0");
param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0");
Map<String, Object> sendParam = new HashMap<>(12);
sendParam.put("vhost","__defaultVhost__");
sendParam.put("app",sendRtpItem.getApp());
sendParam.put("stream",sendRtpItem.getStreamId());
sendParam.put("ssrc", sendRtpItem.getSsrc());
sendParam.put("src_port", sendRtpItem.getLocalPort());
sendParam.put("pt", sendRtpItem.getPt());
sendParam.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0");
sendParam.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0");
JSONObject jsonObject;
if (sendRtpItem.isTcpActive()) {
jsonObject = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, param);
jsonObject = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, sendParam);
} else {
param.put("is_udp", sendRtpItem.isTcp() ? "0" : "1");
param.put("dst_url", sendRtpItem.getIp());
param.put("dst_port", sendRtpItem.getPort());
jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
sendParam.put("is_udp", sendRtpItem.isTcp() ? "0" : "1");
sendParam.put("dst_url", sendRtpItem.getIp());
sendParam.put("dst_port", sendRtpItem.getPort());
jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaInfo, sendParam);
}
if (jsonObject != null && jsonObject.getInteger("code") == 0) {
logger.info("[语音对讲] 自动推流成功, device: {}, channel: {}", deviceId, channelId);
@ -450,7 +448,7 @@ public class ZLMHttpHookListener {
}
}else {
// 开启语音对讲通道
MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
MediaServerItem mediaServerItem = mediaServerService.getOne(param.getMediaServerId());
playService.talk(mediaServerItem, device, channelId, (mediaServer, jsonObject)->{
System.out.println("开始推流");
}, eventResult -> {
@ -466,9 +464,9 @@ public class ZLMHttpHookListener {
}
}else{
if (!"rtp".equals(app)){
String type = OriginType.values()[item.getOriginType()].getType();
MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
if (!"rtp".equals(param.getApp())){
String type = OriginType.values()[param.getOriginType()].getType();
MediaServerItem mediaServerItem = mediaServerService.getOne(param.getMediaServerId());
if (mediaServerItem != null){
if (param.isRegist()) {
@ -478,7 +476,7 @@ public class ZLMHttpHookListener {
callId = streamAuthorityInfo.getCallId();
}
StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaServerItem,
param.getApp(), param.getStream(), tracks, callId);
param.getApp(), param.getStream(), param.getTracks(), callId);
param.setStreamInfo(streamInfoByAppAndStream);
redisCatchStorage.addStream(mediaServerItem, type, param.getApp(), param.getStream(), param);
if (param.getOriginType() == OriginType.RTSP_PUSH.ordinal()
@ -489,7 +487,8 @@ public class ZLMHttpHookListener {
}
}else {
// 兼容流注销时类型从redis记录获取
OnStreamChangedHookParam onStreamChangedHookParam = redisCatchStorage.getStreamInfo(param.getApp(), param.getStream(), param.getMediaServerId());
OnStreamChangedHookParam onStreamChangedHookParam = redisCatchStorage.getStreamInfo(
param.getApp(), param.getStream(), param.getMediaServerId());
if (onStreamChangedHookParam != null) {
type = OriginType.values()[onStreamChangedHookParam.getOriginType()].getType();
redisCatchStorage.removeStream(mediaServerItem.getId(), type, param.getApp(), param.getStream());
@ -526,13 +525,13 @@ public class ZLMHttpHookListener {
if (platform != null) {
commanderFroPlatform.streamByeCmd(platform, sendRtpItem);
}else {
if ("talk".equals(app) && sendRtpItem.isOnlyAudio()) {
if ("talk".equals(param.getApp()) && sendRtpItem.isOnlyAudio()) {
AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId());
if (device != null && audioBroadcastCatch != null) {
// cmder.streamByeCmd(device, sendRtpItem.getChannelId(), audioBroadcastCatch.getSipTransactionInfo(), null);
}
}else {
cmder.streamByeCmd(device, sendRtpItem.getChannelId(), stream, sendRtpItem.getCallId());
cmder.streamByeCmd(device, sendRtpItem.getChannelId(), param.getStream(), sendRtpItem.getCallId());
}
}
@ -575,6 +574,9 @@ public class ZLMHttpHookListener {
if (sendRtpItems.size() > 0) {
for (SendRtpItem sendRtpItem : sendRtpItems) {
ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId());
if (parentPlatform == null) {
continue;
}
try {
commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId());
} catch (SipException | InvalidArgumentException | ParseException e) {

View File

@ -78,6 +78,7 @@ public class ZLMRESTfulUtils {
if (callback == null) {
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
ResponseBody responseBody = response.body();
if (responseBody != null) {
@ -85,6 +86,8 @@ public class ZLMRESTfulUtils {
responseJSON = JSON.parseObject(responseStr);
}
}else {
System.out.println( 2222);
System.out.println( response.code());
response.close();
Objects.requireNonNull(response.body()).close();
}
@ -93,11 +96,11 @@ public class ZLMRESTfulUtils {
if(e instanceof SocketTimeoutException){
//读取超时超时异常
logger.error(String.format("读取ZLM数据失败: %s, %s", url, e.getMessage()));
logger.error(String.format("读取ZLM数据超时失败: %s, %s", url, e.getMessage()));
}
if(e instanceof ConnectException){
//判断连接异常我这里是报Failed to connect to 10.7.5.144
logger.error(String.format("连接ZLM失败: %s, %s", url, e.getMessage()));
logger.error(String.format("连接ZLM连接失败: %s, %s", url, e.getMessage()));
}
}catch (Exception e){

View File

@ -5,9 +5,9 @@ import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.genersoft.iot.vmp.conf.UserSetting;
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;
import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRtpServerTimeout;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.media.zlm.dto.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -346,23 +346,4 @@ public class ZLMRTPServerFactory {
return result;
}
public void closeAllSendRtpStream() {
}
public MediaItem getMediaInfo(MediaServerItem mediaServerItem, String app, String stream) {
JSONObject json = zlmresTfulUtils.getMediaList(mediaServerItem, app, stream);
MediaItem mediaItem = null;
if (json == null || json.getInteger("code") != 0) {
return null;
} else {
JSONArray data = json.getJSONArray("data");
if (data == null || data.size() == 0) {
return null;
}else {
mediaItem = JSONObject.toJavaObject(data.getJSONObject(0), MediaItem.class);
}
}
return mediaItem;
}
}

View File

@ -37,7 +37,7 @@ public class HookSubscribeFactory {
public static HookSubscribeForStreamPush on_publish(String app, String stream, String scheam, String mediaServerId) {
HookSubscribeForStreamPush hookSubscribe = new HookSubscribeForStreamPush();
JSONObject subscribeKey = new com.alibaba.fastjson.JSONObject();
JSONObject subscribeKey = new JSONObject();
subscribeKey.put("app", app);
subscribeKey.put("stream", stream);
if (scheam != null) {

View File

@ -1,6 +1,7 @@
package com.genersoft.iot.vmp.media.zlm.dto;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSONObject;
import java.time.Instant;

View File

@ -1,12 +1,6 @@
package com.genersoft.iot.vmp.media.zlm.dto;
import com.genersoft.iot.vmp.gb28181.session.SsrcConfig;
import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
import org.springframework.util.StringUtils;
import java.util.HashMap;
/**
* MediaServerItem便
*/
@ -38,8 +32,6 @@ public class MediaServerItemLite {
private String secret;
private int hookAliveInterval;
private int recordAssistPort;
@ -58,7 +50,6 @@ public class MediaServerItemLite {
this.rtspPort = mediaServerItem.getRtspPort();
this.rtspSSLPort = mediaServerItem.getRtspSSLPort();
this.secret = mediaServerItem.getSecret();
this.hookAliveInterval = mediaServerItem.getHookAliveInterval();
this.recordAssistPort = mediaServerItem.getRecordAssistPort();
}
@ -167,14 +158,6 @@ public class MediaServerItemLite {
this.secret = secret;
}
public int getHookAliveInterval() {
return hookAliveInterval;
}
public void setHookAliveInterval(int hookAliveInterval) {
this.hookAliveInterval = hookAliveInterval;
}
public int getRecordAssistPort() {
return recordAssistPort;
}

View File

@ -1,17 +1,12 @@
package com.genersoft.iot.vmp.service;
import com.alibaba.fastjson2.JSONObject;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.media.zlm.dto.ServerKeepaliveData;
import com.genersoft.iot.vmp.service.bean.MediaServerLoad;
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
import java.util.List;
import java.util.Map;
/**
*

View File

@ -4,21 +4,18 @@ import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.common.StreamURL;
import com.genersoft.iot.vmp.conf.MediaConfig;
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.StreamAuthorityInfo;
import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.service.IMediaService;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
import com.genersoft.iot.vmp.service.IMediaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import java.net.URL;
@Service
public class MediaServiceImpl implements IMediaService {
@ -104,7 +101,7 @@ public class MediaServiceImpl implements IMediaService {
streamInfoResult.setFmp4(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam);
streamInfoResult.setHls(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam);
streamInfoResult.setTs(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam);
streamInfoResult.setRtc(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam);
streamInfoResult.setRtc(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam, isPlay);
streamInfoResult.setTracks(tracks);
return streamInfoResult;

View File

@ -1,62 +1,28 @@
package com.genersoft.iot.vmp.service.impl;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.util.*;
import javax.sip.InvalidArgumentException;
import javax.sip.ResponseEvent;
import javax.sip.SipException;
import com.genersoft.iot.vmp.gb28181.bean.*;
import com.genersoft.iot.vmp.common.VideoManagerConstants;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.conf.DynamicTask;
import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.conf.UserSetting;
import com.genersoft.iot.vmp.conf.exception.ControllerException;
import com.genersoft.iot.vmp.conf.exception.ServiceException;
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
import com.genersoft.iot.vmp.service.IDeviceService;
import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult;
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.async.DeferredResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.conf.DynamicTask;
import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.conf.UserSetting;
import com.genersoft.iot.vmp.gb28181.bean.*;
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager;
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
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.impl.SIPCommander;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils;
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
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.media.zlm.dto.MediaServerItem;
@ -72,10 +38,10 @@ import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
import com.genersoft.iot.vmp.utils.DateUtil;
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult;
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.AudioBroadcastEvent;
import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -91,7 +57,9 @@ import javax.sip.SipException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@SuppressWarnings(value = {"rawtypes", "unchecked"})
@ -1092,7 +1060,7 @@ public class PlayServiceImpl implements IPlayService {
AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(deviceId, channelId);
if (audioBroadcastCatch != null) {
Device device = deviceService.queryDevice(deviceId);
Device device = deviceService.getDevice(deviceId);
if (device == null) {
return;
}

View File

@ -111,22 +111,25 @@ public class PlayController {
resultHolder.invokeResult(msg);
});
// TODO 在点播未成功的情况下在此调用接口点播会导致返回的流地址ip错误
deferredResultEx.setFilter(result1 -> {
WVPResult<StreamInfo> wvpResult1 = (WVPResult<StreamInfo>)result1;
WVPResult<StreamInfo> clone = null;
try {
clone = (WVPResult<StreamInfo>)wvpResult1.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
if (clone.getCode() == ErrorCode.SUCCESS.getCode()) {
StreamInfo data = clone.getData().clone();
data.channgeStreamIp(request.getLocalName());
clone.setData(data);
}
return clone;
});
if (userSetting.isUsePushingAsStatus()) {
// TODO 在点播未成功的情况下在此调用接口点播会导致返回的流地址ip错误
deferredResultEx.setFilter(result1 -> {
WVPResult<StreamInfo> wvpResult1 = (WVPResult<StreamInfo>)result1;
WVPResult<StreamInfo> clone = null;
try {
clone = (WVPResult<StreamInfo>)wvpResult1.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
if (clone.getCode() == ErrorCode.SUCCESS.getCode()) {
StreamInfo data = clone.getData().clone();
data.channgeStreamIp(request.getLocalName());
clone.setData(data);
}
return clone;
});
}
// 录像查询以channelId作为deviceId查询
resultHolder.put(key, uuid, deferredResultEx);

View File

@ -302,15 +302,13 @@
<script>
import rtcPlayer from '../dialog/rtcPlayer.vue'
import crypto from 'crypto'
// import LivePlayer from '@liveqing/liveplayer'
// import player from '../dialog/easyPlayer.vue'
import jessibucaPlayer from '../common/jessibuca.vue'
import recordDownload from '../dialog/recordDownload.vue'
export default {
name: 'devicePlayer',
props: {},
components: {
LivePlayer, jessibucaPlayer, rtcPlayer, recordDownload,
jessibucaPlayer, rtcPlayer, recordDownload,
},
computed: {
getPlayerShared: function () {
@ -864,9 +862,9 @@ export default {
if (res.data.code == 0) {
let streamInfo = res.data.data.streamInfo;
if (document.location.protocol.includes("https")) {
this.startBroadcast(streamInfo.rtcs)
this.startBroadcast(streamInfo.rtcs.url)
}else {
this.startBroadcast(streamInfo.rtc)
this.startBroadcast(streamInfo.rtc.url)
}
}else {