|
@@ -39,6 +39,7 @@ import org.springframework.stereotype.Service;
|
|
|
import org.springframework.util.ResourceUtils;
|
|
import org.springframework.util.ResourceUtils;
|
|
|
import org.springframework.web.context.request.async.DeferredResult;
|
|
import org.springframework.web.context.request.async.DeferredResult;
|
|
|
|
|
|
|
|
|
|
+import javax.sip.ResponseEvent;
|
|
|
import java.io.FileNotFoundException;
|
|
import java.io.FileNotFoundException;
|
|
|
import java.math.BigDecimal;
|
|
import java.math.BigDecimal;
|
|
|
import java.util.*;
|
|
import java.util.*;
|
|
@@ -256,18 +257,46 @@ public class PlayServiceImpl implements IPlayService {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}, userSetting.getPlayTimeout());
|
|
}, userSetting.getPlayTimeout());
|
|
|
-
|
|
|
|
|
|
|
+ final String ssrc = ssrcInfo.getSsrc();
|
|
|
cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> {
|
|
cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> {
|
|
|
logger.info("收到订阅消息: " + response.toJSONString());
|
|
logger.info("收到订阅消息: " + response.toJSONString());
|
|
|
timer.cancel();
|
|
timer.cancel();
|
|
|
// hook响应
|
|
// hook响应
|
|
|
onPublishHandlerForPlay(mediaServerItemInuse, response, device.getDeviceId(), channelId, uuid);
|
|
onPublishHandlerForPlay(mediaServerItemInuse, response, device.getDeviceId(), channelId, uuid);
|
|
|
hookEvent.response(mediaServerItemInuse, response);
|
|
hookEvent.response(mediaServerItemInuse, response);
|
|
|
|
|
+ }, (event) -> {
|
|
|
|
|
+ ResponseEvent responseEvent = (ResponseEvent)event.event;
|
|
|
|
|
+ String contentString = new String(responseEvent.getResponse().getRawContent());
|
|
|
|
|
+ // 获取ssrc
|
|
|
|
|
+ int ssrcIndex = contentString.indexOf("y=");
|
|
|
|
|
+ // 检查是否有y字段
|
|
|
|
|
+ if (ssrcIndex >= 0) {
|
|
|
|
|
+ //ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段 TODO 后续对不规范的非10位ssrc兼容
|
|
|
|
|
+ String ssrcInResponse = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
|
|
|
|
|
+ if (!ssrc.equals(ssrcInResponse) && device.isSsrcCheck()) { // 查询到ssrc不一致且开启了ssrc校验则需要针对处理
|
|
|
|
|
+ // 查询 ssrcInResponse 是否可用
|
|
|
|
|
+ if (mediaServerItem.isRtpEnable() && !mediaServerItem.getSsrcConfig().checkSsrc(ssrcInResponse)) {
|
|
|
|
|
+ // ssrc 不可用
|
|
|
|
|
+ // 释放ssrc
|
|
|
|
|
+ mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc());
|
|
|
|
|
+ streamSession.remove(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
|
|
|
|
|
+ event.msg = "下级自定义了ssrc,但是此ssrc不可用";
|
|
|
|
|
+ event.statusCode = 400;
|
|
|
|
|
+ errorEvent.response(event);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 关闭rtp server
|
|
|
|
|
+ mediaServerService.closeRTPServer(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
|
|
|
|
|
+ // 重新开启ssrc server
|
|
|
|
|
+ mediaServerService.openRTPServer(mediaServerItem, finalSsrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), false);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}, (event) -> {
|
|
}, (event) -> {
|
|
|
timer.cancel();
|
|
timer.cancel();
|
|
|
mediaServerService.closeRTPServer(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
|
|
mediaServerService.closeRTPServer(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
|
|
|
// 释放ssrc
|
|
// 释放ssrc
|
|
|
mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc());
|
|
mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc());
|
|
|
|
|
+
|
|
|
streamSession.remove(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
|
|
streamSession.remove(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
|
|
|
errorEvent.response(event);
|
|
errorEvent.response(event);
|
|
|
});
|
|
});
|