Merge branch 'wvp-28181-2.0' into main-dev
# Conflicts:
# src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java
# src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
# src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java
# src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java
# src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
New file |
| | |
| | | alter table wvp_device_channel |
| | | change stream_id stream_id varying(255) |
| | |
| | | custom_longitude double precision, |
| | | latitude double precision, |
| | | custom_latitude double precision, |
| | | stream_id character varying(50), |
| | | stream_id character varying(255), |
| | | device_id character varying(50) not null, |
| | | parental character varying(50), |
| | | has_audio bool default false, |
| | |
| | | logger.warn("[æ¶å°ACK]ï¼æªæ¾å°æ¥èª{}ï¼ç®æ 为({})çæ¨æµä¿¡æ¯",fromUserId, toUserId); |
| | | return; |
| | | } |
| | | // tcp䏻卿¶ï¼æ¤æ¶æ¯çº§èä¸çº§å¹³å°ï¼å¨åå¤200okæ¶ï¼æ¬å°å·²ç»è¯·æ±zlmå¼å¯çå¬ï¼è·³è¿ä¸é¢æ¥éª¤ |
| | | if (sendRtpItem.isTcpActive()) { |
| | | return; |
| | | } |
| | | logger.info("[æ¶å°ACK]ï¼rtp/{}å¼å§çº§æ¨æµ, ç®æ ={}:{}ï¼SSRC={}, RTCP={}", sendRtpItem.getStream(), |
| | | sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc(), sendRtpItem.isRtcp()); |
| | | // åæ¶è®¾ç½®çè¶
æ¶ä»»å¡ |
| | |
| | | import javax.sip.message.Response; |
| | | import java.text.ParseException; |
| | | import java.time.Instant; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | import java.util.Random; |
| | | import java.util.Vector; |
| | | |
| | |
| | | content.append("y=" + sendRtpItem.getSsrc() + "\r\n"); |
| | | content.append("f=\r\n"); |
| | | |
| | | |
| | | try { |
| | | // è¶
æ¶æªæ¶å°Ackåºè¯¥åå¤bye,å½åçå¾
æ¶é´ä¸º10ç§ |
| | | dynamicTask.startDelay(callIdHeader.getCallId(), () -> { |
| | |
| | | logger.error("[å½ä»¤åé失败] 彿 级è åéBYE: {}", e.getMessage()); |
| | | } |
| | | }, 60 * 1000); |
| | | |
| | | responseSdpAck(request, content.toString(), platform); |
| | | responseSdpAck(request, content.toString(), platform); |
| | | // tcp䏻卿¨¡å¼ï¼åå¤sdpåå¼å¯çå¬ |
| | | if (sendRtpItem.isTcpActive()) { |
| | | MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); |
| | | Map<String, Object> param = new HashMap<>(12); |
| | | param.put("vhost","__defaultVhost__"); |
| | | param.put("app",sendRtpItem.getApp()); |
| | | param.put("stream",sendRtpItem.getStreamId()); |
| | | param.put("ssrc", sendRtpItem.getSsrc()); |
| | | if (!sendRtpItem.isTcpActive()) { |
| | | param.put("dst_url",sendRtpItem.getIp()); |
| | | param.put("dst_port", sendRtpItem.getPort()); |
| | | } |
| | | String is_Udp = sendRtpItem.isTcp() ? "0" : "1"; |
| | | param.put("is_udp", is_Udp); |
| | | param.put("src_port", localPort); |
| | | param.put("pt", sendRtpItem.getPt()); |
| | | param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0"); |
| | | param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0"); |
| | | if (!sendRtpItem.isTcp()) { |
| | | // å¼å¯rtcpä¿æ´» |
| | | param.put("udp_rtcp_timeout", sendRtpItem.isRtcp()? "1":"0"); |
| | | } |
| | | JSONObject startSendRtpStreamResult = zlmServerFactory.startSendRtpStreamForPassive(mediaInfo, param); |
| | | if (startSendRtpStreamResult != null) { |
| | | startSendRtpStreamHand(evt, sendRtpItem, null, startSendRtpStreamResult, param, callIdHeader); |
| | | } |
| | | } |
| | | } catch (SipException | InvalidArgumentException | ParseException e) { |
| | | logger.error("[å½ä»¤åé失败] 彿 级è åå¤SdpAck", e); |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | private void startSendRtpStreamHand(RequestEvent evt, SendRtpItem sendRtpItem, ParentPlatform parentPlatform, |
| | | JSONObject jsonObject, Map<String, Object> param, CallIdHeader callIdHeader) { |
| | | if (jsonObject == null) { |
| | | logger.error("ä¸çº§TCP被å¨å¯å¨çå¬å¤±è´¥: è¯·æ£æ¥ZLMæå¡"); |
| | | } else if (jsonObject.getInteger("code") == 0) { |
| | | logger.info("è°ç¨ZLM-TCPè¢«å¨æ¨æµæ¥å£, ç»æï¼ {}", jsonObject); |
| | | logger.info("å¯å¨çå¬TCPè¢«å¨æ¨æµæå[ {}/{} ]ï¼{}->{}:{}, " ,param.get("app"), param.get("stream"), jsonObject.getString("local_port"), param.get("dst_url"), param.get("dst_port")); |
| | | } else { |
| | | logger.error("å¯å¨çå¬TCPè¢«å¨æ¨æµå¤±è´¥: {}, åæ°ï¼{}",jsonObject.getString("msg"), JSON.toJSONString(param)); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å®ææ¨æµ |
| | | */ |
| | |
| | | // æªæ³¨åç设å¤ä¸åå¤ç |
| | | return; |
| | | } |
| | | logger.info("[æ¶å°å¿è·³]ï¼ device: {}", device.getDeviceId()); |
| | | SIPRequest request = (SIPRequest) evt.getRequest(); |
| | | // åå¤200 OK |
| | | try { |
| | |
| | | import com.genersoft.iot.vmp.media.zlm.dto.hook.*;
|
| | | import com.genersoft.iot.vmp.service.*;
|
| | | import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
|
| | | import com.genersoft.iot.vmp.service.bean.SSRCInfo;
|
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
| | | import com.genersoft.iot.vmp.utils.DateUtil;
|
| | | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
| | | import com.genersoft.iot.vmp.vmanager.bean.OtherRtpSendInfo;
|
| | | import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
|
| | |
| | |
|
| | | if ("rtp".equals(param.getApp())) {
|
| | | String[] s = param.getStream().split("_");
|
| | | if (!mediaInfo.isRtpEnable() || s.length != 2) {
|
| | | if (!mediaInfo.isRtpEnable() || (s.length != 2 && s.length != 4)) {
|
| | | defaultResult.setResult(HookResult.SUCCESS());
|
| | | return defaultResult;
|
| | | }
|
| | |
| | | defaultResult.setResult(new HookResult(ErrorCode.ERROR404.getCode(), ErrorCode.ERROR404.getMsg()));
|
| | | return defaultResult;
|
| | | }
|
| | | logger.info("[ZLM HOOK] æµæªæ¾å°, åèµ·èªå¨ç¹æï¼{}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream());
|
| | | if (s.length == 2) {
|
| | | logger.info("[ZLM HOOK] é¢è§æµæªæ¾å°, åèµ·èªå¨ç¹æï¼{}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream());
|
| | |
|
| | | RequestMessage msg = new RequestMessage();
|
| | | String key = DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId;
|
| | | boolean exist = resultHolder.exist(key, null);
|
| | | msg.setKey(key);
|
| | | String uuid = UUID.randomUUID().toString();
|
| | | msg.setId(uuid);
|
| | | DeferredResult<HookResult> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue());
|
| | | RequestMessage msg = new RequestMessage();
|
| | | String key = DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId;
|
| | | boolean exist = resultHolder.exist(key, null);
|
| | | msg.setKey(key);
|
| | | String uuid = UUID.randomUUID().toString();
|
| | | msg.setId(uuid);
|
| | | DeferredResult<HookResult> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue());
|
| | |
|
| | | result.onTimeout(() -> {
|
| | | logger.info("[ZLM HOOK] èªå¨ç¹æ, çå¾
è¶
æ¶");
|
| | | // éæ¾rtpserver
|
| | | msg.setData(new HookResult(ErrorCode.ERROR100.getCode(), "ç¹æè¶
æ¶"));
|
| | | resultHolder.invokeResult(msg);
|
| | | });
|
| | |
|
| | | // å½åæ¥è¯¢ä»¥channelIdä½ä¸ºdeviceIdæ¥è¯¢
|
| | | resultHolder.put(key, uuid, result);
|
| | |
|
| | | if (!exist) {
|
| | | playService.play(mediaInfo, deviceId, channelId, null, (code, message, data) -> {
|
| | | msg.setData(new HookResult(code, message));
|
| | | result.onTimeout(() -> {
|
| | | logger.info("[ZLM HOOK] é¢è§æµèªå¨ç¹æ, çå¾
è¶
æ¶");
|
| | | // éæ¾rtpserver
|
| | | msg.setData(new HookResult(ErrorCode.ERROR100.getCode(), "ç¹æè¶
æ¶"));
|
| | | resultHolder.invokeResult(msg);
|
| | | });
|
| | |
|
| | | resultHolder.put(key, uuid, result);
|
| | |
|
| | | if (!exist) {
|
| | | playService.play(mediaInfo, deviceId, channelId, null, (code, message, data) -> {
|
| | | msg.setData(new HookResult(code, message));
|
| | | resultHolder.invokeResult(msg);
|
| | | });
|
| | | }
|
| | | return result;
|
| | | }else if(s.length == 4){
|
| | | // æ¤æ¶ä¸ºå½ååæ¾ï¼ å½ååæ¾æ ¼å¼ä¸º> 设å¤ID_ééID_å¼å§æ¶é´_ç»ææ¶é´
|
| | | String startTimeStr = s[2];
|
| | | String endTimeStr = s[3];
|
| | | if (startTimeStr == null || endTimeStr == null || startTimeStr.length() != 14 || endTimeStr.length() != 14) {
|
| | | defaultResult.setResult(HookResult.SUCCESS());
|
| | | return defaultResult;
|
| | | }
|
| | | String startTime = DateUtil.urlToyyyy_MM_dd_HH_mm_ss(startTimeStr);
|
| | | String endTime = DateUtil.urlToyyyy_MM_dd_HH_mm_ss(endTimeStr);
|
| | | logger.info("[ZLM HOOK] åæ¾æµæªæ¾å°, åèµ·èªå¨ç¹æï¼{}->{}->{}/{}-{}-{}",
|
| | | param.getMediaServerId(), param.getSchema(),
|
| | | param.getApp(), param.getStream(),
|
| | | startTime, endTime
|
| | | );
|
| | | RequestMessage msg = new RequestMessage();
|
| | | String key = DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId;
|
| | | boolean exist = resultHolder.exist(key, null);
|
| | | msg.setKey(key);
|
| | | String uuid = UUID.randomUUID().toString();
|
| | | msg.setId(uuid);
|
| | | DeferredResult<HookResult> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue());
|
| | |
|
| | | result.onTimeout(() -> {
|
| | | logger.info("[ZLM HOOK] åæ¾æµèªå¨ç¹æ, çå¾
è¶
æ¶");
|
| | | // éæ¾rtpserver
|
| | | msg.setData(new HookResult(ErrorCode.ERROR100.getCode(), "ç¹æè¶
æ¶"));
|
| | | resultHolder.invokeResult(msg);
|
| | | });
|
| | |
|
| | | resultHolder.put(key, uuid, result);
|
| | |
|
| | | if (!exist) {
|
| | | SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaInfo, param.getStream(), null,
|
| | | device.isSsrcCheck(), true, 0, false, device.getStreamModeForParam());
|
| | | playService.playBack(mediaInfo, ssrcInfo, deviceId, channelId, startTime, endTime, (code, message, data) -> {
|
| | | msg.setData(new HookResult(code, message));
|
| | | resultHolder.invokeResult(msg);
|
| | | });
|
| | | }
|
| | | return result;
|
| | | }else {
|
| | | defaultResult.setResult(HookResult.SUCCESS());
|
| | | return defaultResult;
|
| | | }
|
| | | return result;
|
| | |
|
| | | } else {
|
| | | // ææµä»£ç
|
| | | StreamProxyItem streamProxyByAppAndStream = streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream());
|
| | |
| | | |
| | | void playBack(String deviceId, String channelId, String startTime, String endTime, ErrorCallback<Object> callback); |
| | | void playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, ErrorCallback<Object> callback); |
| | | |
| | | void zlmServerOffline(String mediaServerId); |
| | | |
| | | void download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, ErrorCallback<Object> callback); |
| | |
| | | void stopTalk(Device device, String channelId, Boolean streamIsReady); |
| | | |
| | | void getSnap(String deviceId, String channelId, String fileName, ErrorCallback errorCallback); |
| | | |
| | | |
| | | } |
| | |
| | | List<DeviceChannel> deviceChannelList = new ArrayList<>(); |
| | | if (channelReduces.size() > 0){ |
| | | PlatformCatalog catalog = catalogManager.selectByPlatFormAndCatalogId(platform.getServerGBId(),catalogId); |
| | | if (catalog == null || !catalogId.equals(platform.getDeviceGBId())) { |
| | | if (catalog == null && catalogId.equals(platform.getDeviceGBId())) { |
| | | for (ChannelReduce channelReduce : channelReduces) { |
| | | DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(channelReduce.getDeviceId(), channelReduce.getChannelId()); |
| | | deviceChannel.setParental(0); |
| | | deviceChannel.setCivilCode(platform.getServerGBDomain()); |
| | | deviceChannelList.add(deviceChannel); |
| | | } |
| | | return deviceChannelList; |
| | | } else if (catalog == null || !catalogId.equals(platform.getDeviceGBId())) { |
| | | logger.warn("æªæ¥è¯¢å°ç®å½{}çä¿¡æ¯", catalogId); |
| | | return null; |
| | | } |
| | |
| | | return; |
| | | } |
| | | MediaServerItem newMediaServerItem = getNewMediaServerItem(device); |
| | | SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, null, device.isSsrcCheck(), true, 0, false,false, device.getStreamModeForParam()); |
| | | String stream = null; |
| | | if (newMediaServerItem.isRtpEnable()) { |
| | | String startTimeStr = startTime.replace("-", "") |
| | | .replace(":", "") |
| | | .replace(" ", ""); |
| | | System.out.println(startTimeStr); |
| | | String endTimeTimeStr = endTime.replace("-", "") |
| | | .replace(":", "") |
| | | .replace(" ", ""); |
| | | System.out.println(endTimeTimeStr); |
| | | stream = deviceId + "_" + channelId + "_" + startTimeStr + "_" + endTimeTimeStr; |
| | | } |
| | | SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, stream, null, device.isSsrcCheck(), true, 0, false,false, device.getStreamModeForParam()); |
| | | playBack(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, callback); |
| | | } |
| | | |
| | |
| | | return formatter.format(formatterCompatibleISO8601.parse(formatTime)); |
| | | } |
| | | |
| | | public static String urlToyyyy_MM_dd_HH_mm_ss(String formatTime) { |
| | | return formatter.format(urlFormatter.parse(formatTime)); |
| | | } |
| | | |
| | | /** |
| | | * yyyy_MM_dd_HH_mm_ss 转æ¶é´æ³ |
| | | * @param formatTime |
| | |
| | | return urlFormatter.format(nowDateTime); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * æ ¼å¼æ ¡éª |
| | | * @param timeStr æ¶é´å符串 |