From 0f3898910c42d4303347ac7295d3c7f0cc8e8457 Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: 星期三, 19 四月 2023 16:21:28 +0800
Subject: [PATCH] 收流时设置re_use_port参数解决端口关闭快速打开造成的端口未释放问题, 支持点播的tcp主动
---
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java | 4 +-
web_src/src/components/DeviceList.vue | 4 +
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java | 11 +++++
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java | 22 +++++++++-
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java | 39 +++++++++++++++----
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java | 8 ++++
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java | 14 +-----
src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java | 7 +--
8 files changed, 79 insertions(+), 30 deletions(-)
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
index 9093970..daf709f 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
@@ -247,6 +247,17 @@
return streamMode;
}
+ public Integer getStreamModeForParam() {
+ if (streamMode.equalsIgnoreCase("UDP")) {
+ return 0;
+ }else if (streamMode.equalsIgnoreCase("TCP-PASSIVE")) {
+ return 1;
+ }else if (streamMode.equalsIgnoreCase("TCP-ACTIVE")) {
+ return 2;
+ }
+ return 0;
+ }
+
public void setStreamMode(String streamMode) {
this.streamMode = streamMode;
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
index aef01e4..a4367b4 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
@@ -425,7 +425,7 @@
sendRtpItem.setApp("rtp");
if ("Playback".equalsIgnoreCase(sessionName)) {
sendRtpItem.setPlayType(InviteStreamType.PLAYBACK);
- SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, device.isSsrcCheck(), true);
+ SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, null, device.isSsrcCheck(), true, 0, false, device.getStreamModeForParam());
sendRtpItem.setStreamId(ssrcInfo.getStream());
// 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
redisCatchStorage.updateSendRTPSever(sendRtpItem);
@@ -469,7 +469,7 @@
if (mediaServerItem.isRtpEnable()) {
streamId = String.format("%s_%s", device.getDeviceId(), channelId);
}
- SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, null, device.isSsrcCheck(), false);
+ SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, null, device.isSsrcCheck(), false, 0, false, device.getStreamModeForParam());
logger.info(JSONObject.toJSONString(ssrcInfo));
sendRtpItem.setStreamId(ssrcInfo.getStream());
sendRtpItem.setSsrc(ssrc.equals(ssrcDefault) ? ssrcInfo.getSsrc() : ssrc);
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java
index 77758a3..13f3240 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java
@@ -346,4 +346,12 @@
param.put("stream_id", streamId);
return sendPost(mediaServerItem, "resumeRtpCheck",param, null);
}
+
+ public JSONObject connectRtpServer(MediaServerItem mediaServerItem, String dst_url, int dst_port, String stream_id) {
+ Map<String, Object> param = new HashMap<>(1);
+ param.put("dst_url", dst_url);
+ param.put("dst_port", dst_port);
+ param.put("stream_id", stream_id);
+ return sendPost(mediaServerItem, "connectRtpServer",param, null);
+ }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
index ce38b10..99576c4 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
@@ -91,7 +91,17 @@
return result;
}
- public int createRTPServer(MediaServerItem mediaServerItem, String streamId, int ssrc, Integer port) {
+ /**
+ * 寮�鍚痳tpServer
+ * @param mediaServerItem zlm鏈嶅姟瀹炰緥
+ * @param streamId 娴両d
+ * @param ssrc ssrc
+ * @param port 绔彛锛� 0/null涓轰娇鐢ㄩ殢鏈�
+ * @param reUsePort 鏄惁閲嶇敤绔彛
+ * @param tcpMode 0/null udp 妯″紡锛�1 tcp 琚姩妯″紡, 2 tcp 涓诲姩妯″紡銆�
+ * @return
+ */
+ public int createRTPServer(MediaServerItem mediaServerItem, String streamId, int ssrc, Integer port, Boolean reUsePort, Integer tcpMode) {
int result = -1;
// 鏌ヨ姝tp server 鏄惁宸茬粡瀛樺湪
JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaServerItem, streamId);
@@ -107,7 +117,7 @@
JSONObject jsonObject = zlmresTfulUtils.closeRtpServer(mediaServerItem, param);
if (jsonObject != null ) {
if (jsonObject.getInteger("code") == 0) {
- return createRTPServer(mediaServerItem, streamId, ssrc, port);
+ return createRTPServer(mediaServerItem, streamId, ssrc, port, reUsePort, tcpMode);
}else {
logger.warn("[寮�鍚痳tpServer], 閲嶅惎RtpServer閿欒");
}
@@ -121,8 +131,14 @@
Map<String, Object> param = new HashMap<>();
- param.put("enable_tcp", 1);
+ if (tcpMode == null) {
+ tcpMode = 0;
+ }
+ param.put("tcp_mode", tcpMode);
param.put("stream_id", streamId);
+ if (reUsePort != null) {
+ param.put("re_use_port", reUsePort?"1":"0");
+ }
// 鎺ㄦ祦绔彛璁剧疆0鍒欎娇鐢ㄩ殢鏈虹鍙�
if (port == null) {
param.put("port", 0);
diff --git a/src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java b/src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
index a5b9034..495b009 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
@@ -44,11 +44,8 @@
void updateVmServer(List<MediaServerItem> mediaServerItemList);
- SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, boolean ssrcCheck, boolean isPlayback);
-
- SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, String ssrc, boolean ssrcCheck, boolean isPlayback);
-
- SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, String ssrc, boolean ssrcCheck, boolean isPlayback, Integer port);
+ SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, String ssrc, boolean ssrcCheck,
+ boolean isPlayback, Integer port, Boolean reUsePort, Integer tcpMode);
void closeRTPServer(MediaServerItem mediaServerItem, String streamId);
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
index 29eb6e9..94ed200 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
@@ -125,13 +125,10 @@
}
}
- @Override
- public SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, boolean ssrcCheck, boolean isPlayback) {
- return openRTPServer(mediaServerItem, streamId, null, ssrcCheck,isPlayback);
- }
@Override
- public SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, String presetSsrc, boolean ssrcCheck, boolean isPlayback, Integer port) {
+ public SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, String presetSsrc, boolean ssrcCheck,
+ boolean isPlayback, Integer port, Boolean reUsePort, Integer tcpMode) {
if (mediaServerItem == null || mediaServerItem.getId() == null) {
logger.info("[openRTPServer] 澶辫触, mediaServerItem == null || mediaServerItem.getId() == null");
return null;
@@ -153,16 +150,11 @@
}
int rtpServerPort;
if (mediaServerItem.isRtpEnable()) {
- rtpServerPort = zlmrtpServerFactory.createRTPServer(mediaServerItem, streamId, ssrcCheck?Integer.parseInt(ssrc):0, port);
+ rtpServerPort = zlmrtpServerFactory.createRTPServer(mediaServerItem, streamId, ssrcCheck?Integer.parseInt(ssrc):0, port, reUsePort, tcpMode);
} else {
rtpServerPort = mediaServerItem.getRtpProxyPort();
}
return new SSRCInfo(rtpServerPort, ssrc, streamId);
- }
-
- @Override
- public SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, String ssrc, boolean ssrcCheck, boolean isPlayback) {
- return openRTPServer(mediaServerItem, streamId, ssrc, ssrcCheck, isPlayback, null);
}
@Override
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
index 6c2ee7e..a18d8ba 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -43,6 +43,7 @@
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
+import javax.sdp.*;
import javax.sip.InvalidArgumentException;
import javax.sip.ResponseEvent;
import javax.sip.SipException;
@@ -51,6 +52,7 @@
import java.text.ParseException;
import java.util.List;
import java.util.UUID;
+import java.util.Vector;
@SuppressWarnings(value = {"rawtypes", "unchecked"})
@Service
@@ -180,7 +182,7 @@
if (mediaServerItem.isRtpEnable()) {
streamId = String.format("%s_%s", device.getDeviceId(), channelId);
}
- SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, device.isSsrcCheck(), false);
+ SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, null, device.isSsrcCheck(), false, 0, false, device.getStreamModeForParam());
if (ssrcInfo == null) {
WVPResult wvpResult = new WVPResult();
wvpResult.setCode(ErrorCode.ERROR100.getCode());
@@ -296,6 +298,29 @@
String ssrcInResponse = contentString.substring(ssrcIndex + 2, ssrcIndex + 12).trim();
// 鏌ヨ鍒皊src涓嶄竴鑷翠笖寮�鍚簡ssrc鏍¢獙鍒欓渶瑕侀拡瀵瑰鐞�
if (ssrcInfo.getSsrc().equals(ssrcInResponse)) {
+ if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE")) {
+ String substring = contentString.substring(0, contentString.indexOf("y="));
+ try {
+ SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring);
+ int port = -1;
+ Vector mediaDescriptions = sdp.getMediaDescriptions(true);
+ for (Object description : mediaDescriptions) {
+ MediaDescription mediaDescription = (MediaDescription) description;
+ Media media = mediaDescription.getMedia();
+
+ Vector mediaFormats = media.getMediaFormats(false);
+ if (mediaFormats.contains("96")) {
+ port = media.getMediaPort();
+ break;
+ }
+ }
+ logger.info("[鐐规挱-TCP涓诲姩杩炴帴瀵规柟] deviceId: {}, channelId: {}, 杩炴帴瀵规柟鐨勫湴鍧�锛歿}:{}, 鏀舵祦妯″紡锛歿}, SSRC: {}, SSRC鏍¢獙锛歿}", device.getDeviceId(), channelId, sdp.getConnection().getAddress(), port, device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck());
+ JSONObject jsonObject = zlmresTfulUtils.connectRtpServer(mediaServerItem, sdp.getConnection().getAddress(), port, ssrcInfo.getStream());
+ logger.info("[鐐规挱-TCP涓诲姩杩炴帴瀵规柟] 缁撴灉锛� {}", jsonObject);
+ } catch (SdpException e) {
+ logger.error("[鐐规挱-TCP涓诲姩杩炴帴瀵规柟] deviceId: {}, channelId: {}, 瑙f瀽200OK鐨凷DP淇℃伅澶辫触", device.getDeviceId(), channelId, e);
+ }
+ }
return;
}
logger.info("[鐐规挱娑堟伅] 鏀跺埌invite 200, 鍙戠幇涓嬬骇鑷畾涔変簡ssrc: {}", ssrcInResponse);
@@ -331,7 +356,7 @@
mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream(), result->{
if (result) {
// 閲嶆柊寮�鍚痵src server
- mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), false, ssrcInfo.getPort());
+ mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), false, ssrcInfo.getPort(), true, device.getStreamModeForParam());
}else {
try {
logger.warn("[鍋滄鐐规挱] {}/{}", device.getDeviceId(), channelId);
@@ -475,8 +500,7 @@
return;
}
MediaServerItem newMediaServerItem = getNewMediaServerItem(device);
- SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, device.isSsrcCheck(), true);
-
+ SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, null, device.isSsrcCheck(), true, 0, false, device.getStreamModeForParam());
playBack(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, inviteStreamCallback, callback);
}
@@ -595,7 +619,7 @@
mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream(), result->{
if (result) {
// 閲嶆柊寮�鍚痵src server
- mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), true, ssrcInfo.getPort());
+ mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), true, ssrcInfo.getPort(), true, device.getStreamModeForParam());
}else {
try {
logger.warn("[鍥炴斁娑堟伅]鍋滄 {}/{}", device.getDeviceId(), channelId);
@@ -645,8 +669,7 @@
playBackCallback.call(downloadResult);
return;
}
- SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, device.isSsrcCheck(), true);
-
+ SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, null, device.isSsrcCheck(), true, 0, false, device.getStreamModeForParam());
download(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, downloadSpeed, infoCallBack, playBackCallback);
}
@@ -755,7 +778,7 @@
mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream(), result->{
if (result) {
// 閲嶆柊寮�鍚痵src server
- mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), true, ssrcInfo.getPort());
+ mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), true, ssrcInfo.getPort(), true, device.getStreamModeForParam());
}else {
try {
logger.warn("[褰曞儚涓嬭浇] 鍋滄{}/{}", device.getDeviceId(), channelId);
diff --git a/web_src/src/components/DeviceList.vue b/web_src/src/components/DeviceList.vue
index 29e049d..bff0d1d 100644
--- a/web_src/src/components/DeviceList.vue
+++ b/web_src/src/components/DeviceList.vue
@@ -25,11 +25,13 @@
</el-table-column>
<el-table-column prop="manufacturer" label="鍘傚" min-width="120" >
</el-table-column>
+ <el-table-column prop="transport" label="淇′护浼犺緭妯″紡" min-width="120" >
+ </el-table-column>
<el-table-column label="娴佷紶杈撴ā寮�" min-width="160" >
<template slot-scope="scope">
<el-select size="mini" @change="transportChange(scope.row)" v-model="scope.row.streamMode" placeholder="璇烽�夋嫨" style="width: 120px">
<el-option key="UDP" label="UDP" value="UDP"></el-option>
- <el-option key="TCP-ACTIVE" label="TCP涓诲姩妯″紡" :disabled="true" value="TCP-ACTIVE"></el-option>
+ <el-option key="TCP-ACTIVE" label="TCP涓诲姩妯″紡" value="TCP-ACTIVE"></el-option>
<el-option key="TCP-PASSIVE" label="TCP琚姩妯″紡" value="TCP-PASSIVE"></el-option>
</el-select>
</template>
--
Gitblit v1.8.0