|
|
@@ -18,7 +18,6 @@ import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
|
|
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
|
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
|
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
|
|
|
-import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
|
|
|
import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils;
|
|
|
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
|
|
|
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
|
|
|
@@ -116,28 +115,43 @@ public class PlayServiceImpl implements IPlayService {
|
|
|
|
|
|
|
|
|
@Override
|
|
|
- public SSRCInfo play(MediaServerItem mediaServerItem, String deviceId, String channelId, ErrorCallback<Object> callback) {
|
|
|
+ public SSRCInfo play(MediaServerItem mediaServerItem, String deviceId, String channelId,boolean isSubStream, ErrorCallback<Object> callback) {
|
|
|
if (mediaServerItem == null) {
|
|
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到可用的zlm");
|
|
|
}
|
|
|
|
|
|
Device device = redisCatchStorage.getDevice(deviceId);
|
|
|
- InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
|
|
|
-
|
|
|
+ InviteInfo inviteInfo;
|
|
|
+ if(device.isSwitchPrimarySubStream()){
|
|
|
+ inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId,isSubStream);
|
|
|
+ }else {
|
|
|
+ inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
|
|
|
+ }
|
|
|
if (inviteInfo != null ) {
|
|
|
if (inviteInfo.getStreamInfo() == null) {
|
|
|
// 点播发起了但是尚未成功, 仅注册回调等待结果即可
|
|
|
- inviteStreamService.once(InviteSessionType.PLAY, deviceId, channelId, null, callback);
|
|
|
+ if(device.isSwitchPrimarySubStream()){
|
|
|
+ inviteStreamService.once(InviteSessionType.PLAY, deviceId, channelId,isSubStream, null, callback);
|
|
|
+ }else {
|
|
|
+ inviteStreamService.once(InviteSessionType.PLAY, deviceId, channelId, null, callback);
|
|
|
+ }
|
|
|
return inviteInfo.getSsrcInfo();
|
|
|
}else {
|
|
|
StreamInfo streamInfo = inviteInfo.getStreamInfo();
|
|
|
String streamId = streamInfo.getStream();
|
|
|
if (streamId == null) {
|
|
|
callback.run(InviteErrorCode.ERROR_FOR_CATCH_DATA.getCode(), "点播失败, redis缓存streamId等于null", null);
|
|
|
- inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
- InviteErrorCode.ERROR_FOR_CATCH_DATA.getCode(),
|
|
|
- "点播失败, redis缓存streamId等于null",
|
|
|
- null);
|
|
|
+ if(device.isSwitchPrimarySubStream()){
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
|
|
+ InviteErrorCode.ERROR_FOR_CATCH_DATA.getCode(),
|
|
|
+ "点播失败, redis缓存streamId等于null",
|
|
|
+ null);
|
|
|
+ }else {
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
+ InviteErrorCode.ERROR_FOR_CATCH_DATA.getCode(),
|
|
|
+ "点播失败, redis缓存streamId等于null",
|
|
|
+ null);
|
|
|
+ }
|
|
|
return inviteInfo.getSsrcInfo();
|
|
|
}
|
|
|
String mediaServerId = streamInfo.getMediaServerId();
|
|
|
@@ -146,41 +160,64 @@ public class PlayServiceImpl implements IPlayService {
|
|
|
Boolean ready = zlmrtpServerFactory.isStreamReady(mediaInfo, "rtp", streamId);
|
|
|
if (ready != null && ready) {
|
|
|
callback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), streamInfo);
|
|
|
- inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
- InviteErrorCode.SUCCESS.getCode(),
|
|
|
- InviteErrorCode.SUCCESS.getMsg(),
|
|
|
- streamInfo);
|
|
|
+ if(device.isSwitchPrimarySubStream()){
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
|
|
+ InviteErrorCode.SUCCESS.getCode(),
|
|
|
+ InviteErrorCode.SUCCESS.getMsg(),
|
|
|
+ streamInfo);
|
|
|
+ }else {
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
+ InviteErrorCode.SUCCESS.getCode(),
|
|
|
+ InviteErrorCode.SUCCESS.getMsg(),
|
|
|
+ streamInfo);
|
|
|
+ }
|
|
|
return inviteInfo.getSsrcInfo();
|
|
|
}else {
|
|
|
// 点播发起了但是尚未成功, 仅注册回调等待结果即可
|
|
|
- inviteStreamService.once(InviteSessionType.PLAY, deviceId, channelId, null, callback);
|
|
|
- storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
|
|
|
- inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
|
|
|
+ if(device.isSwitchPrimarySubStream()) {
|
|
|
+ inviteStreamService.once(InviteSessionType.PLAY, deviceId, channelId, null, callback);
|
|
|
+ storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
|
|
|
+ inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
|
|
|
+ }else {
|
|
|
+ inviteStreamService.once(InviteSessionType.PLAY, deviceId, channelId,isSubStream, null, callback);
|
|
|
+ inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId,isSubStream);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
String streamId = null;
|
|
|
if (mediaServerItem.isRtpEnable()) {
|
|
|
- streamId = String.format("%s_%s", device.getDeviceId(), channelId);
|
|
|
+ if(device.isSwitchPrimarySubStream()){
|
|
|
+ streamId = StreamInfo.getPlayStream(deviceId, channelId, isSubStream);
|
|
|
+ }else {
|
|
|
+ streamId = String.format("%s_%s", device.getDeviceId(), channelId);
|
|
|
+ }
|
|
|
}
|
|
|
SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, null, device.isSsrcCheck(), false, 0, false, device.getStreamModeForParam());
|
|
|
if (ssrcInfo == null) {
|
|
|
callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(), null);
|
|
|
- inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
- InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(),
|
|
|
- InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(),
|
|
|
- null);
|
|
|
+ if(device.isSwitchPrimarySubStream()){
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
|
|
+ InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(),
|
|
|
+ InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(),
|
|
|
+ null);
|
|
|
+ }else {
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
+ InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(),
|
|
|
+ InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(),
|
|
|
+ null);
|
|
|
+ }
|
|
|
return null;
|
|
|
}
|
|
|
// TODO 记录点播的状态
|
|
|
- play(mediaServerItem, ssrcInfo, device, channelId, callback);
|
|
|
+ play(mediaServerItem, ssrcInfo, device, channelId,isSubStream, callback);
|
|
|
return ssrcInfo;
|
|
|
}
|
|
|
|
|
|
|
|
|
@Override
|
|
|
- public void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
|
|
|
+ public void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,boolean isSubStream,
|
|
|
ErrorCallback<Object> callback) {
|
|
|
|
|
|
if (mediaServerItem == null || ssrcInfo == null) {
|
|
|
@@ -189,21 +226,11 @@ public class PlayServiceImpl implements IPlayService {
|
|
|
null);
|
|
|
return;
|
|
|
}
|
|
|
- logger.info("\r\n" +
|
|
|
- " [点播开始] \r\n" +
|
|
|
- "deviceId : {}, \r\n" +
|
|
|
- "channelId : {},\r\n" +
|
|
|
- "收流端口 : {}, \r\n" +
|
|
|
- "收流模式 : {}, \r\n" +
|
|
|
- "SSRC : {}, \r\n" +
|
|
|
- "SSRC校验 :{}",
|
|
|
- device.getDeviceId(),
|
|
|
- channelId,
|
|
|
- ssrcInfo.getPort(),
|
|
|
- device.getStreamMode(),
|
|
|
- ssrcInfo.getSsrc(),
|
|
|
- device.isSsrcCheck());
|
|
|
-
|
|
|
+ if( device.isSwitchPrimarySubStream() ){
|
|
|
+ logger.info("[点播开始] deviceId: {}, channelId: {},码流类型:{},收流端口: {}, 收流模式:{}, SSRC: {}, SSRC校验:{}", device.getDeviceId(), channelId,isSubStream ? "辅码流" : "主码流", ssrcInfo.getPort(), device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck());
|
|
|
+ }else {
|
|
|
+ logger.info("[点播开始] deviceId: {}, channelId: {},收流端口: {}, 收流模式:{}, SSRC: {}, SSRC校验:{}", device.getDeviceId(), channelId, ssrcInfo.getPort(), device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck());
|
|
|
+ }
|
|
|
//端口获取失败的ssrcInfo 没有必要发送点播指令
|
|
|
if (ssrcInfo.getPort() <= 0) {
|
|
|
logger.info("[点播端口分配异常],deviceId={},channelId={},ssrcInfo={}", device.getDeviceId(), channelId, ssrcInfo);
|
|
|
@@ -212,23 +239,50 @@ public class PlayServiceImpl implements IPlayService {
|
|
|
streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
|
|
|
|
|
|
callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), "点播端口分配异常", null);
|
|
|
- inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
- InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), "点播端口分配异常", null);
|
|
|
+ if(device.isSwitchPrimarySubStream()){
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
|
|
+ InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), "点播端口分配异常", null);
|
|
|
+ }else {
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
+ InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), "点播端口分配异常", null);
|
|
|
+ }
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 初始化redis中的invite消息状态
|
|
|
- InviteInfo inviteInfo = InviteInfo.getinviteInfo(device.getDeviceId(), channelId, ssrcInfo.getStream(), ssrcInfo,
|
|
|
- mediaServerItem.getSdpIp(), ssrcInfo.getPort(), device.getStreamMode(), InviteSessionType.PLAY,
|
|
|
- InviteSessionStatus.ready);
|
|
|
- inviteStreamService.updateInviteInfo(inviteInfo);
|
|
|
+ InviteInfo inviteInfo;
|
|
|
+
|
|
|
+ if(device.isSwitchPrimarySubStream()){
|
|
|
+ // 初始化redis中的invite消息状态
|
|
|
+ inviteInfo = InviteInfo.getInviteInfo(device.getDeviceId(), channelId,isSubStream, ssrcInfo.getStream(), ssrcInfo,
|
|
|
+ mediaServerItem.getSdpIp(), ssrcInfo.getPort(), device.getStreamMode(), InviteSessionType.PLAY,
|
|
|
+ InviteSessionStatus.ready);
|
|
|
+ inviteStreamService.updateInviteInfoSub(inviteInfo);
|
|
|
+ }else {
|
|
|
+ // 初始化redis中的invite消息状态
|
|
|
+ inviteInfo = InviteInfo.getinviteInfo(device.getDeviceId(), channelId, ssrcInfo.getStream(), ssrcInfo,
|
|
|
+ mediaServerItem.getSdpIp(), ssrcInfo.getPort(), device.getStreamMode(), InviteSessionType.PLAY,
|
|
|
+ InviteSessionStatus.ready);
|
|
|
+ inviteStreamService.updateInviteInfo(inviteInfo);
|
|
|
+ }
|
|
|
// 超时处理
|
|
|
String timeOutTaskKey = UUID.randomUUID().toString();
|
|
|
dynamicTask.startDelay(timeOutTaskKey, () -> {
|
|
|
// 执行超时任务时查询是否已经成功,成功了则不执行超时任务,防止超时任务取消失败的情况
|
|
|
- InviteInfo inviteInfoForTimeOut = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
|
|
|
+ InviteInfo inviteInfoForTimeOut;
|
|
|
+ if(device.isSwitchPrimarySubStream()){
|
|
|
+ // 初始化redis中的invite消息状态
|
|
|
+ inviteInfoForTimeOut = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream);
|
|
|
+ }else {
|
|
|
+ // 初始化redis中的invite消息状态
|
|
|
+ inviteInfoForTimeOut = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
|
|
|
+ }
|
|
|
if (inviteInfoForTimeOut == null || inviteInfoForTimeOut.getStreamInfo() == null) {
|
|
|
- logger.info("[点播超时] 收流超时 deviceId: {}, channelId: {},端口:{}, SSRC: {}", device.getDeviceId(), channelId, ssrcInfo.getPort(), ssrcInfo.getSsrc());
|
|
|
+ if( device.isSwitchPrimarySubStream()){
|
|
|
+ logger.info("[点播超时] 收流超时 deviceId: {}, channelId: {},码流类型:{},端口:{}, SSRC: {}", device.getDeviceId(), channelId,isSubStream ? "辅码流" : "主码流", ssrcInfo.getPort(), ssrcInfo.getSsrc());
|
|
|
+ }else {
|
|
|
+ logger.info("[点播超时] 收流超时 deviceId: {}, channelId: {},端口:{}, SSRC: {}", device.getDeviceId(), channelId, ssrcInfo.getPort(), ssrcInfo.getSsrc());
|
|
|
+ }
|
|
|
// 点播超时回复BYE 同时释放ssrc以及此次点播的资源
|
|
|
// InviteInfo inviteInfoForTimeout = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.play, device.getDeviceId(), channelId);
|
|
|
// if (inviteInfoForTimeout == null) {
|
|
|
@@ -240,10 +294,16 @@ public class PlayServiceImpl implements IPlayService {
|
|
|
// // TODO 发送cancel
|
|
|
// }
|
|
|
callback.run(InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode(), InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getMsg(), null);
|
|
|
- inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
- InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode(), InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getMsg(), null);
|
|
|
+ if( device.isSwitchPrimarySubStream()){
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
|
|
+ InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode(), InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getMsg(), null);
|
|
|
+ inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream);
|
|
|
|
|
|
- inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
|
|
|
+ }else {
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
+ InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode(), InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getMsg(), null);
|
|
|
+ inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
|
|
|
+ }
|
|
|
try {
|
|
|
cmder.streamByeCmd(device, channelId, ssrcInfo.getStream(), null);
|
|
|
} catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) {
|
|
|
@@ -261,25 +321,42 @@ public class PlayServiceImpl implements IPlayService {
|
|
|
}, userSetting.getPlayTimeout());
|
|
|
|
|
|
try {
|
|
|
- cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> {
|
|
|
+ cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId,isSubStream, (MediaServerItem mediaServerItemInuse, JSONObject response) -> {
|
|
|
logger.info("收到订阅消息: " + response.toJSONString());
|
|
|
dynamicTask.stop(timeOutTaskKey);
|
|
|
// hook响应
|
|
|
- StreamInfo streamInfo = onPublishHandlerForPlay(mediaServerItemInuse, response, device.getDeviceId(), channelId);
|
|
|
+ StreamInfo streamInfo = onPublishHandlerForPlay(mediaServerItemInuse, response, device.getDeviceId(), channelId,isSubStream);
|
|
|
if (streamInfo == null){
|
|
|
callback.run(InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(),
|
|
|
InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null);
|
|
|
- inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
- InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(),
|
|
|
- InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null);
|
|
|
+ if( device.isSwitchPrimarySubStream()){
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
|
|
+ InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(),
|
|
|
+ InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null);
|
|
|
+ }else {
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
+ InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(),
|
|
|
+ InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null);
|
|
|
+ }
|
|
|
return;
|
|
|
}
|
|
|
callback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), streamInfo);
|
|
|
- inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
- InviteErrorCode.SUCCESS.getCode(),
|
|
|
- InviteErrorCode.SUCCESS.getMsg(),
|
|
|
- streamInfo);
|
|
|
- logger.info("[点播成功] deviceId: {}, channelId: {}", device.getDeviceId(), channelId);
|
|
|
+ if( device.isSwitchPrimarySubStream()){
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
|
|
+ InviteErrorCode.SUCCESS.getCode(),
|
|
|
+ InviteErrorCode.SUCCESS.getMsg(),
|
|
|
+ streamInfo);
|
|
|
+ }else {
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
+ InviteErrorCode.SUCCESS.getCode(),
|
|
|
+ InviteErrorCode.SUCCESS.getMsg(),
|
|
|
+ streamInfo);
|
|
|
+ }
|
|
|
+ if( device.isSwitchPrimarySubStream() ){
|
|
|
+ logger.info("[点播成功] deviceId: {}, channelId: {},码流类型:{}", device.getDeviceId(), channelId,isSubStream ? "辅码流" : "主码流");
|
|
|
+ }else {
|
|
|
+ logger.info("[点播成功] deviceId: {}, channelId: {}", device.getDeviceId(), channelId);
|
|
|
+ }
|
|
|
String streamUrl;
|
|
|
if (mediaServerItemInuse.getRtspPort() != 0) {
|
|
|
streamUrl = String.format("rtsp://127.0.0.1:%s/%s/%s", mediaServerItemInuse.getRtspPort(), "rtp", ssrcInfo.getStream());
|
|
|
@@ -298,16 +375,17 @@ public class PlayServiceImpl implements IPlayService {
|
|
|
ResponseEvent responseEvent = (ResponseEvent) event.event;
|
|
|
String contentString = new String(responseEvent.getResponse().getRawContent());
|
|
|
// 获取ssrc
|
|
|
- String ssrcInResponse = SipUtils.getSsrcFromSdp(contentString);
|
|
|
-
|
|
|
+ int ssrcIndex = contentString.indexOf("y=");
|
|
|
// 检查是否有y字段
|
|
|
- if (ssrcInResponse != null) {
|
|
|
+ if (ssrcIndex >= 0) {
|
|
|
+ //ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段 TODO 后续对不规范的非10位ssrc兼容
|
|
|
+ String ssrcInResponse = contentString.substring(ssrcIndex + 2, ssrcIndex + 12).trim();
|
|
|
// 查询到ssrc不一致且开启了ssrc校验则需要针对处理
|
|
|
if (ssrcInfo.getSsrc().equals(ssrcInResponse)) {
|
|
|
if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE")) {
|
|
|
+ String substring = contentString.substring(0, contentString.indexOf("y="));
|
|
|
try {
|
|
|
- Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString);
|
|
|
- SessionDescription sdp = gb28181Sdp.getBaseSdb();
|
|
|
+ SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring);
|
|
|
int port = -1;
|
|
|
Vector mediaDescriptions = sdp.getMediaDescriptions(true);
|
|
|
for (Object description : mediaDescriptions) {
|
|
|
@@ -334,21 +412,24 @@ public class PlayServiceImpl implements IPlayService {
|
|
|
|
|
|
callback.run(InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
|
|
|
InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
|
|
|
- inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
- InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
|
|
|
- InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
|
|
|
+ if(device.isSwitchPrimarySubStream()){
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
|
|
+ InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
|
|
|
+ InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
|
|
|
+ }else {
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
+ InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
|
|
|
+ InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
return;
|
|
|
}
|
|
|
logger.info("[点播消息] 收到invite 200, 发现下级自定义了ssrc: {}", ssrcInResponse);
|
|
|
-
|
|
|
if (!mediaServerItem.isRtpEnable() || device.isSsrcCheck()) {
|
|
|
logger.info("[点播消息] SSRC修正 {}->{}", ssrcInfo.getSsrc(), ssrcInResponse);
|
|
|
-
|
|
|
// 释放ssrc
|
|
|
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
|
|
|
-
|
|
|
// 单端口模式streamId也有变化,重新设置监听即可
|
|
|
if (!mediaServerItem.isRtpEnable()) {
|
|
|
// 添加订阅
|
|
|
@@ -361,21 +442,34 @@ public class PlayServiceImpl implements IPlayService {
|
|
|
logger.info("[ZLM HOOK] ssrc修正后收到订阅消息: " + response.toJSONString());
|
|
|
dynamicTask.stop(timeOutTaskKey);
|
|
|
// hook响应
|
|
|
- StreamInfo streamInfo = onPublishHandlerForPlay(mediaServerItemInUse, response, device.getDeviceId(), channelId);
|
|
|
+ StreamInfo streamInfo = onPublishHandlerForPlay(mediaServerItemInUse, response, device.getDeviceId(), channelId,isSubStream);
|
|
|
if (streamInfo == null){
|
|
|
callback.run(InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(),
|
|
|
InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null);
|
|
|
- inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
- InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(),
|
|
|
- InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null);
|
|
|
+ if( device.isSwitchPrimarySubStream()){
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
|
|
+ InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(),
|
|
|
+ InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null);
|
|
|
+ }else {
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
+ InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(),
|
|
|
+ InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null);
|
|
|
+ }
|
|
|
return;
|
|
|
}
|
|
|
callback.run(InviteErrorCode.SUCCESS.getCode(),
|
|
|
InviteErrorCode.SUCCESS.getMsg(), streamInfo);
|
|
|
- inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
- InviteErrorCode.SUCCESS.getCode(),
|
|
|
- InviteErrorCode.SUCCESS.getMsg(),
|
|
|
- streamInfo);
|
|
|
+ if( device.isSwitchPrimarySubStream()){
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
|
|
+ InviteErrorCode.SUCCESS.getCode(),
|
|
|
+ InviteErrorCode.SUCCESS.getMsg(),
|
|
|
+ streamInfo);
|
|
|
+ }else {
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
+ InviteErrorCode.SUCCESS.getCode(),
|
|
|
+ InviteErrorCode.SUCCESS.getMsg(),
|
|
|
+ streamInfo);
|
|
|
+ }
|
|
|
});
|
|
|
return;
|
|
|
}
|
|
|
@@ -391,14 +485,22 @@ public class PlayServiceImpl implements IPlayService {
|
|
|
}
|
|
|
|
|
|
dynamicTask.stop(timeOutTaskKey);
|
|
|
+ // 释放ssrc
|
|
|
+ mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
|
|
|
|
|
|
streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
|
|
|
|
|
|
callback.run(InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(),
|
|
|
"下级自定义了ssrc,重新设置收流信息失败", null);
|
|
|
- inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
- InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(),
|
|
|
- "下级自定义了ssrc,重新设置收流信息失败", null);
|
|
|
+ if( device.isSwitchPrimarySubStream()){
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
|
|
+ InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(),
|
|
|
+ "下级自定义了ssrc,重新设置收流信息失败", null);
|
|
|
+ }else {
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
+ InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(),
|
|
|
+ "下级自定义了ssrc,重新设置收流信息失败", null);
|
|
|
+ }
|
|
|
|
|
|
}else {
|
|
|
ssrcInfo.setSsrc(ssrcInResponse);
|
|
|
@@ -409,7 +511,11 @@ public class PlayServiceImpl implements IPlayService {
|
|
|
logger.info("[点播消息] 收到invite 200, 下级自定义了ssrc, 但是当前模式无需修正");
|
|
|
}
|
|
|
}
|
|
|
- inviteStreamService.updateInviteInfo(inviteInfo);
|
|
|
+ if(device.isSwitchPrimarySubStream()){
|
|
|
+ inviteStreamService.updateInviteInfoSub(inviteInfo);
|
|
|
+ }else {
|
|
|
+ inviteStreamService.updateInviteInfo(inviteInfo);
|
|
|
+ }
|
|
|
}, (event) -> {
|
|
|
dynamicTask.stop(timeOutTaskKey);
|
|
|
mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
|
|
|
@@ -420,11 +526,19 @@ public class PlayServiceImpl implements IPlayService {
|
|
|
|
|
|
callback.run(InviteErrorCode.ERROR_FOR_SIGNALLING_ERROR.getCode(),
|
|
|
String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg), null);
|
|
|
- inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
- InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(),
|
|
|
- String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg), null);
|
|
|
+ if( device.isSwitchPrimarySubStream()){
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
|
|
+ InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(),
|
|
|
+ String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg), null);
|
|
|
|
|
|
- inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
|
|
|
+ inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream);
|
|
|
+ }else {
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
+ InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(),
|
|
|
+ String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg), null);
|
|
|
+
|
|
|
+ inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
|
|
|
+ }
|
|
|
});
|
|
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
|
|
|
|
|
@@ -438,27 +552,51 @@ public class PlayServiceImpl implements IPlayService {
|
|
|
|
|
|
callback.run(InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getCode(),
|
|
|
InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getMsg(), null);
|
|
|
- inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
- InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getCode(),
|
|
|
- InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getMsg(), null);
|
|
|
+ if( device.isSwitchPrimarySubStream()){
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
|
|
+ InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getCode(),
|
|
|
+ InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getMsg(), null);
|
|
|
|
|
|
- inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
|
|
|
+ inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream);
|
|
|
+ }else {
|
|
|
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
|
|
+ InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getCode(),
|
|
|
+ InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getMsg(), null);
|
|
|
+
|
|
|
+ inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private StreamInfo onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId) {
|
|
|
- StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId);
|
|
|
+ private StreamInfo onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId,boolean isSubStream) {
|
|
|
+ StreamInfo streamInfo = null;
|
|
|
+ Device device = redisCatchStorage.getDevice(deviceId);
|
|
|
+ if( device.isSwitchPrimarySubStream() ){
|
|
|
+ streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId,isSubStream);
|
|
|
+ }else {
|
|
|
+ streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId);
|
|
|
+ }
|
|
|
if (streamInfo != null) {
|
|
|
- DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
|
|
|
- if (deviceChannel != null) {
|
|
|
- deviceChannel.setStreamId(streamInfo.getStream());
|
|
|
- storager.startPlay(deviceId, channelId, streamInfo.getStream());
|
|
|
+ InviteInfo inviteInfo;
|
|
|
+ if(device.isSwitchPrimarySubStream()){
|
|
|
+ inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId,isSubStream);
|
|
|
+ }else {
|
|
|
+ DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
|
|
|
+ if (deviceChannel != null) {
|
|
|
+ deviceChannel.setStreamId(streamInfo.getStream());
|
|
|
+ storager.startPlay(deviceId, channelId, streamInfo.getStream());
|
|
|
+ }
|
|
|
+ inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
|
|
|
}
|
|
|
- InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
|
|
|
if (inviteInfo != null) {
|
|
|
inviteInfo.setStatus(InviteSessionStatus.ok);
|
|
|
inviteInfo.setStreamInfo(streamInfo);
|
|
|
- inviteStreamService.updateInviteInfo(inviteInfo);
|
|
|
+ if(device.isSwitchPrimarySubStream()){
|
|
|
+ inviteStreamService.updateInviteInfoSub(inviteInfo);
|
|
|
+ }else {
|
|
|
+ inviteStreamService.updateInviteInfo(inviteInfo);
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
}
|
|
|
return streamInfo;
|
|
|
@@ -607,16 +745,17 @@ public class PlayServiceImpl implements IPlayService {
|
|
|
ResponseEvent responseEvent = (ResponseEvent) eventResult.event;
|
|
|
String contentString = new String(responseEvent.getResponse().getRawContent());
|
|
|
// 获取ssrc
|
|
|
- String ssrcInResponse = SipUtils.getSsrcFromSdp(contentString);
|
|
|
-
|
|
|
+ int ssrcIndex = contentString.indexOf("y=");
|
|
|
// 检查是否有y字段
|
|
|
- if (ssrcInResponse != null) {
|
|
|
+ if (ssrcIndex >= 0) {
|
|
|
+ //ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段 TODO 后续对不规范的非10位ssrc兼容
|
|
|
+ String ssrcInResponse = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
|
|
|
// 查询到ssrc不一致且开启了ssrc校验则需要针对处理
|
|
|
if (ssrcInfo.getSsrc().equals(ssrcInResponse)) {
|
|
|
if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE")) {
|
|
|
+ String substring = contentString.substring(0, contentString.indexOf("y="));
|
|
|
try {
|
|
|
- Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString);
|
|
|
- SessionDescription sdp = gb28181Sdp.getBaseSdb();
|
|
|
+ SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring);
|
|
|
int port = -1;
|
|
|
Vector mediaDescriptions = sdp.getMediaDescriptions(true);
|
|
|
for (Object description : mediaDescriptions) {
|
|
|
@@ -684,6 +823,8 @@ public class PlayServiceImpl implements IPlayService {
|
|
|
}
|
|
|
|
|
|
dynamicTask.stop(playBackTimeOutTaskKey);
|
|
|
+ // 释放ssrc
|
|
|
+ mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
|
|
|
|
|
|
streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
|
|
|
|
|
|
@@ -799,15 +940,17 @@ public class PlayServiceImpl implements IPlayService {
|
|
|
ResponseEvent responseEvent = (ResponseEvent) eventResult.event;
|
|
|
String contentString = new String(responseEvent.getResponse().getRawContent());
|
|
|
// 获取ssrc
|
|
|
- String ssrcInResponse = SipUtils.getSsrcFromSdp(contentString);
|
|
|
+ int ssrcIndex = contentString.indexOf("y=");
|
|
|
// 检查是否有y字段
|
|
|
- if (ssrcInResponse != null) {
|
|
|
+ if (ssrcIndex >= 0) {
|
|
|
+ //ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段 TODO 后续对不规范的非10位ssrc兼容
|
|
|
+ String ssrcInResponse = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
|
|
|
// 查询到ssrc不一致且开启了ssrc校验则需要针对处理
|
|
|
if (ssrcInfo.getSsrc().equals(ssrcInResponse)) {
|
|
|
if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE")) {
|
|
|
+ String substring = contentString.substring(0, contentString.indexOf("y="));
|
|
|
try {
|
|
|
- Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString);
|
|
|
- SessionDescription sdp = gb28181Sdp.getBaseSdb();
|
|
|
+ SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring);
|
|
|
int port = -1;
|
|
|
Vector mediaDescriptions = sdp.getMediaDescriptions(true);
|
|
|
for (Object description : mediaDescriptions) {
|
|
|
@@ -872,6 +1015,8 @@ public class PlayServiceImpl implements IPlayService {
|
|
|
}
|
|
|
|
|
|
dynamicTask.stop(downLoadTimeOutTaskKey);
|
|
|
+ // 释放ssrc
|
|
|
+ mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
|
|
|
|
|
|
streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
|
|
|
|
|
|
@@ -972,6 +1117,7 @@ public class PlayServiceImpl implements IPlayService {
|
|
|
return streamInfo;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
@Override
|
|
|
public void zlmServerOffline(String mediaServerId) {
|
|
|
// 处理正在向上推流的上级平台
|
|
|
@@ -1108,14 +1254,18 @@ public class PlayServiceImpl implements IPlayService {
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public void getSnap(String deviceId, String channelId, String fileName, ErrorCallback errorCallback) {
|
|
|
+ public void getSnap(String deviceId, String channelId, String fileName,boolean isSubStream, ErrorCallback errorCallback) {
|
|
|
Device device = deviceService.getDevice(deviceId);
|
|
|
if (device == null) {
|
|
|
errorCallback.run(InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getCode(), InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getMsg(), null);
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
- InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
|
|
|
+ InviteInfo inviteInfo;
|
|
|
+ if(device.isSwitchPrimarySubStream()){
|
|
|
+ inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId,isSubStream);
|
|
|
+ }else {
|
|
|
+ inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
|
|
|
+ }
|
|
|
if (inviteInfo != null) {
|
|
|
if (inviteInfo.getStreamInfo() != null) {
|
|
|
// 已存在线直接截图
|
|
|
@@ -1130,10 +1280,9 @@ public class PlayServiceImpl implements IPlayService {
|
|
|
// 请求截图
|
|
|
logger.info("[请求截图]: " + fileName);
|
|
|
zlmresTfulUtils.getSnap(mediaServerItemInuse, streamUrl, 15, 1, path, fileName);
|
|
|
- String filePath = path + File.separator + fileName;
|
|
|
File snapFile = new File(path + File.separator + fileName);
|
|
|
if (snapFile.exists()) {
|
|
|
- errorCallback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), filePath);
|
|
|
+ errorCallback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), snapFile.getAbsoluteFile());
|
|
|
}else {
|
|
|
errorCallback.run(InviteErrorCode.FAIL.getCode(), InviteErrorCode.FAIL.getMsg(), null);
|
|
|
}
|
|
|
@@ -1142,11 +1291,11 @@ public class PlayServiceImpl implements IPlayService {
|
|
|
}
|
|
|
|
|
|
MediaServerItem newMediaServerItem = getNewMediaServerItem(device);
|
|
|
- play(newMediaServerItem, deviceId, channelId, (code, msg, data)->{
|
|
|
+ play(newMediaServerItem, deviceId, channelId,isSubStream, (code, msg, data)->{
|
|
|
if (code == InviteErrorCode.SUCCESS.getCode()) {
|
|
|
InviteInfo inviteInfoForPlay = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
|
|
|
if (inviteInfoForPlay != null && inviteInfoForPlay.getStreamInfo() != null) {
|
|
|
- getSnap(deviceId, channelId, fileName, errorCallback);
|
|
|
+ getSnap(deviceId, channelId, fileName,isSubStream, errorCallback);
|
|
|
}else {
|
|
|
errorCallback.run(InviteErrorCode.FAIL.getCode(), InviteErrorCode.FAIL.getMsg(), null);
|
|
|
}
|
|
|
@@ -1156,4 +1305,17 @@ public class PlayServiceImpl implements IPlayService {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ /*======================设备主子码流逻辑START=========================*/
|
|
|
+ public StreamInfo onPublishHandler(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId,boolean isSubStream) {
|
|
|
+ String streamId = resonse.getString("stream");
|
|
|
+ JSONArray tracks = resonse.getJSONArray("tracks");
|
|
|
+ StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem, "rtp", streamId, tracks, null);
|
|
|
+ streamInfo.setDeviceID(deviceId);
|
|
|
+ streamInfo.setChannelId(channelId);
|
|
|
+ streamInfo.setSubStream(isSubStream);
|
|
|
+ return streamInfo;
|
|
|
+ }
|
|
|
+ /*======================设备主子码流逻辑END=========================*/
|
|
|
+
|
|
|
}
|