| | |
| | | package com.genersoft.iot.vmp.service.impl; |
| | | |
| | | import com.alibaba.fastjson2.JSONArray; |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import com.genersoft.iot.vmp.common.InviteInfo; |
| | | import com.genersoft.iot.vmp.common.InviteSessionStatus; |
| | |
| | | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; |
| | | import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils; |
| | | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
| | | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
| | | import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; |
| | | import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; |
| | | import com.genersoft.iot.vmp.service.*; |
| | | import com.genersoft.iot.vmp.service.bean.ErrorCallback; |
| | | import com.genersoft.iot.vmp.service.bean.InviteErrorCode; |
| | |
| | | private ZLMRESTfulUtils zlmresTfulUtils; |
| | | |
| | | @Autowired |
| | | private ZLMRTPServerFactory zlmrtpServerFactory; |
| | | private ZLMServerFactory zlmServerFactory; |
| | | |
| | | @Autowired |
| | | private AssistRESTfulUtils assistRESTfulUtils; |
| | |
| | | |
| | | |
| | | @Override |
| | | public SSRCInfo play(MediaServerItem mediaServerItem, String deviceId, String channelId,boolean isSubStream, ErrorCallback<Object> callback) { |
| | | public SSRCInfo play(MediaServerItem mediaServerItem, String deviceId, String channelId, ErrorCallback<Object> callback) { |
| | | if (mediaServerItem == null) { |
| | | throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到可用的zlm"); |
| | | } |
| | | |
| | | Device device = redisCatchStorage.getDevice(deviceId); |
| | | InviteInfo inviteInfo; |
| | | if(device.isSwitchPrimarySubStream()){ |
| | | inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId,isSubStream); |
| | | }else { |
| | | inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId); |
| | | } |
| | | InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId); |
| | | if (inviteInfo != null ) { |
| | | if (inviteInfo.getStreamInfo() == null) { |
| | | // 点播发起了但是尚未成功, 仅注册回调等待结果即可 |
| | | if(device.isSwitchPrimarySubStream()){ |
| | | inviteStreamService.once(InviteSessionType.PLAY, deviceId, channelId,isSubStream, null, callback); |
| | | }else { |
| | | inviteStreamService.once(InviteSessionType.PLAY, deviceId, channelId, null, callback); |
| | | } |
| | | 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); |
| | | 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); |
| | | } |
| | | 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(); |
| | | MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); |
| | | |
| | | Boolean ready = zlmrtpServerFactory.isStreamReady(mediaInfo, "rtp", streamId); |
| | | Boolean ready = zlmServerFactory.isStreamReady(mediaInfo, "rtp", streamId); |
| | | if (ready != null && ready) { |
| | | callback.run(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); |
| | | } |
| | | inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null, |
| | | InviteErrorCode.SUCCESS.getCode(), |
| | | InviteErrorCode.SUCCESS.getMsg(), |
| | | streamInfo); |
| | | return inviteInfo.getSsrcInfo(); |
| | | }else { |
| | | // 点播发起了但是尚未成功, 仅注册回调等待结果即可 |
| | | 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); |
| | | } |
| | | inviteStreamService.once(InviteSessionType.PLAY, deviceId, channelId, null, callback); |
| | | storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); |
| | | inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId); |
| | | } |
| | | } |
| | | } |
| | | |
| | | String streamId = null; |
| | | if (mediaServerItem.isRtpEnable()) { |
| | | if(device.isSwitchPrimarySubStream()){ |
| | | streamId = StreamInfo.getPlayStream(deviceId, channelId, isSubStream); |
| | | }else { |
| | | streamId = String.format("%s_%s", device.getDeviceId(), channelId); |
| | | } |
| | | 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); |
| | | 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); |
| | | } |
| | | 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,isSubStream, callback); |
| | | play(mediaServerItem, ssrcInfo, device, channelId, callback); |
| | | return ssrcInfo; |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,boolean isSubStream, |
| | | public void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, |
| | | ErrorCallback<Object> callback) { |
| | | |
| | | if (mediaServerItem == null || ssrcInfo == null) { |
| | |
| | | null); |
| | | return; |
| | | } |
| | | 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()); |
| | | } |
| | | logger.info("[点播开始] deviceId: {}, channelId: {},码流类型:{}, 收流端口: {}, 收流模式:{}, SSRC: {}, SSRC校验:{}", |
| | | device.getDeviceId(), channelId, device.isSwitchPrimarySubStream() ? "辅码流" : "主码流", ssrcInfo.getPort(), |
| | | device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck()); |
| | | //端口获取失败的ssrcInfo 没有必要发送点播指令 |
| | | if (ssrcInfo.getPort() <= 0) { |
| | | logger.info("[点播端口分配异常],deviceId={},channelId={},ssrcInfo={}", device.getDeviceId(), channelId, ssrcInfo); |
| | |
| | | streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); |
| | | |
| | | callback.run(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); |
| | | } |
| | | inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null, |
| | | InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), "点播端口分配异常", null); |
| | | return; |
| | | } |
| | | |
| | | // 初始化redis中的invite消息状态 |
| | | 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); |
| | | } |
| | | InviteInfo inviteInfo = InviteInfo.getInviteInfo(device.getDeviceId(), channelId, ssrcInfo.getStream(), ssrcInfo, |
| | | mediaServerItem.getSdpIp(), ssrcInfo.getPort(), device.getStreamMode(), InviteSessionType.PLAY, |
| | | InviteSessionStatus.ready); |
| | | inviteInfo.setSubStream(device.isSwitchPrimarySubStream()); |
| | | inviteStreamService.updateInviteInfo(inviteInfo); |
| | | // 超时处理 |
| | | String timeOutTaskKey = UUID.randomUUID().toString(); |
| | | dynamicTask.startDelay(timeOutTaskKey, () -> { |
| | | // 执行超时任务时查询是否已经成功,成功了则不执行超时任务,防止超时任务取消失败的情况 |
| | | 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); |
| | | } |
| | | InviteInfo inviteInfoForTimeOut = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId); |
| | | if (inviteInfoForTimeOut == null || inviteInfoForTimeOut.getStreamInfo() == null) { |
| | | 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()); |
| | | } |
| | | logger.info("[点播超时] 收流超时 deviceId: {}, channelId: {},码流类型:{},端口:{}, SSRC: {}", |
| | | device.getDeviceId(), channelId, device.isSwitchPrimarySubStream() ? "辅码流" : "主码流", |
| | | ssrcInfo.getPort(), ssrcInfo.getSsrc()); |
| | | |
| | | // 点播超时回复BYE 同时释放ssrc以及此次点播的资源 |
| | | // InviteInfo inviteInfoForTimeout = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.play, device.getDeviceId(), channelId); |
| | | // if (inviteInfoForTimeout == null) { |
| | |
| | | // // TODO 发送cancel |
| | | // } |
| | | callback.run(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.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); |
| | | |
| | | }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) { |
| | |
| | | }, userSetting.getPlayTimeout()); |
| | | |
| | | try { |
| | | cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId,isSubStream, (MediaServerItem mediaServerItemInuse, JSONObject response) -> { |
| | | logger.info("收到订阅消息: " + response.toJSONString()); |
| | | cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (mediaServerItemInuse, hookParam ) -> { |
| | | logger.info("收到订阅消息: " + hookParam); |
| | | dynamicTask.stop(timeOutTaskKey); |
| | | // hook响应 |
| | | StreamInfo streamInfo = onPublishHandlerForPlay(mediaServerItemInuse, response, device.getDeviceId(), channelId,isSubStream); |
| | | StreamInfo streamInfo = onPublishHandlerForPlay(mediaServerItemInuse, hookParam, device.getDeviceId(), channelId); |
| | | if (streamInfo == null){ |
| | | callback.run(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); |
| | | } |
| | | 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); |
| | | 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()); |
| | | }else { |
| | | streamUrl = String.format("http://127.0.0.1:%s/%s/%s.live.mp4", mediaServerItemInuse.getHttpPort(), "rtp", ssrcInfo.getStream()); |
| | | } |
| | | String path = "snap"; |
| | | String fileName = device.getDeviceId() + "_" + channelId + ".jpg"; |
| | | // 请求截图 |
| | | logger.info("[请求截图]: " + fileName); |
| | | zlmresTfulUtils.getSnap(mediaServerItemInuse, streamUrl, 15, 1, path, fileName); |
| | | |
| | | inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null, |
| | | InviteErrorCode.SUCCESS.getCode(), |
| | | InviteErrorCode.SUCCESS.getMsg(), |
| | | streamInfo); |
| | | logger.info("[点播成功] deviceId: {}, channelId:{}, 码流类型:{}", device.getDeviceId(), |
| | | device.isSwitchPrimarySubStream() ? "辅码流" : "主码流"); |
| | | snapOnPlay(mediaServerItemInuse, device.getDeviceId(), channelId, ssrcInfo.getStream()); |
| | | }, (event) -> { |
| | | inviteInfo.setStatus(InviteSessionStatus.ok); |
| | | |
| | |
| | | |
| | | callback.run(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); |
| | | } |
| | | inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null, |
| | | InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(), |
| | | InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null); |
| | | } |
| | | } |
| | | return; |
| | |
| | | subscribe.removeSubscribe(hookSubscribe); |
| | | String stream = String.format("%08x", Integer.parseInt(ssrcInResponse)).toUpperCase(); |
| | | hookSubscribe.getContent().put("stream", stream); |
| | | inviteInfo.setStream(stream); |
| | | subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject response) -> { |
| | | logger.info("[ZLM HOOK] ssrc修正后收到订阅消息: " + response.toJSONString()); |
| | | inviteStreamService.updateInviteInfoForStream(inviteInfo, stream); |
| | | subscribe.addSubscribe(hookSubscribe, (mediaServerItemInUse, hookParam) -> { |
| | | logger.info("[ZLM HOOK] ssrc修正后收到订阅消息: " + hookParam); |
| | | dynamicTask.stop(timeOutTaskKey); |
| | | // hook响应 |
| | | StreamInfo streamInfo = onPublishHandlerForPlay(mediaServerItemInUse, response, device.getDeviceId(), channelId,isSubStream); |
| | | StreamInfo streamInfo = onPublishHandlerForPlay(mediaServerItemInUse, hookParam, device.getDeviceId(), channelId); |
| | | if (streamInfo == null){ |
| | | callback.run(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); |
| | | } |
| | | 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); |
| | | 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); |
| | | } |
| | | inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null, |
| | | InviteErrorCode.SUCCESS.getCode(), |
| | | InviteErrorCode.SUCCESS.getMsg(), |
| | | streamInfo); |
| | | snapOnPlay(mediaServerItemInUse, device.getDeviceId(), channelId, stream); |
| | | }); |
| | | return; |
| | | } |
| | |
| | | |
| | | callback.run(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); |
| | | } |
| | | inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null, |
| | | InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(), |
| | | "下级自定义了ssrc,重新设置收流信息失败", null); |
| | | |
| | | }else { |
| | | if (ssrcInfo.getStream()!= null && !ssrcInfo.getStream().equals(inviteInfo.getStream())) { |
| | | inviteStreamService.removeInviteInfo(inviteInfo); |
| | | } |
| | | ssrcInfo.setSsrc(ssrcInResponse); |
| | | inviteInfo.setSsrcInfo(ssrcInfo); |
| | | inviteInfo.setStream(ssrcInfo.getStream()); |
| | |
| | | logger.info("[点播消息] 收到invite 200, 下级自定义了ssrc, 但是当前模式无需修正"); |
| | | } |
| | | } |
| | | if(device.isSwitchPrimarySubStream()){ |
| | | inviteStreamService.updateInviteInfoSub(inviteInfo); |
| | | }else { |
| | | inviteStreamService.updateInviteInfo(inviteInfo); |
| | | } |
| | | inviteStreamService.updateInviteInfo(inviteInfo); |
| | | }, (event) -> { |
| | | dynamicTask.stop(timeOutTaskKey); |
| | | mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream()); |
| | |
| | | |
| | | callback.run(InviteErrorCode.ERROR_FOR_SIGNALLING_ERROR.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.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,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); |
| | | } |
| | | inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId); |
| | | }); |
| | | } catch (InvalidArgumentException | SipException | ParseException e) { |
| | | |
| | |
| | | |
| | | callback.run(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.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,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); |
| | | } |
| | | inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId); |
| | | } |
| | | } |
| | | |
| | | private StreamInfo onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId,boolean isSubStream) { |
| | | /** |
| | | * 点播成功时调用截图. |
| | | * |
| | | * @param mediaServerItemInuse media |
| | | * @param deviceId 设备 ID |
| | | * @param channelId 通道 ID |
| | | * @param stream ssrc |
| | | */ |
| | | private void snapOnPlay(MediaServerItem mediaServerItemInuse, String deviceId, String channelId, String stream) { |
| | | String streamUrl; |
| | | if (mediaServerItemInuse.getRtspPort() != 0) { |
| | | streamUrl = String.format("rtsp://127.0.0.1:%s/%s/%s", mediaServerItemInuse.getRtspPort(), "rtp", stream); |
| | | } else { |
| | | streamUrl = String.format("http://127.0.0.1:%s/%s/%s.live.mp4", mediaServerItemInuse.getHttpPort(), "rtp", stream); |
| | | } |
| | | String path = "snap"; |
| | | String fileName = deviceId + "_" + channelId + ".jpg"; |
| | | // 请求截图 |
| | | logger.info("[请求截图]: " + fileName); |
| | | zlmresTfulUtils.getSnap(mediaServerItemInuse, streamUrl, 15, 1, path, fileName); |
| | | } |
| | | |
| | | private StreamInfo onPublishHandlerForPlay(MediaServerItem mediaServerItem, HookParam hookParam, String deviceId, String channelId) { |
| | | 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); |
| | | } |
| | | OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam)hookParam; |
| | | streamInfo = onPublishHandler(mediaServerItem, streamChangedHookParam, deviceId, channelId); |
| | | if (streamInfo != null) { |
| | | 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); |
| | | DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); |
| | | if (deviceChannel != null) { |
| | | deviceChannel.setStreamId(streamInfo.getStream()); |
| | | storager.startPlay(deviceId, channelId, streamInfo.getStream()); |
| | | } |
| | | InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId); |
| | | if (inviteInfo != null) { |
| | | inviteInfo.setStatus(InviteSessionStatus.ok); |
| | | inviteInfo.setStreamInfo(streamInfo); |
| | | if(device.isSwitchPrimarySubStream()){ |
| | | inviteStreamService.updateInviteInfoSub(inviteInfo); |
| | | }else { |
| | | inviteStreamService.updateInviteInfo(inviteInfo); |
| | | } |
| | | |
| | | inviteStreamService.updateInviteInfo(inviteInfo); |
| | | } |
| | | } |
| | | return streamInfo; |
| | | |
| | | } |
| | | |
| | | private StreamInfo onPublishHandlerForPlayback(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, String startTime, String endTime) { |
| | | |
| | | StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId); |
| | | private StreamInfo onPublishHandlerForPlayback(MediaServerItem mediaServerItem, HookParam param, String deviceId, String channelId, String startTime, String endTime) { |
| | | OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam) param; |
| | | StreamInfo streamInfo = onPublishHandler(mediaServerItem, streamChangedHookParam, deviceId, channelId); |
| | | if (streamInfo != null) { |
| | | streamInfo.setStartTime(startTime); |
| | | streamInfo.setEndTime(endTime); |
| | |
| | | device.getDeviceId(), channelId, startTime, endTime, ssrcInfo.getPort(), device.getStreamMode(), |
| | | ssrcInfo.getSsrc(), device.isSsrcCheck()); |
| | | // 初始化redis中的invite消息状态 |
| | | InviteInfo inviteInfo = InviteInfo.getinviteInfo(device.getDeviceId(), channelId, ssrcInfo.getStream(), ssrcInfo, |
| | | InviteInfo inviteInfo = InviteInfo.getInviteInfo(device.getDeviceId(), channelId, ssrcInfo.getStream(), ssrcInfo, |
| | | mediaServerItem.getSdpIp(), ssrcInfo.getPort(), device.getStreamMode(), InviteSessionType.PLAYBACK, |
| | | InviteSessionStatus.ready); |
| | | inviteStreamService.updateInviteInfo(inviteInfo); |
| | |
| | | inviteStreamService.removeInviteInfo(inviteInfo); |
| | | }; |
| | | |
| | | ZlmHttpHookSubscribe.Event hookEvent = (mediaServerItemInuse, jsonObject) -> { |
| | | logger.info("收到回放订阅消息: " + jsonObject); |
| | | ZlmHttpHookSubscribe.Event hookEvent = (mediaServerItemInuse, hookParam) -> { |
| | | logger.info("收到回放订阅消息: " + hookParam); |
| | | dynamicTask.stop(playBackTimeOutTaskKey); |
| | | StreamInfo streamInfo = onPublishHandlerForPlayback(mediaServerItemInuse, jsonObject, deviceId, channelId, startTime, endTime); |
| | | StreamInfo streamInfo = onPublishHandlerForPlayback(mediaServerItemInuse, hookParam, deviceId, channelId, startTime, endTime); |
| | | if (streamInfo == null) { |
| | | logger.warn("设备回放API调用失败!"); |
| | | callback.run(InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(), |
| | |
| | | subscribe.removeSubscribe(hookSubscribe); |
| | | String stream = String.format("%08x", Integer.parseInt(ssrcInResponse)).toUpperCase(); |
| | | hookSubscribe.getContent().put("stream", stream); |
| | | inviteInfo.setStream(stream); |
| | | subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject response) -> { |
| | | logger.info("[ZLM HOOK] ssrc修正后收到订阅消息: " + response.toJSONString()); |
| | | inviteStreamService.updateInviteInfoForStream(inviteInfo, stream); |
| | | subscribe.addSubscribe(hookSubscribe, (mediaServerItemInUse, hookParam) -> { |
| | | logger.info("[ZLM HOOK] ssrc修正后收到订阅消息: " + hookParam); |
| | | dynamicTask.stop(playBackTimeOutTaskKey); |
| | | // hook响应 |
| | | hookEvent.response(mediaServerItemInUse, response); |
| | | hookEvent.response(mediaServerItemInUse, hookParam); |
| | | }); |
| | | } |
| | | // 更新ssrc |
| | |
| | | "下级自定义了ssrc,重新设置收流信息失败", null); |
| | | |
| | | }else { |
| | | if (ssrcInfo.getStream()!= null && !ssrcInfo.getStream().equals(inviteInfo.getStream())) { |
| | | inviteStreamService.removeInviteInfo(inviteInfo); |
| | | } |
| | | |
| | | ssrcInfo.setSsrc(ssrcInResponse); |
| | | inviteInfo.setSsrcInfo(ssrcInfo); |
| | | inviteInfo.setStream(ssrcInfo.getStream()); |
| | |
| | | } |
| | | logger.info("[录像下载] deviceId: {}, channelId: {}, 下载速度:{}, 收流端口:{}, 收流模式:{}, SSRC: {}, SSRC校验:{}", device.getDeviceId(), channelId, downloadSpeed, ssrcInfo.getPort(), device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck()); |
| | | // 初始化redis中的invite消息状态 |
| | | InviteInfo inviteInfo = InviteInfo.getinviteInfo(device.getDeviceId(), channelId, ssrcInfo.getStream(), ssrcInfo, |
| | | InviteInfo inviteInfo = InviteInfo.getInviteInfo(device.getDeviceId(), channelId, ssrcInfo.getStream(), ssrcInfo, |
| | | mediaServerItem.getSdpIp(), ssrcInfo.getPort(), device.getStreamMode(), InviteSessionType.DOWNLOAD, |
| | | InviteSessionStatus.ready); |
| | | inviteStreamService.updateInviteInfo(inviteInfo); |
| | |
| | | streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); |
| | | inviteStreamService.removeInviteInfo(inviteInfo); |
| | | }; |
| | | ZlmHttpHookSubscribe.Event hookEvent = (mediaServerItemInuse, jsonObject) -> { |
| | | logger.info("[录像下载]收到订阅消息: " + jsonObject); |
| | | ZlmHttpHookSubscribe.Event hookEvent = (mediaServerItemInuse, hookParam) -> { |
| | | logger.info("[录像下载]收到订阅消息: " + hookParam); |
| | | dynamicTask.stop(downLoadTimeOutTaskKey); |
| | | StreamInfo streamInfo = onPublishHandlerForDownload(mediaServerItemInuse, jsonObject, deviceId, channelId, startTime, endTime); |
| | | StreamInfo streamInfo = onPublishHandlerForDownload(mediaServerItemInuse, hookParam, deviceId, channelId, startTime, endTime); |
| | | if (streamInfo == null) { |
| | | logger.warn("[录像下载] 获取流地址信息失败"); |
| | | callback.run(InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(), |
| | |
| | | // 添加订阅 |
| | | HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId()); |
| | | subscribe.removeSubscribe(hookSubscribe); |
| | | hookSubscribe.getContent().put("stream", String.format("%08x", Integer.parseInt(ssrcInResponse)).toUpperCase()); |
| | | subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject response) -> { |
| | | logger.info("[ZLM HOOK] ssrc修正后收到订阅消息: " + response.toJSONString()); |
| | | String stream = String.format("%08x", Integer.parseInt(ssrcInResponse)).toUpperCase(); |
| | | hookSubscribe.getContent().put("stream", stream); |
| | | inviteStreamService.updateInviteInfoForStream(inviteInfo, stream); |
| | | subscribe.addSubscribe(hookSubscribe, (mediaServerItemInUse, hookParam) -> { |
| | | logger.info("[ZLM HOOK] ssrc修正后收到订阅消息: " + hookParam); |
| | | dynamicTask.stop(downLoadTimeOutTaskKey); |
| | | hookEvent.response(mediaServerItemInUse, response); |
| | | hookEvent.response(mediaServerItemInUse, hookParam); |
| | | }); |
| | | } |
| | | |
| | |
| | | "下级自定义了ssrc,重新设置收流信息失败", null); |
| | | |
| | | }else { |
| | | if (ssrcInfo.getStream()!= null && !ssrcInfo.getStream().equals(inviteInfo.getStream())) { |
| | | inviteStreamService.removeInviteInfo(inviteInfo); |
| | | } |
| | | ssrcInfo.setSsrc(ssrcInResponse); |
| | | inviteInfo.setSsrcInfo(ssrcInfo); |
| | | inviteInfo.setStream(ssrcInfo.getStream()); |
| | |
| | | logger.info("[录像下载] 收到invite 200, 下级自定义了ssrc, 但是当前模式无需修正"); |
| | | } |
| | | } |
| | | inviteStreamService.updateInviteInfo(inviteInfo); |
| | | }); |
| | | } catch (InvalidArgumentException | SipException | ParseException e) { |
| | | logger.error("[命令发送失败] 录像下载: {}", e.getMessage()); |
| | |
| | | return null; |
| | | } |
| | | |
| | | private StreamInfo onPublishHandlerForDownload(MediaServerItem mediaServerItemInuse, JSONObject response, String deviceId, String channelId, String startTime, String endTime) { |
| | | StreamInfo streamInfo = onPublishHandler(mediaServerItemInuse, response, deviceId, channelId); |
| | | private StreamInfo onPublishHandlerForDownload(MediaServerItem mediaServerItemInuse, HookParam hookParam, String deviceId, String channelId, String startTime, String endTime) { |
| | | OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam) hookParam; |
| | | StreamInfo streamInfo = onPublishHandler(mediaServerItemInuse, streamChangedHookParam, deviceId, channelId); |
| | | if (streamInfo != null) { |
| | | streamInfo.setProgress(0); |
| | | streamInfo.setStartTime(startTime); |
| | |
| | | } |
| | | |
| | | |
| | | public StreamInfo onPublishHandler(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId) { |
| | | String streamId = resonse.getString("stream"); |
| | | JSONArray tracks = resonse.getJSONArray("tracks"); |
| | | StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem, "rtp", streamId, tracks, null); |
| | | public StreamInfo onPublishHandler(MediaServerItem mediaServerItem, OnStreamChangedHookParam hookParam, String deviceId, String channelId) { |
| | | StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem, "rtp", hookParam.getStream(), hookParam.getTracks(), null); |
| | | streamInfo.setDeviceID(deviceId); |
| | | streamInfo.setChannelId(channelId); |
| | | return streamInfo; |
| | |
| | | } |
| | | |
| | | @Override |
| | | public void getSnap(String deviceId, String channelId, String fileName,boolean isSubStream, ErrorCallback errorCallback) { |
| | | public void getSnap(String deviceId, String channelId, String fileName, 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; |
| | | if(device.isSwitchPrimarySubStream()){ |
| | | inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId,isSubStream); |
| | | }else { |
| | | inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId); |
| | | } |
| | | InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId); |
| | | if (inviteInfo != null) { |
| | | if (inviteInfo.getStreamInfo() != null) { |
| | | // 已存在线直接截图 |
| | |
| | | } |
| | | |
| | | MediaServerItem newMediaServerItem = getNewMediaServerItem(device); |
| | | play(newMediaServerItem, deviceId, channelId,isSubStream, (code, msg, data)->{ |
| | | play(newMediaServerItem, deviceId, channelId, (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,isSubStream, errorCallback); |
| | | getSnap(deviceId, channelId, fileName, errorCallback); |
| | | }else { |
| | | errorCallback.run(InviteErrorCode.FAIL.getCode(), InviteErrorCode.FAIL.getMsg(), null); |
| | | } |
| | |
| | | } |
| | | }); |
| | | } |
| | | |
| | | |
| | | /*======================设备主子码流逻辑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=========================*/ |
| | | |
| | | } |