| | |
| | | import com.genersoft.iot.vmp.media.bean.MediaServer; |
| | | import com.genersoft.iot.vmp.service.*; |
| | | import com.genersoft.iot.vmp.service.bean.*; |
| | | import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| | | import com.genersoft.iot.vmp.utils.CloudRecordUtils; |
| | |
| | | |
| | | @Autowired |
| | | private ISIPCommanderForPlatform commanderForPlatform; |
| | | |
| | | @Autowired |
| | | private RedisGbPlayMsgListener redisGbPlayMsgListener; |
| | | |
| | | @Autowired |
| | | private SSRCFactory ssrcFactory; |
| | |
| | | ); |
| | | |
| | | SSRCInfo ssrcInfo = mediaServerService.openRTPServer(event.getMediaServer(), event.getStream(), null, |
| | | device.isSsrcCheck(), true, 0, false, !deviceChannel.isHasAudio(), false, device.getStreamModeForParam()); |
| | | device.isSsrcCheck(), true, 0, false, !deviceChannel.getHasAudio(), false, device.getStreamModeForParam()); |
| | | playBack(event.getMediaServer(), ssrcInfo, deviceId, channelId, startTime, endTime, null); |
| | | } |
| | | } |
| | |
| | | logger.warn("[点播] 未找到可用的zlm deviceId: {},channelId:{}", deviceId, channelId); |
| | | throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到可用的zlm"); |
| | | } |
| | | |
| | | Device device = redisCatchStorage.getDevice(deviceId); |
| | | if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE") && !mediaServerItem.isRtpEnable()) { |
| | | logger.warn("[点播] 单端口收流时不支持TCP主动方式收流 deviceId: {},channelId:{}", deviceId, channelId); |
| | |
| | | InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId); |
| | | if (inviteInfo != null ) { |
| | | if (inviteInfo.getStreamInfo() == null) { |
| | | // 释放生成的ssrc,使用上一次申请的 |
| | | ssrcFactory.releaseSsrc(mediaServerItem.getId(), ssrc); |
| | | // 点播发起了但是尚未成功, 仅注册回调等待结果即可 |
| | | inviteStreamService.once(InviteSessionType.PLAY, deviceId, channelId, null, callback); |
| | | logger.info("[点播开始] 已经请求中,等待结果, deviceId: {}, channelId: {}", device.getDeviceId(), channelId); |
| | |
| | | } |
| | | } |
| | | String streamId = String.format("%s_%s", device.getDeviceId(), channelId); |
| | | SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, ssrc, device.isSsrcCheck(), false, 0, false, !channel.isHasAudio(), false, device.getStreamModeForParam()); |
| | | SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, ssrc, device.isSsrcCheck(), false, 0, false, !channel.getHasAudio(), 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, |
| | |
| | | }, userSetting.getPlayTimeout()); |
| | | |
| | | try { |
| | | mediaServerService.startSendRtpPassive(mediaServerItem, null, sendRtpItem, userSetting.getPlayTimeout() * 1000); |
| | | mediaServerService.startSendRtpPassive(mediaServerItem, sendRtpItem, userSetting.getPlayTimeout() * 1000); |
| | | }catch (ControllerException e) { |
| | | mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc()); |
| | | logger.info("[语音对讲]失败 deviceId: {}, channelId: {}", device.getDeviceId(), channelId); |
| | |
| | | ErrorCallback<Object> callback) { |
| | | |
| | | if (mediaServerItem == null || ssrcInfo == null) { |
| | | callback.run(InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getCode(), |
| | | InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getMsg(), |
| | | null); |
| | | if (callback != null) { |
| | | callback.run(InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getCode(), |
| | | InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getMsg(), |
| | | null); |
| | | } |
| | | return; |
| | | } |
| | | logger.info("[点播开始] deviceId: {}, channelId: {},码流类型:{}, 收流端口: {}, 码流:{}, 收流模式:{}, SSRC: {}, SSRC校验:{}", |
| | |
| | | // 释放ssrc |
| | | mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); |
| | | streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); |
| | | |
| | | callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), "点播端口分配异常", null); |
| | | if (callback != null) { |
| | | callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), "点播端口分配异常", null); |
| | | } |
| | | inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channel.getChannelId(), null, |
| | | InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), "点播端口分配异常", null); |
| | | return; |
| | |
| | | logger.info("[点播超时] 收流超时 deviceId: {}, channelId: {},码流:{},端口:{}, SSRC: {}", |
| | | device.getDeviceId(), channel.getChannelId(), channel.getStreamIdentification(), |
| | | ssrcInfo.getPort(), ssrcInfo.getSsrc()); |
| | | |
| | | callback.run(InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode(), InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getMsg(), null); |
| | | if (callback != null) { |
| | | callback.run(InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode(), InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getMsg(), null); |
| | | } |
| | | inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channel.getChannelId(), null, |
| | | InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode(), InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getMsg(), null); |
| | | inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channel.getChannelId()); |
| | |
| | | // hook响应 |
| | | StreamInfo streamInfo = onPublishHandlerForPlay(hookData.getMediaServer(), hookData.getMediaInfo(), device.getDeviceId(), channel.getChannelId()); |
| | | if (streamInfo == null){ |
| | | callback.run(InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(), |
| | | InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null); |
| | | if (callback != null) { |
| | | callback.run(InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(), |
| | | InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null); |
| | | } |
| | | |
| | | inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channel.getChannelId(), 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 (callback != null) { |
| | | callback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), streamInfo); |
| | | } |
| | | inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channel.getChannelId(), null, |
| | | InviteErrorCode.SUCCESS.getCode(), |
| | | InviteErrorCode.SUCCESS.getMsg(), |
| | |
| | | mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); |
| | | |
| | | streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); |
| | | |
| | | callback.run(event.statusCode, event.msg, null); |
| | | if (callback != null) { |
| | | callback.run(event.statusCode, event.msg, null); |
| | | } |
| | | inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channel.getChannelId(), null, |
| | | InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(), |
| | | String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg), null); |
| | |
| | | mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); |
| | | |
| | | streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); |
| | | |
| | | callback.run(InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getCode(), |
| | | InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getMsg(), null); |
| | | if (callback != null) { |
| | | callback.run(InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getCode(), |
| | | InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getMsg(), null); |
| | | } |
| | | inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channel.getChannelId(), null, |
| | | InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getCode(), |
| | | InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getMsg(), null); |
| | |
| | | |
| | | @Override |
| | | public MediaServer getNewMediaServerItem(Device device) { |
| | | logger.error(device.getMediaServerId(), "wocnm"); |
| | | if (device == null) { |
| | | return null; |
| | | } |
| | | MediaServer mediaServerItem; |
| | | if (ObjectUtils.isEmpty(device.getMediaServerId()) || "auto".equals(device.getMediaServerId())) { |
| | | logger.error("进的这"); |
| | | mediaServerItem = mediaServerService.getMediaServerForMinimumLoad(null); |
| | | } else { |
| | | logger.error("进的else"); |
| | | mediaServerItem = mediaServerService.getOne(device.getMediaServerId()); |
| | | } |
| | | if (mediaServerItem == null) { |
| | |
| | | } |
| | | |
| | | MediaServer newMediaServerItem = getNewMediaServerItem(device); |
| | | if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE") && ! newMediaServerItem.isRtpEnable()) { |
| | | if ("TCP-ACTIVE".equalsIgnoreCase(device.getStreamMode()) && ! newMediaServerItem.isRtpEnable()) { |
| | | logger.warn("[录像回放] 单端口收流时不支持TCP主动方式收流 deviceId: {},channelId:{}", deviceId, channelId); |
| | | throw new ControllerException(ErrorCode.ERROR100.getCode(), "单端口收流时不支持TCP主动方式收流"); |
| | | } |
| | |
| | | .replace(":", "") |
| | | .replace(" ", ""); |
| | | String stream = deviceId + "_" + channelId + "_" + startTimeStr + "_" + endTimeTimeStr; |
| | | SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, stream, null, device.isSsrcCheck(), true, 0, false, !channel.isHasAudio(), false, device.getStreamModeForParam()); |
| | | SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, stream, null, device.isSsrcCheck(), true, 0, false, !channel.getHasAudio(), false, device.getStreamModeForParam()); |
| | | playBack(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, callback); |
| | | } |
| | | |
| | |
| | | return; |
| | | } |
| | | // 录像下载不使用固定流地址,固定流地址会导致如果开始时间与结束时间一致时文件错误的叠加在一起 |
| | | SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, null, device.isSsrcCheck(), true, 0, false,!channel.isHasAudio(), false, device.getStreamModeForParam()); |
| | | SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, null, device.isSsrcCheck(), true, 0, false,!channel.getHasAudio(), false, device.getStreamModeForParam()); |
| | | download(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, downloadSpeed, callback); |
| | | } |
| | | |
| | |
| | | dynamicTask.stop(downLoadTimeOutTaskKey); |
| | | callback.run(InviteErrorCode.ERROR_FOR_SIGNALLING_TIMEOUT.getCode(), |
| | | String.format("录像下载失败, 错误码: %s, %s", event.statusCode, event.msg), null); |
| | | mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); |
| | | streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); |
| | | inviteStreamService.removeInviteInfo(inviteInfo); |
| | | }; |
| | |
| | | InviteInfo inviteInfoForNew = inviteStreamService.getInviteInfo(inviteInfo.getType(), inviteInfo.getDeviceId() |
| | | , inviteInfo.getChannelId(), inviteInfo.getStream()); |
| | | inviteInfoForNew.getStreamInfo().setDownLoadFilePath(downloadFileInfo); |
| | | inviteStreamService.updateInviteInfo(inviteInfoForNew); |
| | | // 不可以马上移除会导致后续接口拿不到下载地址 |
| | | inviteStreamService.updateInviteInfo(inviteInfoForNew, 60*15L); |
| | | }; |
| | | Hook hook = Hook.getInstance(HookType.on_record_mp4, "rtp", ssrcInfo.getStream(), mediaServerItem.getId()); |
| | | // 设置过期时间,下载失败时自动处理订阅数据 |
| | | // long difference = DateUtil.getDifference(startTime, endTime)/1000; |
| | | // Instant expiresInstant = Instant.now().plusSeconds(TimeUnit.MINUTES.toSeconds(difference * 2)); |
| | | // hookSubscribe.setExpires(expiresInstant); |
| | | hook.setExpireTime(System.currentTimeMillis() + 24 * 60 * 60 * 1000); |
| | | subscribe.addSubscribe(hook, hookEventForRecord); |
| | | }); |
| | | } catch (InvalidArgumentException | SipException | ParseException e) { |
| | |
| | | logger.warn("[获取下载进度] 查询录像信息时发现节点不存在"); |
| | | return null; |
| | | } |
| | | SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(deviceId, channelId, null, stream); |
| | | |
| | | if (ssrcTransaction == null) { |
| | | logger.warn("[获取下载进度] 下载已结束"); |
| | | return null; |
| | | } |
| | | String app = "rtp"; |
| | | MediaInfo mediaInfo = mediaServerService.getMediaInfo(mediaServerItem, app, stream); |
| | | if (mediaInfo == null) { |
| | | logger.warn("[获取下载进度] 查询进度失败, 节点Id: {}, {}/{}", mediaServerId, app, stream); |
| | | return null; |
| | | } |
| | | if (mediaInfo.getDuration() == 0) { |
| | | Long duration = mediaServerService.updateDownloadProcess(mediaServerItem, app, stream); |
| | | if (duration == null || duration == 0) { |
| | | inviteInfo.getStreamInfo().setProgress(0); |
| | | } else { |
| | | String startTime = inviteInfo.getStreamInfo().getStartTime(); |
| | |
| | | long start = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(startTime); |
| | | long end = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(endTime); |
| | | |
| | | BigDecimal currentCount = new BigDecimal(mediaInfo.getDuration()); |
| | | BigDecimal currentCount = new BigDecimal(duration); |
| | | BigDecimal totalCount = new BigDecimal((end - start) * 1000); |
| | | BigDecimal divide = currentCount.divide(totalCount, 2, RoundingMode.HALF_UP); |
| | | double process = divide.doubleValue(); |
| | |
| | | // 开始发流 |
| | | MediaServer mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); |
| | | |
| | | if (mediaInfo == null) { |
| | | RequestPushStreamMsg requestPushStreamMsg = RequestPushStreamMsg.getInstance(sendRtpItem); |
| | | redisGbPlayMsgListener.sendMsgForStartSendRtpStream(sendRtpItem.getServerId(), requestPushStreamMsg, () -> { |
| | | startSendRtpStreamFailHand(sendRtpItem, platform, callIdHeader); |
| | | }); |
| | | } else { |
| | | if (mediaInfo != null) { |
| | | try { |
| | | if (sendRtpItem.isTcpActive()) { |
| | | mediaServerService.startSendRtpPassive(mediaInfo, platform, sendRtpItem, null); |
| | | mediaServerService.startSendRtpPassive(mediaInfo, sendRtpItem, null); |
| | | } else { |
| | | mediaServerService.startSendRtp(mediaInfo, platform, sendRtpItem); |
| | | mediaServerService.startSendRtp(mediaInfo, sendRtpItem); |
| | | } |
| | | redisCatchStorage.sendPlatformStartPlayMsg(sendRtpItem, platform); |
| | | }catch (ControllerException e) { |
| | | logger.error("RTP推流失败: {}", e.getMessage()); |
| | | startSendRtpStreamFailHand(sendRtpItem, platform, callIdHeader); |