From 7e48d847402d2ea4da85af582529de676f30dc38 Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: 星期一, 08 五月 2023 17:56:56 +0800
Subject: [PATCH] Merge pull request #844 from xiaoQQya/wvp-28181-2.0
---
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java | 160 ++++++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 127 insertions(+), 33 deletions(-)
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 91f9bae..96e4098 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
@@ -11,6 +11,7 @@
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.SSRCFactory;
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;
@@ -42,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;
@@ -50,6 +52,7 @@
import java.text.ParseException;
import java.util.List;
import java.util.UUID;
+import java.util.Vector;
@SuppressWarnings(value = {"rawtypes", "unchecked"})
@Service
@@ -101,6 +104,9 @@
private ZlmHttpHookSubscribe subscribe;
@Autowired
+ private SSRCFactory ssrcFactory;
+
+ @Autowired
private RedisTemplate<Object, Object> redisTemplate;
@@ -137,7 +143,7 @@
if (rtpInfo.getBoolean("exist")) {
int localPort = rtpInfo.getInteger("local_port");
if (localPort == 0) {
- logger.warn("[鐐规挱]锛岀偣鎾椂鍙戠幇rtpServerC瀛樺湪锛屼絾鏄皻鏈紑濮嬫帹娴�");
+ logger.warn("[鐐规挱]锛岀偣鎾椂鍙戠幇rtpServer瀛樺湪锛屼絾鏄皻鏈紑濮嬫帹娴�");
// 姝ゆ椂璇存槑rtpServer宸茬粡鍒涘缓浣嗘槸娴佽繕娌℃湁鎺ㄤ笂鏉�
WVPResult wvpResult = new WVPResult();
wvpResult.setCode(ErrorCode.ERROR100.getCode());
@@ -176,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());
@@ -222,7 +228,7 @@
ZlmHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent,
InviteTimeOutCallback timeoutCallback) {
- logger.info("[鐐规挱寮�濮媇 deviceId: {}, channelId: {},鏀舵祦绔彛锛� {}, 鏀舵祦妯″紡锛歿}, SSRC: {}, SSRC鏍¢獙锛歿}", device.getDeviceId(), channelId, ssrcInfo.getPort(), device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck());
+ logger.info("[鐐规挱寮�濮媇 deviceId: {}, channelId: {},鏀舵祦绔彛锛歿}, 鏀舵祦妯″紡锛歿}, SSRC: {}, SSRC鏍¢獙锛歿}", device.getDeviceId(), channelId, ssrcInfo.getPort(), device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck());
// 瓒呮椂澶勭悊
String timeOutTaskKey = UUID.randomUUID().toString();
dynamicTask.startDelay(timeOutTaskKey, () -> {
@@ -292,24 +298,46 @@
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);
if (!mediaServerItem.isRtpEnable() || device.isSsrcCheck()) {
logger.info("[鐐规挱娑堟伅] SSRC淇 {}->{}", ssrcInfo.getSsrc(), ssrcInResponse);
-
- if (!mediaServerItem.getSsrcConfig().checkSsrc(ssrcInResponse)) {
+ if (!ssrcFactory.checkSsrc(mediaServerItem.getId(),ssrcInResponse)) {
// ssrc 涓嶅彲鐢�
+ logger.info("[鐐规挱娑堟伅] SSRC淇鏃跺彂鐜皊src涓嶅彲浣跨敤 {}->{}", ssrcInfo.getSsrc(), ssrcInResponse);
// 閲婃斁ssrc
- mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
+ ssrcFactory.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
event.msg = "涓嬬骇鑷畾涔変簡ssrc,浣嗘槸姝src涓嶅彲鐢�";
event.statusCode = 400;
errorEvent.response(event);
return;
}
-
- // 鍗曠鍙fā寮弒treamId涔熸湁鍙樺寲锛岄渶瑕侀噸鏂拌缃洃鍚�
+ // 鍗曠鍙fā寮弒treamId涔熸湁鍙樺寲锛岄噸鏂拌缃洃鍚嵆鍙�
if (!mediaServerItem.isRtpEnable()) {
// 娣诲姞璁㈤槄
HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId());
@@ -322,12 +350,32 @@
onPublishHandlerForPlay(mediaServerItemInUse, response, device.getDeviceId(), channelId);
hookEvent.response(mediaServerItemInUse, response);
});
+ return;
}
- // 鍏抽棴rtp server
- mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
- // 閲嶆柊寮�鍚痵src server
- mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), false, ssrcInfo.getPort());
+
+ // 鏇存柊ssrc
+ Boolean result = mediaServerService.updateRtpServerSSRC(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse);
+ if (!result) {
+ try {
+ logger.warn("[鍋滄鐐规挱] {}/{}", device.getDeviceId(), channelId);
+ cmder.streamByeCmd(device, channelId, ssrcInfo.getStream(), null, null);
+ } catch (InvalidArgumentException | SipException | ParseException | SsrcTransactionNotFoundException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 鍋滄鐐规挱锛� 鍙戦�丅YE: {}", e.getMessage());
+ throw new ControllerException(ErrorCode.ERROR100.getCode(), "鍛戒护鍙戦�佸け璐�: " + e.getMessage());
+ }
+
+ dynamicTask.stop(timeOutTaskKey);
+ // 閲婃斁ssrc
+ mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
+
+ streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
+ event.msg = "涓嬬骇鑷畾涔変簡ssrc,閲嶆柊璁剧疆鏀舵祦淇℃伅澶辫触";
+ event.statusCode = 500;
+ errorEvent.response(event);
+ }
+ }else {
+ logger.info("[鐐规挱娑堟伅] 鏀跺埌invite 200, 涓嬬骇鑷畾涔変簡ssrc, 浣嗘槸褰撳墠妯″紡鏃犻渶淇");
}
}
}, (event) -> {
@@ -348,7 +396,9 @@
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
- SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(new CmdSendFailEvent(null));
+ SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult();
+ eventResult.type = SipSubscribe.EventResultType.cmdSendFailEvent;
+ eventResult.statusCode = -1;
eventResult.msg = "鍛戒护鍙戦�佸け璐�";
errorEvent.response(eventResult);
}
@@ -450,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);
}
@@ -468,7 +517,7 @@
if (device == null) {
throw new ControllerException(ErrorCode.ERROR100.getCode(), "璁惧锛� " + deviceId + "涓嶅瓨鍦�");
}
-
+ logger.info("[鍥炴斁娑堟伅] deviceId: {}, channelId: {},鏀舵祦绔彛锛歿}, 鏀舵祦妯″紡锛歿}, SSRC: {}, SSRC鏍¢獙锛歿}", device.getDeviceId(), channelId, ssrcInfo.getPort(), device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck());
PlayBackResult<StreamInfo> playBackResult = new PlayBackResult<>();
String playBackTimeOutTaskKey = UUID.randomUUID().toString();
dynamicTask.startDelay(playBackTimeOutTaskKey, () -> {
@@ -539,9 +588,10 @@
if (!mediaServerItem.isRtpEnable() || device.isSsrcCheck()) {
logger.info("[鍥炴斁娑堟伅] SSRC淇 {}->{}", ssrcInfo.getSsrc(), ssrcInResponse);
- if (!mediaServerItem.getSsrcConfig().checkSsrc(ssrcInResponse)) {
+ if (!ssrcFactory.checkSsrc(mediaServerItem.getId(),ssrcInResponse)) {
// ssrc 涓嶅彲鐢�
// 閲婃斁ssrc
+ dynamicTask.stop(playBackTimeOutTaskKey);
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
eventResult.msg = "涓嬬骇鑷畾涔変簡ssrc,浣嗘槸姝src涓嶅彲鐢�";
@@ -564,10 +614,31 @@
hookEvent.call(new InviteStreamInfo(mediaServerItem, null, eventResult.callId, "rtp", ssrcInfo.getStream()));
});
}
+
// 鍏抽棴rtp server
- mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
- // 閲嶆柊寮�鍚痵src server
- mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), true, ssrcInfo.getPort());
+ mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream(), result->{
+ if (result) {
+ // 閲嶆柊寮�鍚痵src server
+ mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), true, ssrcInfo.getPort(), true, device.getStreamModeForParam());
+ }else {
+ try {
+ logger.warn("[鍥炴斁娑堟伅]鍋滄 {}/{}", device.getDeviceId(), channelId);
+ cmder.streamByeCmd(device, channelId, ssrcInfo.getStream(), null, null);
+ } catch (InvalidArgumentException | SipException | ParseException | SsrcTransactionNotFoundException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 鍋滄鐐规挱 鍋滄锛� 鍙戦�丅YE: {}", e.getMessage());
+ throw new ControllerException(ErrorCode.ERROR100.getCode(), "鍛戒护鍙戦�佸け璐�: " + e.getMessage());
+ }
+
+ dynamicTask.stop(playBackTimeOutTaskKey);
+ // 閲婃斁ssrc
+ mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
+ streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
+ errorEvent.response(eventResult);
+ eventResult.msg = "涓嬬骇鑷畾涔変簡ssrc,閲嶆柊璁剧疆鏀舵祦淇℃伅澶辫触";
+ eventResult.statusCode = 500;
+ errorEvent.response(eventResult);
+ }
+ });
}
}
}
@@ -576,7 +647,9 @@
} catch (InvalidArgumentException | SipException | ParseException e) {
logger.error("[鍛戒护鍙戦�佸け璐 鍥炴斁: {}", e.getMessage());
- SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(new CmdSendFailEvent(null));
+ SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult();
+ eventResult.type = SipSubscribe.EventResultType.cmdSendFailEvent;
+ eventResult.statusCode = -1;
eventResult.msg = "鍛戒护鍙戦�佸け璐�";
errorEvent.response(eventResult);
}
@@ -598,8 +671,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);
}
@@ -615,7 +687,7 @@
throw new ControllerException(ErrorCode.ERROR400.getCode(), "璁惧锛�" + deviceId + "涓嶅瓨鍦�");
}
PlayBackResult<StreamInfo> downloadResult = new PlayBackResult<>();
-
+ logger.info("[褰曞儚涓嬭浇] deviceId: {}, channelId: {},鏀舵祦绔彛锛歿}, 鏀舵祦妯″紡锛歿}, SSRC: {}, SSRC鏍¢獙锛歿}", device.getDeviceId(), channelId, ssrcInfo.getPort(), device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck());
String downLoadTimeOutTaskKey = UUID.randomUUID().toString();
dynamicTask.startDelay(downLoadTimeOutTaskKey, () -> {
logger.warn(String.format("褰曞儚涓嬭浇璇锋眰瓒呮椂锛宒eviceId锛�%s 锛宑hannelId锛�%s", deviceId, channelId));
@@ -644,7 +716,7 @@
streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
};
InviteStreamCallback hookEvent = (InviteStreamInfo inviteStreamInfo) -> {
- logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + inviteStreamInfo.getCallId());
+ logger.info("[褰曞儚涓嬭浇]鏀跺埌璁㈤槄娑堟伅锛� " + inviteStreamInfo.getCallId());
dynamicTask.stop(downLoadTimeOutTaskKey);
StreamInfo streamInfo = onPublishHandler(inviteStreamInfo.getMediaServerItem(), inviteStreamInfo.getResponse(), deviceId, channelId);
streamInfo.setStartTime(startTime);
@@ -674,11 +746,11 @@
if (ssrcInfo.getSsrc().equals(ssrcInResponse)) {
return;
}
- logger.info("[鍥炴斁娑堟伅] 鏀跺埌invite 200, 鍙戠幇涓嬬骇鑷畾涔変簡ssrc: {}", ssrcInResponse);
+ logger.info("[褰曞儚涓嬭浇] 鏀跺埌invite 200, 鍙戠幇涓嬬骇鑷畾涔変簡ssrc: {}", ssrcInResponse);
if (!mediaServerItem.isRtpEnable() || device.isSsrcCheck()) {
- logger.info("[鍥炴斁娑堟伅] SSRC淇 {}->{}", ssrcInfo.getSsrc(), ssrcInResponse);
+ logger.info("[褰曞儚涓嬭浇] SSRC淇 {}->{}", ssrcInfo.getSsrc(), ssrcInResponse);
- if (!mediaServerItem.getSsrcConfig().checkSsrc(ssrcInResponse)) {
+ if (!ssrcFactory.checkSsrc(mediaServerItem.getId(),ssrcInResponse)) {
// ssrc 涓嶅彲鐢�
// 閲婃斁ssrc
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
@@ -703,19 +775,41 @@
hookEvent.call(new InviteStreamInfo(mediaServerItem, null, eventResult.callId, "rtp", ssrcInfo.getStream()));
});
}
+
// 鍏抽棴rtp server
- mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
- // 閲嶆柊寮�鍚痵src server
- mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), true, ssrcInfo.getPort());
+ mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream(), result->{
+ if (result) {
+ // 閲嶆柊寮�鍚痵src server
+ mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), true, ssrcInfo.getPort(), true, device.getStreamModeForParam());
+ }else {
+ try {
+ logger.warn("[褰曞儚涓嬭浇] 鍋滄{}/{}", device.getDeviceId(), channelId);
+ cmder.streamByeCmd(device, channelId, ssrcInfo.getStream(), null, null);
+ } catch (InvalidArgumentException | SipException | ParseException | SsrcTransactionNotFoundException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 褰曞儚涓嬭浇鍋滄锛� 鍙戦�丅YE: {}", e.getMessage());
+ throw new ControllerException(ErrorCode.ERROR100.getCode(), "鍛戒护鍙戦�佸け璐�: " + e.getMessage());
+ }
+
+ dynamicTask.stop(downLoadTimeOutTaskKey);
+ // 閲婃斁ssrc
+ mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
+
+ streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
+ eventResult.msg = "涓嬬骇鑷畾涔変簡ssrc,閲嶆柊璁剧疆鏀舵祦淇℃伅澶辫触";
+ eventResult.statusCode = 500;
+ errorEvent.response(eventResult);
+ }
+ });
}
}
}
-
});
} catch (InvalidArgumentException | SipException | ParseException e) {
logger.error("[鍛戒护鍙戦�佸け璐 褰曞儚涓嬭浇: {}", e.getMessage());
- SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(new CmdSendFailEvent(null));
+ SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult();
+ eventResult.type = SipSubscribe.EventResultType.cmdSendFailEvent;
+ eventResult.statusCode = -1;
eventResult.msg = "鍛戒护鍙戦�佸け璐�";
errorEvent.response(eventResult);
}
--
Gitblit v1.8.0