Commit 446f729e559730b813291f072a6e33a012923018

Authored by 648540858
1 parent 03f35986

优化sdp解析,兼容带有f=的设备

src/main/java/com/genersoft/iot/vmp/gb28181/bean/Gb28181Sdp.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.bean;
  2 +
  3 +import javax.sdp.SessionDescription;
  4 +
  5 +/**
  6 + * 28181 的SDP解析器
  7 + */
  8 +public class Gb28181Sdp {
  9 + private SessionDescription baseSdb;
  10 + private String ssrc;
  11 +
  12 + private String mediaDescription;
  13 +
  14 + public static Gb28181Sdp getInstance(SessionDescription baseSdb, String ssrc, String mediaDescription) {
  15 + Gb28181Sdp gb28181Sdp = new Gb28181Sdp();
  16 + gb28181Sdp.setBaseSdb(baseSdb);
  17 + gb28181Sdp.setSsrc(ssrc);
  18 + gb28181Sdp.setMediaDescription(mediaDescription);
  19 + return gb28181Sdp;
  20 + }
  21 +
  22 +
  23 + public SessionDescription getBaseSdb() {
  24 + return baseSdb;
  25 + }
  26 +
  27 + public void setBaseSdb(SessionDescription baseSdb) {
  28 + this.baseSdb = baseSdb;
  29 + }
  30 +
  31 + public String getSsrc() {
  32 + return ssrc;
  33 + }
  34 +
  35 + public void setSsrc(String ssrc) {
  36 + this.ssrc = ssrc;
  37 + }
  38 +
  39 + public String getMediaDescription() {
  40 + return mediaDescription;
  41 + }
  42 +
  43 + public void setMediaDescription(String mediaDescription) {
  44 + this.mediaDescription = mediaDescription;
  45 + }
  46 +}
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
@@ -54,8 +54,8 @@ public class SIPRequestHeaderPlarformProvider { @@ -54,8 +54,8 @@ public class SIPRequestHeaderPlarformProvider {
54 parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort()); 54 parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort());
55 //via 55 //via
56 ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); 56 ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
57 - ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(parentPlatform.getServerIP(),  
58 - parentPlatform.getServerPort(), parentPlatform.getTransport(), SipUtils.getNewViaTag()); 57 + ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(parentPlatform.getDeviceIp(),
  58 + Integer.parseInt(parentPlatform.getDevicePort()), parentPlatform.getTransport(), SipUtils.getNewViaTag());
59 viaHeader.setRPort(); 59 viaHeader.setRPort();
60 viaHeaders.add(viaHeader); 60 viaHeaders.add(viaHeader);
61 //from 61 //from
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
@@ -574,11 +574,7 @@ public class SIPCommander implements ISIPCommander { @@ -574,11 +574,7 @@ public class SIPCommander implements ISIPCommander {
574 ResponseEvent responseEvent = (ResponseEvent) event.event; 574 ResponseEvent responseEvent = (ResponseEvent) event.event;
575 SIPResponse response = (SIPResponse) responseEvent.getResponse(); 575 SIPResponse response = (SIPResponse) responseEvent.getResponse();
576 String contentString =new String(response.getRawContent()); 576 String contentString =new String(response.getRawContent());
577 - int ssrcIndex = contentString.indexOf("y=");  
578 - String ssrc=ssrcInfo.getSsrc();  
579 - if (ssrcIndex >= 0) {  
580 - ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);  
581 - } 577 + String ssrc = SipUtils.getSsrcFromSdp(contentString);
582 streamSession.put(device.getDeviceId(), channelId, response.getCallIdHeader().getCallId(), ssrcInfo.getStream(), ssrc, mediaServerItem.getId(), response, InviteSessionType.DOWNLOAD); 578 streamSession.put(device.getDeviceId(), channelId, response.getCallIdHeader().getCallId(), ssrcInfo.getStream(), ssrc, mediaServerItem.getId(), response, InviteSessionType.DOWNLOAD);
583 okEvent.response(event); 579 okEvent.response(event);
584 }); 580 });
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
@@ -241,18 +241,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -241,18 +241,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
241 // 解析sdp消息, 使用jainsip 自带的sdp解析方式 241 // 解析sdp消息, 使用jainsip 自带的sdp解析方式
242 String contentString = new String(request.getRawContent()); 242 String contentString = new String(request.getRawContent());
243 243
244 - // jainSip不支持y=字段, 移除以解析。  
245 - // 检查是否有y字段  
246 - int ssrcIndex = contentString.indexOf("y=");  
247 -  
248 - SessionDescription sdp;  
249 - if (ssrcIndex >= 0) {  
250 - //ssrc规定长度为10个字节,不取余下长度以避免后续还有“f=”字段  
251 - String substring = contentString.substring(0, ssrcIndex);  
252 - sdp = SdpFactory.getInstance().createSessionDescription(substring);  
253 - } else {  
254 - sdp = SdpFactory.getInstance().createSessionDescription(contentString);  
255 - } 244 + Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString);
  245 + SessionDescription sdp = gb28181Sdp.getBaseSdb();
256 String sessionName = sdp.getSessionName().getValue(); 246 String sessionName = sdp.getSessionName().getValue();
257 247
258 Long startTime = null; 248 Long startTime = null;
@@ -340,11 +330,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -340,11 +330,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
340 } 330 }
341 331
342 String ssrc; 332 String ssrc;
343 - if (userSetting.getUseCustomSsrcForParentInvite() || ssrcIndex < 0) { 333 + if (userSetting.getUseCustomSsrcForParentInvite() || gb28181Sdp.getSsrc() == null) {
344 // 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 334 // 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式
345 ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId()); 335 ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId());
346 }else { 336 }else {
347 - ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); 337 + ssrc = gb28181Sdp.getSsrc();
348 } 338 }
349 String streamTypeStr = null; 339 String streamTypeStr = null;
350 if (mediaTransmissionTCP) { 340 if (mediaTransmissionTCP) {
@@ -513,11 +503,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -513,11 +503,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
513 } else if (gbStream != null) { 503 } else if (gbStream != null) {
514 504
515 String ssrc; 505 String ssrc;
516 - if (userSetting.getUseCustomSsrcForParentInvite() || ssrcIndex < 0) { 506 + if (userSetting.getUseCustomSsrcForParentInvite() || gb28181Sdp.getSsrc() == null) {
517 // 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 507 // 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式
518 ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId()); 508 ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId());
519 }else { 509 }else {
520 - ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); 510 + ssrc = gb28181Sdp.getSsrc();
521 } 511 }
522 512
523 if("push".equals(gbStream.getStreamType())) { 513 if("push".equals(gbStream.getStreamType())) {
@@ -891,20 +881,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -891,20 +881,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
891 } 881 }
892 String contentString = new String(request.getRawContent()); 882 String contentString = new String(request.getRawContent());
893 // jainSip不支持y=字段, 移除移除以解析。 883 // jainSip不支持y=字段, 移除移除以解析。
894 - String substring = contentString;  
895 String ssrc = "0000000404"; 884 String ssrc = "0000000404";
896 - int ssrcIndex = contentString.indexOf("y=");  
897 - if (ssrcIndex > 0) {  
898 - substring = contentString.substring(0, ssrcIndex);  
899 - ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);  
900 - }  
901 - ssrcIndex = substring.indexOf("f=");  
902 - if (ssrcIndex > 0) {  
903 - substring = contentString.substring(0, ssrcIndex);  
904 - }  
905 - SessionDescription sdp = null; 885 +
906 try { 886 try {
907 - sdp = SdpFactory.getInstance().createSessionDescription(substring); 887 + Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString);
  888 + SessionDescription sdp = gb28181Sdp.getBaseSdb();
908 // 获取支持的格式 889 // 获取支持的格式
909 Vector mediaDescriptions = sdp.getMediaDescriptions(true); 890 Vector mediaDescriptions = sdp.getMediaDescriptions(true);
910 // 查看是否支持PS 负载96 891 // 查看是否支持PS 负载96
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java
1 package com.genersoft.iot.vmp.gb28181.transmit.event.response.impl; 1 package com.genersoft.iot.vmp.gb28181.transmit.event.response.impl;
2 2
3 import com.genersoft.iot.vmp.gb28181.SipLayer; 3 import com.genersoft.iot.vmp.gb28181.SipLayer;
  4 +import com.genersoft.iot.vmp.gb28181.bean.Gb28181Sdp;
4 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; 5 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
5 import com.genersoft.iot.vmp.gb28181.transmit.SIPSender; 6 import com.genersoft.iot.vmp.gb28181.transmit.SIPSender;
6 import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; 7 import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider;
7 import com.genersoft.iot.vmp.gb28181.transmit.event.response.SIPResponseProcessorAbstract; 8 import com.genersoft.iot.vmp.gb28181.transmit.event.response.SIPResponseProcessorAbstract;
  9 +import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
8 import gov.nist.javax.sip.ResponseEventExt; 10 import gov.nist.javax.sip.ResponseEventExt;
9 import gov.nist.javax.sip.message.SIPResponse; 11 import gov.nist.javax.sip.message.SIPResponse;
10 import org.slf4j.Logger; 12 import org.slf4j.Logger;
@@ -12,7 +14,6 @@ import org.slf4j.LoggerFactory; @@ -12,7 +14,6 @@ import org.slf4j.LoggerFactory;
12 import org.springframework.beans.factory.annotation.Autowired; 14 import org.springframework.beans.factory.annotation.Autowired;
13 import org.springframework.stereotype.Component; 15 import org.springframework.stereotype.Component;
14 16
15 -import javax.sdp.SdpFactory;  
16 import javax.sdp.SdpParseException; 17 import javax.sdp.SdpParseException;
17 import javax.sdp.SessionDescription; 18 import javax.sdp.SessionDescription;
18 import javax.sip.InvalidArgumentException; 19 import javax.sip.InvalidArgumentException;
@@ -79,18 +80,8 @@ public class InviteResponseProcessor extends SIPResponseProcessorAbstract { @@ -79,18 +80,8 @@ public class InviteResponseProcessor extends SIPResponseProcessorAbstract {
79 ResponseEventExt event = (ResponseEventExt)evt; 80 ResponseEventExt event = (ResponseEventExt)evt;
80 81
81 String contentString = new String(response.getRawContent()); 82 String contentString = new String(response.getRawContent());
82 - // jainSip不支持y=字段, 移除以解析。  
83 - int ssrcIndex = contentString.indexOf("y=");  
84 - // 检查是否有y字段  
85 - SessionDescription sdp;  
86 - if (ssrcIndex >= 0) {  
87 - //ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段  
88 - String substring = contentString.substring(0, contentString.indexOf("y="));  
89 - sdp = SdpFactory.getInstance().createSessionDescription(substring);  
90 - } else {  
91 - sdp = SdpFactory.getInstance().createSessionDescription(contentString);  
92 - }  
93 - 83 + Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString);
  84 + SessionDescription sdp = gb28181Sdp.getBaseSdb();
94 SipURI requestUri = SipFactory.getInstance().createAddressFactory().createSipURI(sdp.getOrigin().getUsername(), event.getRemoteIpAddress() + ":" + event.getRemotePort()); 85 SipURI requestUri = SipFactory.getInstance().createAddressFactory().createSipURI(sdp.getOrigin().getUsername(), event.getRemoteIpAddress() + ":" + event.getRemotePort());
95 Request reqAck = headerProvider.createAckRequest(response.getLocalAddress().getHostAddress(), requestUri, response); 86 Request reqAck = headerProvider.createAckRequest(response.getLocalAddress().getHostAddress(), requestUri, response);
96 87
src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java
1 package com.genersoft.iot.vmp.gb28181.utils; 1 package com.genersoft.iot.vmp.gb28181.utils;
2 2
3 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; 3 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
  4 +import com.genersoft.iot.vmp.gb28181.bean.Gb28181Sdp;
4 import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo; 5 import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo;
5 import com.genersoft.iot.vmp.utils.GitUtil; 6 import com.genersoft.iot.vmp.utils.GitUtil;
6 import gov.nist.javax.sip.address.AddressImpl; 7 import gov.nist.javax.sip.address.AddressImpl;
@@ -10,6 +11,9 @@ import gov.nist.javax.sip.message.SIPRequest; @@ -10,6 +11,9 @@ import gov.nist.javax.sip.message.SIPRequest;
10 import org.apache.commons.lang3.RandomStringUtils; 11 import org.apache.commons.lang3.RandomStringUtils;
11 import org.springframework.util.ObjectUtils; 12 import org.springframework.util.ObjectUtils;
12 13
  14 +import javax.sdp.SdpFactory;
  15 +import javax.sdp.SdpParseException;
  16 +import javax.sdp.SessionDescription;
13 import javax.sip.PeerUnavailableException; 17 import javax.sip.PeerUnavailableException;
14 import javax.sip.SipFactory; 18 import javax.sip.SipFactory;
15 import javax.sip.header.FromHeader; 19 import javax.sip.header.FromHeader;
@@ -190,4 +194,52 @@ public class SipUtils { @@ -190,4 +194,52 @@ public class SipUtils {
190 } 194 }
191 return deviceChannel; 195 return deviceChannel;
192 } 196 }
  197 +
  198 + public static Gb28181Sdp parseSDP(String sdpStr) throws SdpParseException {
  199 +
  200 + // jainSip不支持y= f=字段, 移除以解析。
  201 + int ssrcIndex = sdpStr.indexOf("y=");
  202 + int mediaDescriptionIndex = sdpStr.indexOf("f=");
  203 + // 检查是否有y字段
  204 + SessionDescription sdp;
  205 + String ssrc = null;
  206 + String mediaDescription = null;
  207 + if (mediaDescriptionIndex == 0 && ssrcIndex == 0) {
  208 + sdp = SdpFactory.getInstance().createSessionDescription(sdpStr);
  209 + }else {
  210 + int baseSdpIndex = Math.min(mediaDescriptionIndex, ssrcIndex);
  211 + //ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段
  212 + String substring = sdpStr.substring(0, baseSdpIndex);
  213 + sdp = SdpFactory.getInstance().createSessionDescription(substring);
  214 +
  215 + String lines[] = sdpStr.split("\\r?\\n");
  216 + for (String line : lines) {
  217 + if (line.trim().startsWith("y=")) {
  218 + ssrc = line.substring(2);
  219 + }else if (line.trim().startsWith("f=")) {
  220 + mediaDescription = line.substring(2);
  221 + }
  222 + if (ssrc != null && mediaDescription != null) {
  223 + break;
  224 + }
  225 + }
  226 + }
  227 + return Gb28181Sdp.getInstance(sdp, ssrc, mediaDescription);
  228 + }
  229 +
  230 + public static String getSsrcFromSdp(String sdpStr) {
  231 +
  232 + // jainSip不支持y= f=字段, 移除以解析。
  233 + int ssrcIndex = sdpStr.indexOf("y=");
  234 + if (ssrcIndex == 0) {
  235 + return null;
  236 + }
  237 + String lines[] = sdpStr.split("\\r?\\n");
  238 + for (String line : lines) {
  239 + if (line.trim().startsWith("y=")) {
  240 + return line.substring(2);
  241 + }
  242 + }
  243 + return null;
  244 + }
193 } 245 }
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -18,6 +18,7 @@ import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; @@ -18,6 +18,7 @@ import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
18 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; 18 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
19 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; 19 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
20 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; 20 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
  21 +import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
21 import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils; 22 import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils;
22 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; 23 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
23 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; 24 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
@@ -297,17 +298,16 @@ public class PlayServiceImpl implements IPlayService { @@ -297,17 +298,16 @@ public class PlayServiceImpl implements IPlayService {
297 ResponseEvent responseEvent = (ResponseEvent) event.event; 298 ResponseEvent responseEvent = (ResponseEvent) event.event;
298 String contentString = new String(responseEvent.getResponse().getRawContent()); 299 String contentString = new String(responseEvent.getResponse().getRawContent());
299 // 获取ssrc 300 // 获取ssrc
300 - int ssrcIndex = contentString.indexOf("y="); 301 + String ssrcInResponse = SipUtils.getSsrcFromSdp(contentString);
  302 +
301 // 检查是否有y字段 303 // 检查是否有y字段
302 - if (ssrcIndex >= 0) {  
303 - //ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段 TODO 后续对不规范的非10位ssrc兼容  
304 - String ssrcInResponse = contentString.substring(ssrcIndex + 2, ssrcIndex + 12).trim(); 304 + if (ssrcInResponse != null) {
305 // 查询到ssrc不一致且开启了ssrc校验则需要针对处理 305 // 查询到ssrc不一致且开启了ssrc校验则需要针对处理
306 if (ssrcInfo.getSsrc().equals(ssrcInResponse)) { 306 if (ssrcInfo.getSsrc().equals(ssrcInResponse)) {
307 if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE")) { 307 if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE")) {
308 - String substring = contentString.substring(0, contentString.indexOf("y="));  
309 try { 308 try {
310 - SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring); 309 + Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString);
  310 + SessionDescription sdp = gb28181Sdp.getBaseSdb();
311 int port = -1; 311 int port = -1;
312 Vector mediaDescriptions = sdp.getMediaDescriptions(true); 312 Vector mediaDescriptions = sdp.getMediaDescriptions(true);
313 for (Object description : mediaDescriptions) { 313 for (Object description : mediaDescriptions) {
@@ -607,17 +607,16 @@ public class PlayServiceImpl implements IPlayService { @@ -607,17 +607,16 @@ public class PlayServiceImpl implements IPlayService {
607 ResponseEvent responseEvent = (ResponseEvent) eventResult.event; 607 ResponseEvent responseEvent = (ResponseEvent) eventResult.event;
608 String contentString = new String(responseEvent.getResponse().getRawContent()); 608 String contentString = new String(responseEvent.getResponse().getRawContent());
609 // 获取ssrc 609 // 获取ssrc
610 - int ssrcIndex = contentString.indexOf("y="); 610 + String ssrcInResponse = SipUtils.getSsrcFromSdp(contentString);
  611 +
611 // 检查是否有y字段 612 // 检查是否有y字段
612 - if (ssrcIndex >= 0) {  
613 - //ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段 TODO 后续对不规范的非10位ssrc兼容  
614 - String ssrcInResponse = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); 613 + if (ssrcInResponse != null) {
615 // 查询到ssrc不一致且开启了ssrc校验则需要针对处理 614 // 查询到ssrc不一致且开启了ssrc校验则需要针对处理
616 if (ssrcInfo.getSsrc().equals(ssrcInResponse)) { 615 if (ssrcInfo.getSsrc().equals(ssrcInResponse)) {
617 if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE")) { 616 if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE")) {
618 - String substring = contentString.substring(0, contentString.indexOf("y="));  
619 try { 617 try {
620 - SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring); 618 + Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString);
  619 + SessionDescription sdp = gb28181Sdp.getBaseSdb();
621 int port = -1; 620 int port = -1;
622 Vector mediaDescriptions = sdp.getMediaDescriptions(true); 621 Vector mediaDescriptions = sdp.getMediaDescriptions(true);
623 for (Object description : mediaDescriptions) { 622 for (Object description : mediaDescriptions) {
@@ -800,17 +799,15 @@ public class PlayServiceImpl implements IPlayService { @@ -800,17 +799,15 @@ public class PlayServiceImpl implements IPlayService {
800 ResponseEvent responseEvent = (ResponseEvent) eventResult.event; 799 ResponseEvent responseEvent = (ResponseEvent) eventResult.event;
801 String contentString = new String(responseEvent.getResponse().getRawContent()); 800 String contentString = new String(responseEvent.getResponse().getRawContent());
802 // 获取ssrc 801 // 获取ssrc
803 - int ssrcIndex = contentString.indexOf("y="); 802 + String ssrcInResponse = SipUtils.getSsrcFromSdp(contentString);
804 // 检查是否有y字段 803 // 检查是否有y字段
805 - if (ssrcIndex >= 0) {  
806 - //ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段 TODO 后续对不规范的非10位ssrc兼容  
807 - String ssrcInResponse = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); 804 + if (ssrcInResponse != null) {
808 // 查询到ssrc不一致且开启了ssrc校验则需要针对处理 805 // 查询到ssrc不一致且开启了ssrc校验则需要针对处理
809 if (ssrcInfo.getSsrc().equals(ssrcInResponse)) { 806 if (ssrcInfo.getSsrc().equals(ssrcInResponse)) {
810 if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE")) { 807 if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE")) {
811 - String substring = contentString.substring(0, contentString.indexOf("y="));  
812 try { 808 try {
813 - SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring); 809 + Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString);
  810 + SessionDescription sdp = gb28181Sdp.getBaseSdb();
814 int port = -1; 811 int port = -1;
815 Vector mediaDescriptions = sdp.getMediaDescriptions(true); 812 Vector mediaDescriptions = sdp.getMediaDescriptions(true);
816 for (Object description : mediaDescriptions) { 813 for (Object description : mediaDescriptions) {