Commit 446f729e559730b813291f072a6e33a012923018
1 parent
03f35986
优化sdp解析,兼容带有f=的设备
Showing
7 changed files
with
129 additions
and
66 deletions
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) { |