From f9d30bdfadd68e61f545e1c5f6260d4f58dca040 Mon Sep 17 00:00:00 2001
From: lawrencehj <1934378145@qq.com>
Date: 星期五, 26 三月 2021 20:15:12 +0800
Subject: [PATCH] 实现语音广播信令(web语音推流开发中)
---
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java | 2
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java | 4
src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java | 45 +++++
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java | 63 +++++++
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java | 301 +++++++++++++++++++++++--------------
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java | 2
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/RegisterResponseProcessor.java | 1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java | 2
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java | 2
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java | 41 ++++
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java | 8 +
11 files changed, 344 insertions(+), 127 deletions(-)
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
index 257a589..c0b4985 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
@@ -16,7 +16,7 @@
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
+// import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
index ab72be5..b7f592e 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
@@ -41,6 +41,8 @@
public static final String CALLBACK_CMD_ALARM = "CALLBACK_ALARM";
+ public static final String CALLBACK_CMD_BROADCAST = "CALLBACK_BROADCAST";
+
private Map<String, DeferredResult> map = new ConcurrentHashMap<String, DeferredResult>();
public void put(String key, DeferredResult result) {
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
index 27000bb..dd50e06 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
@@ -120,6 +120,14 @@
boolean audioBroadcastCmd(Device device,String channelId);
/**
+ * 璇煶骞挎挱
+ *
+ * @param device 瑙嗛璁惧
+ */
+ void audioBroadcastCmd(Device device, SipSubscribe.Event okEvent);
+ boolean audioBroadcastCmd(Device device);
+
+ /**
* 闊宠棰戝綍鍍忔帶鍒�
*
* @param device 瑙嗛璁惧
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
index 8fe4cbc..5bf9236 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
@@ -3,7 +3,7 @@
import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
+// import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
index c764d5e..aaf3c63 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
@@ -6,14 +6,14 @@
import javax.sip.InvalidArgumentException;
import javax.sip.PeerUnavailableException;
import javax.sip.SipFactory;
-import javax.sip.SipProvider;
+// import javax.sip.SipProvider;
import javax.sip.address.Address;
import javax.sip.address.SipURI;
import javax.sip.header.*;
import javax.sip.message.Request;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
+// import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import com.genersoft.iot.vmp.conf.SipConfig;
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
index abf9cf7..313348e 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
@@ -23,7 +23,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.ComponentScan;
+// import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
@@ -47,8 +47,7 @@
public class SIPCommander implements ISIPCommander {
private final Logger logger = LoggerFactory.getLogger(SIPCommander.class);
-
-
+
@Autowired
private SipConfig sipConfig;
@@ -623,11 +622,67 @@
*/
@Override
public boolean audioBroadcastCmd(Device device, String channelId) {
- // TODO Auto-generated method stub
+ // 鏀逛负鏂扮殑瀹炵幇
return false;
}
/**
+ * 璇煶骞挎挱
+ *
+ * @param device 瑙嗛璁惧
+ * @param channelId 棰勮閫氶亾
+ */
+ @Override
+ public boolean audioBroadcastCmd(Device device) {
+ try {
+ StringBuffer broadcastXml = new StringBuffer(200);
+ broadcastXml.append("<?xml version=\"1.0\" ?>\r\n");
+ broadcastXml.append("<Notify>\r\n");
+ broadcastXml.append("<CmdType>Broadcast</CmdType>\r\n");
+ broadcastXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
+ broadcastXml.append("<SourceID>" + sipConfig.getSipId() + "</SourceID>\r\n");
+ broadcastXml.append("<TargetID>" + device.getDeviceId() + "</TargetID>\r\n");
+ broadcastXml.append("</Notify>\r\n");
+
+ String tm = Long.toString(System.currentTimeMillis());
+
+ CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
+ : udpSipProvider.getNewCallId();
+
+ Request request = headerProvider.createMessageRequest(device, broadcastXml.toString(), "z9hG4bK-ViaBcst-" + tm, "FromBcst" + tm, null, callIdHeader);
+ transmitRequest(device, request);
+ return true;
+ } catch (SipException | ParseException | InvalidArgumentException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+ @Override
+ public void audioBroadcastCmd(Device device, SipSubscribe.Event errorEvent) {
+ try {
+ StringBuffer broadcastXml = new StringBuffer(200);
+ broadcastXml.append("<?xml version=\"1.0\" ?>\r\n");
+ broadcastXml.append("<Notify>\r\n");
+ broadcastXml.append("<CmdType>Broadcast</CmdType>\r\n");
+ broadcastXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
+ broadcastXml.append("<SourceID>" + sipConfig.getSipId() + "</SourceID>\r\n");
+ broadcastXml.append("<TargetID>" + device.getDeviceId() + "</TargetID>\r\n");
+ broadcastXml.append("</Notify>\r\n");
+
+ String tm = Long.toString(System.currentTimeMillis());
+
+ CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
+ : udpSipProvider.getNewCallId();
+
+ Request request = headerProvider.createMessageRequest(device, broadcastXml.toString(), "z9hG4bK-ViaBcst-" + tm, "FromBcst" + tm, null, callIdHeader);
+ transmitRequest(device, request, errorEvent);
+ } catch (SipException | ParseException | InvalidArgumentException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ /**
* 闊宠棰戝綍鍍忔帶鍒�
*
* @param device 瑙嗛璁惧
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
index eac13ef..0892526 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
@@ -15,7 +15,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.ComponentScan;
+// import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Lazy;
import org.springframework.lang.Nullable;
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
index 51ce21e..a7b3d94 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
@@ -14,6 +14,7 @@
import com.genersoft.iot.vmp.conf.MediaServerConfig;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
+import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
@@ -74,144 +75,216 @@
Request request = evt.getRequest();
SipURI sipURI = (SipURI) request.getRequestURI();
String channelId = sipURI.getUser();
- String platformId = null;
+ String requesterId = null;
FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME);
AddressImpl address = (AddressImpl) fromHeader.getAddress();
SipUri uri = (SipUri) address.getURI();
- platformId = uri.getUser();
+ requesterId = uri.getUser();
- if (platformId == null || channelId == null) {
- logger.info("鏃犳硶浠嶧romHeader鐨凙ddress涓幏鍙栧埌骞冲彴id锛岃繑鍥�404");
+ if (requesterId == null || channelId == null) {
+ logger.info("鏃犳硶浠嶧romHeader鐨凙ddress涓幏鍙栧埌骞冲彴id锛岃繑鍥�400");
responseAck(evt, Response.BAD_REQUEST); // 鍙傛暟涓嶅叏锛� 鍙�400锛岃姹傞敊璇�
return;
}
- // 鏌ヨ骞冲彴涓嬫槸鍚︽湁璇ラ�氶亾
- DeviceChannel channel = storager.queryChannelInParentPlatform(platformId, channelId);
- if (channel == null) {
- logger.info("閫氶亾涓嶅瓨鍦紝杩斿洖404");
- responseAck(evt, Response.NOT_FOUND); // 閫氶亾涓嶅瓨鍦紝鍙�404锛岃祫婧愪笉瀛樺湪
- return;
- }else {
- responseAck(evt, Response.TRYING); // 閫氶亾瀛樺湪锛屽彂100锛宼rying
- }
- // 瑙f瀽sdp娑堟伅, 浣跨敤jainsip 鑷甫鐨剆dp瑙f瀽鏂瑰紡
- String contentString = new String(request.getRawContent());
- // jainSip涓嶆敮鎸亂=瀛楁锛� 绉婚櫎绉婚櫎浠ヨВ鏋愩��
- int ssrcIndex = contentString.indexOf("y=");
- String ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
- //ssrc瑙勫畾闀垮害涓�10瀛楄妭锛屼笉鍙栦綑涓嬮暱搴︿互閬垮厤鍚庣画杩樻湁鈥渇=鈥濆瓧娈�
- // String ssrc = contentString.substring(ssrcIndex + 2, contentString.length())
- // .replace("\r\n", "").replace("\n", "");
+ // 鏌ヨ璇锋眰鏂规槸鍚︿笂绾у钩鍙�
+ ParentPlatform platform = storager.queryParentPlatById(requesterId);
+ if (platform != null) {
+ // 鏌ヨ骞冲彴涓嬫槸鍚︽湁璇ラ�氶亾
+ DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId);
+ if (channel == null) {
+ logger.info("閫氶亾涓嶅瓨鍦紝杩斿洖404");
+ responseAck(evt, Response.NOT_FOUND); // 閫氶亾涓嶅瓨鍦紝鍙�404锛岃祫婧愪笉瀛樺湪
+ return;
+ }else {
+ responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 閫氶亾瀛樺湪锛屽彂181锛屽懠鍙浆鎺ヤ腑
+ }
+ // 瑙f瀽sdp娑堟伅, 浣跨敤jainsip 鑷甫鐨剆dp瑙f瀽鏂瑰紡
+ String contentString = new String(request.getRawContent());
- String substring = contentString.substring(0, contentString.indexOf("y="));
- SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring);
+ // jainSip涓嶆敮鎸亂=瀛楁锛� 绉婚櫎绉婚櫎浠ヨВ鏋愩��
+ int ssrcIndex = contentString.indexOf("y=");
+ //ssrc瑙勫畾闀垮害涓�10瀛楄妭锛屼笉鍙栦綑涓嬮暱搴︿互閬垮厤鍚庣画杩樻湁鈥渇=鈥濆瓧娈�
+ String ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
+ String substring = contentString.substring(0, contentString.indexOf("y="));
+ SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring);
- // 鑾峰彇鏀寔鐨勬牸寮�
- Vector mediaDescriptions = sdp.getMediaDescriptions(true);
- // 鏌ョ湅鏄惁鏀寔PS 璐熻浇96
- //String ip = null;
- int port = -1;
- //boolean recvonly = false;
- boolean mediaTransmissionTCP = false;
- Boolean tcpActive = null;
- for (int i = 0; i < mediaDescriptions.size(); i++) {
- MediaDescription mediaDescription = (MediaDescription)mediaDescriptions.get(i);
- Media media = mediaDescription.getMedia();
+ // 鑾峰彇鏀寔鐨勬牸寮�
+ Vector mediaDescriptions = sdp.getMediaDescriptions(true);
+ // 鏌ョ湅鏄惁鏀寔PS 璐熻浇96
+ //String ip = null;
+ int port = -1;
+ //boolean recvonly = false;
+ boolean mediaTransmissionTCP = false;
+ Boolean tcpActive = null;
+ for (int i = 0; i < mediaDescriptions.size(); i++) {
+ MediaDescription mediaDescription = (MediaDescription)mediaDescriptions.get(i);
+ Media media = mediaDescription.getMedia();
- Vector mediaFormats = media.getMediaFormats(false);
- if (mediaFormats.contains("96")) {
- port = media.getMediaPort();
- //String mediaType = media.getMediaType();
- String protocol = media.getProtocol();
+ Vector mediaFormats = media.getMediaFormats(false);
+ if (mediaFormats.contains("96")) {
+ port = media.getMediaPort();
+ //String mediaType = media.getMediaType();
+ String protocol = media.getProtocol();
- // 鍖哄垎TCP鍙戞祦杩樻槸udp锛� 褰撳墠榛樿udp
- if ("TCP/RTP/AVP".equals(protocol)) {
- String setup = mediaDescription.getAttribute("setup");
- if (setup != null) {
- mediaTransmissionTCP = true;
- if ("active".equals(setup)) {
- tcpActive = true;
- }else if ("passive".equals(setup)) {
- tcpActive = false;
+ // 鍖哄垎TCP鍙戞祦杩樻槸udp锛� 褰撳墠榛樿udp
+ if ("TCP/RTP/AVP".equals(protocol)) {
+ String setup = mediaDescription.getAttribute("setup");
+ if (setup != null) {
+ mediaTransmissionTCP = true;
+ if ("active".equals(setup)) {
+ tcpActive = true;
+ }else if ("passive".equals(setup)) {
+ tcpActive = false;
+ }
}
}
+ break;
}
- break;
}
- }
- if (port == -1) {
- logger.info("涓嶆敮鎸佺殑濯掍綋鏍煎紡锛岃繑鍥�415");
- // 鍥炲涓嶆敮鎸佺殑鏍煎紡
- responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE); // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415
- return;
- }
- String username = sdp.getOrigin().getUsername();
- String addressStr = sdp.getOrigin().getAddress();
- //String sessionName = sdp.getSessionName().getValue();
- logger.info("[涓婄骇鐐规挱]鐢ㄦ埛锛歿}锛� 鍦板潃锛歿}:{}锛� ssrc锛歿}", username, addressStr, port, ssrc);
+ if (port == -1) {
+ logger.info("涓嶆敮鎸佺殑濯掍綋鏍煎紡锛岃繑鍥�415");
+ // 鍥炲涓嶆敮鎸佺殑鏍煎紡
+ responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE); // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415
+ return;
+ }
+ String username = sdp.getOrigin().getUsername();
+ String addressStr = sdp.getOrigin().getAddress();
+ //String sessionName = sdp.getSessionName().getValue();
+ logger.info("[涓婄骇鐐规挱]鐢ㄦ埛锛歿}锛� 鍦板潃锛歿}:{}锛� ssrc锛歿}", username, addressStr, port, ssrc);
- Device device = storager.queryVideoDeviceByPlatformIdAndChannelId(platformId, channelId);
- if (device == null) {
- logger.warn("鐐规挱骞冲彴{}鐨勯�氶亾{}鏃舵湭鎵惧埌璁惧淇℃伅", platformId, channel);
- responseAck(evt, Response.SERVER_INTERNAL_ERROR);
- return;
- }
- SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(addressStr, port, ssrc, platformId, device.getDeviceId(), channelId,
- mediaTransmissionTCP);
- if (tcpActive != null) {
- sendRtpItem.setTcpActive(tcpActive);
- }
- if (sendRtpItem == null) {
- logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
- responseAck(evt, Response.BUSY_HERE);
- return;
- }
+ Device device = storager.queryVideoDeviceByPlatformIdAndChannelId(requesterId, channelId);
+ if (device == null) {
+ logger.warn("鐐规挱骞冲彴{}鐨勯�氶亾{}鏃舵湭鎵惧埌璁惧淇℃伅", requesterId, channel);
+ responseAck(evt, Response.SERVER_INTERNAL_ERROR);
+ return;
+ }
+ SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(addressStr, port, ssrc, requesterId, device.getDeviceId(), channelId,
+ mediaTransmissionTCP);
+ if (tcpActive != null) {
+ sendRtpItem.setTcpActive(tcpActive);
+ }
+ if (sendRtpItem == null) {
+ logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
+ responseAck(evt, Response.BUSY_HERE);
+ return;
+ }
- // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
- redisCatchStorage.updateSendRTPSever(sendRtpItem);
- // 閫氱煡涓嬬骇鎺ㄦ祦锛�
- PlayResult playResult = playService.play(device.getDeviceId(), channelId, (responseJSON)->{
- // 鏀跺埌鎺ㄦ祦锛� 鍥炲200OK, 绛夊緟ack
- sendRtpItem.setStatus(1);
+ // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
redisCatchStorage.updateSendRTPSever(sendRtpItem);
- // TODO 娣诲姞瀵箃cp鐨勬敮鎸�
- MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
- StringBuffer content = new StringBuffer(200);
- content.append("v=0\r\n");
- content.append("o="+"00000"+" 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n");
- content.append("s=Play\r\n");
- content.append("c=IN IP4 "+mediaInfo.getWanIp()+"\r\n");
- content.append("t=0 0\r\n");
- content.append("m=video "+ sendRtpItem.getLocalPort()+" RTP/AVP 96\r\n");
- content.append("a=sendonly\r\n");
- content.append("a=rtpmap:96 PS/90000\r\n");
- content.append("y="+ ssrc + "\r\n");
- content.append("f=\r\n");
+ // 閫氱煡涓嬬骇鎺ㄦ祦锛�
+ PlayResult playResult = playService.play(device.getDeviceId(), channelId, (responseJSON)->{
+ // 鏀跺埌鎺ㄦ祦锛� 鍥炲200OK, 绛夊緟ack
+ sendRtpItem.setStatus(1);
+ redisCatchStorage.updateSendRTPSever(sendRtpItem);
+ // TODO 娣诲姞瀵箃cp鐨勬敮鎸�
+ MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
+ StringBuffer content = new StringBuffer(200);
+ content.append("v=0\r\n");
+ content.append("o="+"00000"+" 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n");
+ content.append("s=Play\r\n");
+ content.append("c=IN IP4 "+mediaInfo.getWanIp()+"\r\n");
+ content.append("t=0 0\r\n");
+ content.append("m=video "+ sendRtpItem.getLocalPort()+" RTP/AVP 96\r\n");
+ content.append("a=sendonly\r\n");
+ content.append("a=rtpmap:96 PS/90000\r\n");
+ content.append("y="+ ssrc + "\r\n");
+ content.append("f=\r\n");
- try {
- responseAck(evt, content.toString());
- } catch (SipException e) {
- e.printStackTrace();
- } catch (InvalidArgumentException e) {
- e.printStackTrace();
- } catch (ParseException e) {
- e.printStackTrace();
+ try {
+ responseAck(evt, content.toString());
+ } catch (SipException e) {
+ e.printStackTrace();
+ } catch (InvalidArgumentException e) {
+ e.printStackTrace();
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ },(event -> {
+ // 鏈煡閿欒銆傜洿鎺ヨ浆鍙戣澶囩偣鎾殑閿欒
+ Response response = null;
+ try {
+ response = getMessageFactory().createResponse(event.getResponse().getStatusCode(), evt.getRequest());
+ getServerTransaction(evt).sendResponse(response);
+ } catch (ParseException | SipException | InvalidArgumentException e) {
+ e.printStackTrace();
+ }
+ }));
+ if (logger.isDebugEnabled()) {
+ logger.debug(playResult.getResult().toString());
}
- },(event -> {
- // 鏈煡閿欒銆傜洿鎺ヨ浆鍙戣澶囩偣鎾殑閿欒
- Response response = null;
- try {
- response = getMessageFactory().createResponse(event.getResponse().getStatusCode(), evt.getRequest());
- getServerTransaction(evt).sendResponse(response);
+ } else {
+ // 闈炰笂绾у钩鍙拌姹傦紝鏌ヨ鏄惁璁惧璇锋眰锛堥�氬父涓烘帴鏀惰闊冲箍鎾殑璁惧锛�
+ Device device = storager.queryVideoDevice(requesterId);
+ if (device != null) {
+ logger.info("鏀跺埌璁惧" + requesterId + "鐨勮闊冲箍鎾璉nvite璇锋眰");
+ responseAck(evt, Response.TRYING);
- } catch (ParseException | SipException | InvalidArgumentException e) {
- e.printStackTrace();
+ String contentString = new String(request.getRawContent());
+ // jainSip涓嶆敮鎸亂=瀛楁锛� 绉婚櫎绉婚櫎浠ヨВ鏋愩��
+ String substring = contentString;
+ String ssrc = "0000000404";
+ int ssrcIndex = contentString.indexOf("y=");
+ if (ssrcIndex > 0) {
+ substring = contentString.substring(0, ssrcIndex);
+ ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
+ }
+ ssrcIndex = substring.indexOf("f=");
+ if (ssrcIndex > 0) {
+ substring = contentString.substring(0, ssrcIndex);
+ }
+ SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring);
+
+ // 鑾峰彇鏀寔鐨勬牸寮�
+ Vector mediaDescriptions = sdp.getMediaDescriptions(true);
+ // 鏌ョ湅鏄惁鏀寔PS 璐熻浇96
+ int port = -1;
+ //boolean recvonly = false;
+ boolean mediaTransmissionTCP = false;
+ Boolean tcpActive = null;
+ for (int i = 0; i < mediaDescriptions.size(); i++) {
+ MediaDescription mediaDescription = (MediaDescription)mediaDescriptions.get(i);
+ Media media = mediaDescription.getMedia();
+
+ Vector mediaFormats = media.getMediaFormats(false);
+ if (mediaFormats.contains("8")) {
+ port = media.getMediaPort();
+ String protocol = media.getProtocol();
+ // 鍖哄垎TCP鍙戞祦杩樻槸udp锛� 褰撳墠榛樿udp
+ if ("TCP/RTP/AVP".equals(protocol)) {
+ String setup = mediaDescription.getAttribute("setup");
+ if (setup != null) {
+ mediaTransmissionTCP = true;
+ if ("active".equals(setup)) {
+ tcpActive = true;
+ } else if ("passive".equals(setup)) {
+ tcpActive = false;
+ }
+ }
+ }
+ break;
+ }
+ }
+ if (port == -1) {
+ logger.info("涓嶆敮鎸佺殑濯掍綋鏍煎紡锛岃繑鍥�415");
+ // 鍥炲涓嶆敮鎸佺殑鏍煎紡
+ responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE); // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415
+ return;
+ }
+ String username = sdp.getOrigin().getUsername();
+ String addressStr = sdp.getOrigin().getAddress();
+ logger.info("璁惧{}璇锋眰璇煶娴侊紝鍦板潃锛歿}:{}锛宻src锛歿}", username, addressStr, port, ssrc);
+
+
+
+
+
+
+ } else {
+ logger.warn("鏉ヨ嚜鏃犳晥璁惧/骞冲彴鐨勮姹�");
+ responseAck(evt, Response.BAD_REQUEST);
}
- }));
- if (logger.isDebugEnabled()) {
- logger.debug(playResult.getResult().toString());
}
} catch (SipException | InvalidArgumentException | ParseException e) {
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
index e97629b..5a24202 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
@@ -93,7 +93,7 @@
private static final String MESSAGE_ALARM = "Alarm";
private static final String MESSAGE_RECORD_INFO = "RecordInfo";
private static final String MESSAGE_MEDIA_STATUS = "MediaStatus";
- // private static final String MESSAGE_BROADCAST = "Broadcast";
+ private static final String MESSAGE_BROADCAST = "Broadcast";
private static final String MESSAGE_DEVICE_STATUS = "DeviceStatus";
private static final String MESSAGE_DEVICE_CONTROL = "DeviceControl";
private static final String MESSAGE_DEVICE_CONFIG = "DeviceConfig";
@@ -123,7 +123,7 @@
logger.info("鎺ユ敹鍒癈atalog娑堟伅");
processMessageCatalogList(evt);
} else if (MESSAGE_DEVICE_INFO.equals(cmd)) {
- //DeviceInfo娑堟伅澶勭悊
+ // DeviceInfo娑堟伅澶勭悊
processMessageDeviceInfo(evt);
} else if (MESSAGE_DEVICE_STATUS.equals(cmd)) {
// DeviceStatus娑堟伅澶勭悊
@@ -149,6 +149,9 @@
} else if (MESSAGE_PRESET_QUERY.equals(cmd)) {
logger.info("鎺ユ敹鍒癙resetQuery娑堟伅");
processMessagePresetQuery(evt);
+ } else if (MESSAGE_BROADCAST.equals(cmd)) {
+ // Broadcast娑堟伅澶勭悊
+ processMessageBroadcast(evt);
} else {
logger.info("鎺ユ敹鍒版秷鎭細" + cmd);
responseAck(evt);
@@ -298,7 +301,7 @@
// 杩滅▼鍚姩鍔熻兘
if (!XmlUtil.isEmpty(XmlUtil.getText(rootElement, "TeleBoot"))) {
if (deviceId.equals(targetGBId)) {
- // 杩滅▼鍚姩鍔熻兘锛氶渶瑕佸湪閲嶆柊鍚姩绋嬪簭鍚庡厛瀵筍ipStack瑙g粦
+ // 杩滅▼鍚姩鏈钩鍙帮細闇�瑕佸湪閲嶆柊鍚姩绋嬪簭鍚庡厛瀵筍ipStack瑙g粦
logger.info("鎵ц杩滅▼鍚姩鏈钩鍙板懡浠�");
ParentPlatform parentPlatform = storager.queryParentPlatById(platformId);
cmderFroPlatform.unregister(parentPlatform, null, null);
@@ -333,6 +336,7 @@
// 杩滅▼鍚姩鎸囧畾璁惧
}
}
+ // 浜戝彴/鍓嶇鎺у埗鍛戒护
if (!XmlUtil.isEmpty(XmlUtil.getText(rootElement,"PTZCmd")) && !deviceId.equals(targetGBId)) {
String cmdString = XmlUtil.getText(rootElement,"PTZCmd");
Device device = storager.queryVideoDeviceByPlatformIdAndChannelId(platformId, deviceId);
@@ -895,6 +899,37 @@
}
}
+ /**
+ * 澶勭悊AudioBroadcast璇煶骞挎挱Message
+ *
+ * @param evt
+ */
+ private void processMessageBroadcast(RequestEvent evt) {
+ try {
+ Element rootElement = getRootElement(evt);
+ String deviceId = XmlUtil.getText(rootElement, "DeviceID");
+ // 鍥炲200 OK
+ responseAck(evt);
+ if (rootElement.getName().equals("Response")) {
+ // 姝ゅ鏄鏈钩鍙板彂鍑築roadcast鎸囦护鐨勫簲绛�
+ JSONObject json = new JSONObject();
+ XmlUtil.node2Json(rootElement, json);
+ if (logger.isDebugEnabled()) {
+ logger.debug(json.toJSONString());
+ }
+ RequestMessage msg = new RequestMessage();
+ msg.setDeviceId(deviceId);
+ msg.setType(DeferredResultHolder.CALLBACK_CMD_BROADCAST);
+ msg.setData(json);
+ deferredResultHolder.invokeResult(msg);
+ } else {
+ // 姝ゅ鏄笂绾у彂鍑虹殑Broadcast鎸囦护
+ }
+ } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
+ e.printStackTrace();
+ }
+ }
+
/***
* 鍥炲200 OK
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/RegisterResponseProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/RegisterResponseProcessor.java
index a3952ff..38b0f07 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/RegisterResponseProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/RegisterResponseProcessor.java
@@ -50,7 +50,6 @@
*/
@Override
public void process(ResponseEvent evt, SipLayer layer, SipConfig config) {
- // TODO Auto-generated method stub
Response response = evt.getResponse();
CallIdHeader callIdHeader = (CallIdHeader) response.getHeader(CallIdHeader.NAME);
String callId = callIdHeader.getCallId();
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java
index b0d136e..0c773e6 100644
--- a/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java
@@ -2,6 +2,7 @@
import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.conf.MediaServerConfig;
+import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
@@ -26,6 +27,8 @@
import org.springframework.web.context.request.async.DeferredResult;
import java.util.UUID;
+
+import javax.sip.message.Response;
@CrossOrigin
@RestController
@@ -204,5 +207,47 @@
}
return new ResponseEntity<String>( result.toJSONString(), HttpStatus.OK);
}
+
+ /**
+ * 璇煶骞挎挱鍛戒护API鎺ュ彛
+ *
+ * @param deviceId
+ */
+ @GetMapping("/broadcast/{deviceId}")
+ @PostMapping("/broadcast/{deviceId}")
+ public DeferredResult<ResponseEntity<String>> broadcastApi(@PathVariable String deviceId) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("璇煶骞挎挱API璋冪敤");
+ }
+ Device device = storager.queryVideoDevice(deviceId);
+ cmder.audioBroadcastCmd(device, event -> {
+ Response response = event.getResponse();
+ RequestMessage msg = new RequestMessage();
+ msg.setId(DeferredResultHolder.CALLBACK_CMD_BROADCAST + deviceId);
+ JSONObject json = new JSONObject();
+ json.put("DeviceID", deviceId);
+ json.put("CmdType", "Broadcast");
+ json.put("Result", "Failed");
+ json.put("Description", String.format("璇煶骞挎挱鎿嶄綔澶辫触锛岄敊璇爜锛� %s, %s", response.getStatusCode(), response.getReasonPhrase()));
+ msg.setData(json);
+ resultHolder.invokeResult(msg);
+ });
+ DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(3 * 1000L);
+ result.onTimeout(() -> {
+ logger.warn(String.format("璇煶骞挎挱鎿嶄綔瓒呮椂, 璁惧鏈繑鍥炲簲绛旀寚浠�"));
+ RequestMessage msg = new RequestMessage();
+ msg.setId(DeferredResultHolder.CALLBACK_CMD_BROADCAST + deviceId);
+ JSONObject json = new JSONObject();
+ json.put("DeviceID", deviceId);
+ json.put("CmdType", "Broadcast");
+ json.put("Result", "Failed");
+ json.put("Error", "Timeout. Device did not response to broadcast command.");
+ msg.setData(json);
+ resultHolder.invokeResult(msg);
+ });
+ resultHolder.put(DeferredResultHolder.CALLBACK_CMD_BROADCAST + deviceId, result);
+ return result;
+ }
+
}
--
Gitblit v1.8.0