Merge branch 'refs/heads/2.7.0'
# Conflicts:
# src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpItem.java
# 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/ByeRequestProcessor.java
# src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
# src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
# src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java
# src/main/java/com/genersoft/iot/vmp/media/zlm/ZlmHttpHookSubscribe.java
# src/main/java/com/genersoft/iot/vmp/service/IDeviceChannelService.java
# src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
# src/main/java/com/genersoft/iot/vmp/service/impl/DeviceChannelServiceImpl.java
# src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
# src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
# src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java
# src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java
# src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisStreamMsgListener.java
# src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
# src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
| | |
| | | |
| | | public static final String REGISTER_EXPIRE_TASK_KEY_PREFIX = "VMP_device_register_expire_"; |
| | | public static final String PUSH_STREAM_LIST = "VMP_PUSH_STREAM_LIST_"; |
| | | public static final String WAITE_SEND_PUSH_STREAM = "VMP_WAITE_SEND_PUSH_STREAM:"; |
| | | public static final String START_SEND_PUSH_STREAM = "VMP_START_SEND_PUSH_STREAM:"; |
| | | public static final String PUSH_STREAM_ONLINE = "VMP_PUSH_STREAM_ONLINE:"; |
| | | |
| | | |
| | | |
| | |
| | | |
| | | private List<String> allowedOrigins = new ArrayList<>(); |
| | | |
| | | private int maxNotifyCountQueue = 10000; |
| | | private int maxNotifyCountQueue = 100000; |
| | | |
| | | private int registerAgainAfterTime = 60; |
| | | |
| | |
| | | private RedisAlarmMsgListener redisAlarmMsgListener; |
| | | |
| | | @Autowired |
| | | private RedisStreamMsgListener redisStreamMsgListener; |
| | | |
| | | @Autowired |
| | | private RedisGbPlayMsgListener redisGbPlayMsgListener; |
| | | |
| | | @Autowired |
| | | private RedisPushStreamStatusMsgListener redisPushStreamStatusMsgListener; |
| | | |
| | | @Autowired |
| | | private RedisPushStreamStatusListMsgListener redisPushStreamListMsgListener; |
| | | |
| | | @Autowired |
| | | private RedisPushStreamResponseListener redisPushStreamResponseListener; |
| | | |
| | | @Autowired |
| | | private RedisCloseStreamMsgListener redisCloseStreamMsgListener; |
| | | |
| | | |
| | | @Autowired |
| | | private RedisPushStreamCloseResponseListener redisPushStreamCloseResponseListener; |
| | | private RedisRpcConfig redisRpcConfig; |
| | | |
| | | @Autowired |
| | | private RedisPushStreamResponseListener redisPushStreamCloseResponseListener; |
| | | |
| | | |
| | | /** |
| | |
| | | container.setConnectionFactory(connectionFactory); |
| | | container.addMessageListener(redisGPSMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_GPS)); |
| | | container.addMessageListener(redisAlarmMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_SUBSCRIBE_ALARM_RECEIVE)); |
| | | container.addMessageListener(redisStreamMsgListener, new PatternTopic(VideoManagerConstants.WVP_MSG_STREAM_CHANGE_PREFIX + "PUSH")); |
| | | container.addMessageListener(redisGbPlayMsgListener, new PatternTopic(RedisGbPlayMsgListener.WVP_PUSH_STREAM_KEY)); |
| | | container.addMessageListener(redisPushStreamStatusMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_PUSH_STREAM_STATUS_CHANGE)); |
| | | container.addMessageListener(redisPushStreamListMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_PUSH_STREAM_LIST_CHANGE)); |
| | | container.addMessageListener(redisPushStreamResponseListener, new PatternTopic(VideoManagerConstants.VM_MSG_STREAM_PUSH_RESPONSE)); |
| | | container.addMessageListener(redisCloseStreamMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_STREAM_PUSH_CLOSE)); |
| | | container.addMessageListener(redisPushStreamCloseResponseListener, new PatternTopic(VideoManagerConstants.VM_MSG_STREAM_PUSH_CLOSE_REQUESTED)); |
| | | container.addMessageListener(redisRpcConfig, new PatternTopic(RedisRpcConfig.REDIS_REQUEST_CHANNEL_KEY)); |
| | | container.addMessageListener(redisPushStreamCloseResponseListener, new PatternTopic(VideoManagerConstants.VM_MSG_STREAM_PUSH_RESPONSE)); |
| | | return container; |
| | | } |
| | | } |
New file |
| | |
| | | package com.genersoft.iot.vmp.conf.redis; |
| | | |
| | | import com.alibaba.fastjson2.JSON; |
| | | import com.genersoft.iot.vmp.common.CommonCallback; |
| | | import com.genersoft.iot.vmp.conf.UserSetting; |
| | | import com.genersoft.iot.vmp.conf.redis.bean.RedisRpcMessage; |
| | | import com.genersoft.iot.vmp.conf.redis.bean.RedisRpcRequest; |
| | | import com.genersoft.iot.vmp.conf.redis.bean.RedisRpcResponse; |
| | | import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; |
| | | import com.genersoft.iot.vmp.service.redisMsg.control.RedisRpcController; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Qualifier; |
| | | import org.springframework.data.redis.connection.Message; |
| | | import org.springframework.data.redis.connection.MessageListener; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.lang.reflect.InvocationTargetException; |
| | | import java.lang.reflect.Method; |
| | | import java.util.Map; |
| | | import java.util.Random; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.concurrent.ConcurrentLinkedQueue; |
| | | import java.util.concurrent.SynchronousQueue; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | @Component |
| | | public class RedisRpcConfig implements MessageListener { |
| | | |
| | | private final static Logger logger = LoggerFactory.getLogger(RedisRpcConfig.class); |
| | | |
| | | public final static String REDIS_REQUEST_CHANNEL_KEY = "WVP_REDIS_REQUEST_CHANNEL_KEY"; |
| | | |
| | | private final Random random = new Random(); |
| | | |
| | | @Autowired |
| | | private UserSetting userSetting; |
| | | |
| | | @Autowired |
| | | private RedisRpcController redisRpcController; |
| | | |
| | | @Autowired |
| | | private RedisTemplate<Object, Object> redisTemplate; |
| | | |
| | | @Autowired |
| | | private ZlmHttpHookSubscribe hookSubscribe; |
| | | |
| | | private ConcurrentLinkedQueue<Message> taskQueue = new ConcurrentLinkedQueue<>(); |
| | | |
| | | @Qualifier("taskExecutor") |
| | | @Autowired |
| | | private ThreadPoolTaskExecutor taskExecutor; |
| | | |
| | | @Override |
| | | public void onMessage(Message message, byte[] pattern) { |
| | | boolean isEmpty = taskQueue.isEmpty(); |
| | | taskQueue.offer(message); |
| | | if (isEmpty) { |
| | | taskExecutor.execute(() -> { |
| | | while (!taskQueue.isEmpty()) { |
| | | Message msg = taskQueue.poll(); |
| | | try { |
| | | RedisRpcMessage redisRpcMessage = JSON.parseObject(new String(msg.getBody()), RedisRpcMessage.class); |
| | | if (redisRpcMessage.getRequest() != null) { |
| | | handlerRequest(redisRpcMessage.getRequest()); |
| | | } else if (redisRpcMessage.getResponse() != null){ |
| | | handlerResponse(redisRpcMessage.getResponse()); |
| | | } else { |
| | | logger.error("[redis rpc è§£æå¤±è´¥] {}", JSON.toJSONString(redisRpcMessage)); |
| | | } |
| | | } catch (Exception e) { |
| | | logger.error("[redis rpc è§£æå¼å¸¸] ", e); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | |
| | | private void handlerResponse(RedisRpcResponse response) { |
| | | if (userSetting.getServerId().equals(response.getToId())) { |
| | | return; |
| | | } |
| | | logger.info("[redis-rpc] << {}", response); |
| | | response(response); |
| | | } |
| | | |
| | | private void handlerRequest(RedisRpcRequest request) { |
| | | try { |
| | | if (userSetting.getServerId().equals(request.getFromId())) { |
| | | return; |
| | | } |
| | | logger.info("[redis-rpc] << {}", request); |
| | | Method method = getMethod(request.getUri()); |
| | | // æ²¡ææºå¸¦ç®æ IDçå¯ä»¥ç解为åªä¸ªwvpæç»æå°±åªä¸ªåå¤ï¼æºå¸¦ç®æ IDï¼ä½æ¯å¦ææ¯ä¸åå¨çuriåç´æ¥åå¤404 |
| | | if (userSetting.getServerId().equals(request.getToId())) { |
| | | if (method == null) { |
| | | // åå¤404ç»æ |
| | | RedisRpcResponse response = request.getResponse(); |
| | | response.setStatusCode(404); |
| | | sendResponse(response); |
| | | return; |
| | | } |
| | | RedisRpcResponse response = (RedisRpcResponse)method.invoke(redisRpcController, request); |
| | | if(response != null) { |
| | | sendResponse(response); |
| | | } |
| | | }else { |
| | | if (method == null) { |
| | | return; |
| | | } |
| | | RedisRpcResponse response = (RedisRpcResponse)method.invoke(redisRpcController, request); |
| | | if (response != null) { |
| | | sendResponse(response); |
| | | } |
| | | } |
| | | }catch (InvocationTargetException | IllegalAccessException e) { |
| | | logger.error("[redis rpc ] å¤ç请æ±å¤±è´¥ ", e); |
| | | } |
| | | |
| | | } |
| | | |
| | | private Method getMethod(String name) { |
| | | // å¯å¨åæ«æææçè·¯å¾æ³¨è§£ |
| | | Method[] methods = redisRpcController.getClass().getMethods(); |
| | | for (Method method : methods) { |
| | | if (method.getName().equals(name)) { |
| | | return method; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | private void sendResponse(RedisRpcResponse response){ |
| | | logger.info("[redis-rpc] >> {}", response); |
| | | response.setToId(userSetting.getServerId()); |
| | | RedisRpcMessage message = new RedisRpcMessage(); |
| | | message.setResponse(response); |
| | | redisTemplate.convertAndSend(REDIS_REQUEST_CHANNEL_KEY, message); |
| | | } |
| | | |
| | | private void sendRequest(RedisRpcRequest request){ |
| | | logger.info("[redis-rpc] >> {}", request); |
| | | RedisRpcMessage message = new RedisRpcMessage(); |
| | | message.setRequest(request); |
| | | redisTemplate.convertAndSend(REDIS_REQUEST_CHANNEL_KEY, message); |
| | | } |
| | | |
| | | |
| | | private final Map<Long, SynchronousQueue<RedisRpcResponse>> topicSubscribers = new ConcurrentHashMap<>(); |
| | | private final Map<Long, CommonCallback<RedisRpcResponse>> callbacks = new ConcurrentHashMap<>(); |
| | | |
| | | public RedisRpcResponse request(RedisRpcRequest request, int timeOut) { |
| | | request.setSn((long) random.nextInt(1000) + 1); |
| | | SynchronousQueue<RedisRpcResponse> subscribe = subscribe(request.getSn()); |
| | | |
| | | try { |
| | | sendRequest(request); |
| | | return subscribe.poll(timeOut, TimeUnit.SECONDS); |
| | | } catch (InterruptedException e) { |
| | | logger.warn("[redis rpc timeout] uri: {}, sn: {}", request.getUri(), request.getSn(), e); |
| | | } finally { |
| | | this.unsubscribe(request.getSn()); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public void request(RedisRpcRequest request, CommonCallback<RedisRpcResponse> callback) { |
| | | request.setSn((long) random.nextInt(1000) + 1); |
| | | setCallback(request.getSn(), callback); |
| | | sendRequest(request); |
| | | } |
| | | |
| | | public Boolean response(RedisRpcResponse response) { |
| | | SynchronousQueue<RedisRpcResponse> queue = topicSubscribers.get(response.getSn()); |
| | | CommonCallback<RedisRpcResponse> callback = callbacks.get(response.getSn()); |
| | | if (queue != null) { |
| | | try { |
| | | return queue.offer(response, 2, TimeUnit.SECONDS); |
| | | } catch (InterruptedException e) { |
| | | logger.error("{}", e.getMessage(), e); |
| | | } |
| | | }else if (callback != null) { |
| | | callback.run(response); |
| | | callbacks.remove(response.getSn()); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | private void unsubscribe(long key) { |
| | | topicSubscribers.remove(key); |
| | | } |
| | | |
| | | |
| | | private SynchronousQueue<RedisRpcResponse> subscribe(long key) { |
| | | SynchronousQueue<RedisRpcResponse> queue = null; |
| | | if (!topicSubscribers.containsKey(key)) |
| | | topicSubscribers.put(key, queue = new SynchronousQueue<>()); |
| | | return queue; |
| | | } |
| | | |
| | | private void setCallback(long key, CommonCallback<RedisRpcResponse> callback) { |
| | | // TODO 妿å¤ä¸ªä¸çº§ç¹æåä¸ä¸ªéé伿é®é¢ |
| | | callbacks.put(key, callback); |
| | | } |
| | | |
| | | public void removeCallback(long key) { |
| | | callbacks.remove(key); |
| | | } |
| | | |
| | | |
| | | public int getCallbackCount(){ |
| | | return callbacks.size(); |
| | | } |
| | | |
| | | // @Scheduled(fixedRate = 1000) //æ¯1ç§æ§è¡ä¸æ¬¡ |
| | | // public void execute(){ |
| | | // logger.info("callbacksçé¿åº¦: " + callbacks.size()); |
| | | // logger.info("éåçé¿åº¦: " + topicSubscribers.size()); |
| | | // logger.info("HOOKçå¬çé¿åº¦: " + hookSubscribe.size()); |
| | | // logger.info(""); |
| | | // } |
| | | } |
New file |
| | |
| | | package com.genersoft.iot.vmp.conf.redis.bean; |
| | | |
| | | public class RedisRpcMessage { |
| | | |
| | | private RedisRpcRequest request; |
| | | |
| | | private RedisRpcResponse response; |
| | | |
| | | public RedisRpcRequest getRequest() { |
| | | return request; |
| | | } |
| | | |
| | | public void setRequest(RedisRpcRequest request) { |
| | | this.request = request; |
| | | } |
| | | |
| | | public RedisRpcResponse getResponse() { |
| | | return response; |
| | | } |
| | | |
| | | public void setResponse(RedisRpcResponse response) { |
| | | this.response = response; |
| | | } |
| | | } |
New file |
| | |
| | | package com.genersoft.iot.vmp.conf.redis.bean; |
| | | |
| | | /** |
| | | * éè¿redisåéè¯·æ± |
| | | */ |
| | | public class RedisRpcRequest { |
| | | |
| | | /** |
| | | * æ¥èªçWVP ID |
| | | */ |
| | | private String fromId; |
| | | |
| | | |
| | | /** |
| | | * ç®æ çWVP ID |
| | | */ |
| | | private String toId; |
| | | |
| | | /** |
| | | * åºåå· |
| | | */ |
| | | private long sn; |
| | | |
| | | /** |
| | | * 访é®çè·¯å¾ |
| | | */ |
| | | private String uri; |
| | | |
| | | /** |
| | | * åæ° |
| | | */ |
| | | private Object param; |
| | | |
| | | public String getFromId() { |
| | | return fromId; |
| | | } |
| | | |
| | | public void setFromId(String fromId) { |
| | | this.fromId = fromId; |
| | | } |
| | | |
| | | public String getToId() { |
| | | return toId; |
| | | } |
| | | |
| | | public void setToId(String toId) { |
| | | this.toId = toId; |
| | | } |
| | | |
| | | public String getUri() { |
| | | return uri; |
| | | } |
| | | |
| | | public void setUri(String uri) { |
| | | this.uri = uri; |
| | | } |
| | | |
| | | public Object getParam() { |
| | | return param; |
| | | } |
| | | |
| | | public void setParam(Object param) { |
| | | this.param = param; |
| | | } |
| | | |
| | | public long getSn() { |
| | | return sn; |
| | | } |
| | | |
| | | public void setSn(long sn) { |
| | | this.sn = sn; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | | return "RedisRpcRequest{" + |
| | | "uri='" + uri + '\'' + |
| | | ", fromId='" + fromId + '\'' + |
| | | ", toId='" + toId + '\'' + |
| | | ", sn=" + sn + |
| | | ", param=" + param + |
| | | '}'; |
| | | } |
| | | |
| | | public RedisRpcResponse getResponse() { |
| | | RedisRpcResponse response = new RedisRpcResponse(); |
| | | response.setFromId(fromId); |
| | | response.setToId(toId); |
| | | response.setSn(sn); |
| | | response.setUri(uri); |
| | | return response; |
| | | } |
| | | } |
New file |
| | |
| | | package com.genersoft.iot.vmp.conf.redis.bean; |
| | | |
| | | /** |
| | | * éè¿redisåéåå¤ |
| | | */ |
| | | public class RedisRpcResponse { |
| | | |
| | | /** |
| | | * æ¥èªçWVP ID |
| | | */ |
| | | private String fromId; |
| | | |
| | | |
| | | /** |
| | | * ç®æ çWVP ID |
| | | */ |
| | | private String toId; |
| | | |
| | | |
| | | /** |
| | | * åºåå· |
| | | */ |
| | | private long sn; |
| | | |
| | | /** |
| | | * ç¶æç |
| | | */ |
| | | private int statusCode; |
| | | |
| | | /** |
| | | * 访é®çè·¯å¾ |
| | | */ |
| | | private String uri; |
| | | |
| | | /** |
| | | * åæ° |
| | | */ |
| | | private Object body; |
| | | |
| | | public String getFromId() { |
| | | return fromId; |
| | | } |
| | | |
| | | public void setFromId(String fromId) { |
| | | this.fromId = fromId; |
| | | } |
| | | |
| | | public String getToId() { |
| | | return toId; |
| | | } |
| | | |
| | | public void setToId(String toId) { |
| | | this.toId = toId; |
| | | } |
| | | |
| | | public long getSn() { |
| | | return sn; |
| | | } |
| | | |
| | | public void setSn(long sn) { |
| | | this.sn = sn; |
| | | } |
| | | |
| | | public int getStatusCode() { |
| | | return statusCode; |
| | | } |
| | | |
| | | public void setStatusCode(int statusCode) { |
| | | this.statusCode = statusCode; |
| | | } |
| | | |
| | | public String getUri() { |
| | | return uri; |
| | | } |
| | | |
| | | public void setUri(String uri) { |
| | | this.uri = uri; |
| | | } |
| | | |
| | | public Object getBody() { |
| | | return body; |
| | | } |
| | | |
| | | public void setBody(Object body) { |
| | | this.body = body; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | | return "RedisRpcResponse{" + |
| | | "uri='" + uri + '\'' + |
| | | ", fromId='" + fromId + '\'' + |
| | | ", toId='" + toId + '\'' + |
| | | ", sn=" + sn + |
| | | ", statusCode=" + statusCode + |
| | | ", body=" + body + |
| | | '}'; |
| | | } |
| | | } |
| | |
| | | private double latitude; |
| | | |
| | | /** |
| | | * ç»åº¦ |
| | | */ |
| | | @Schema(description = "èªå®ä¹ç»åº¦") |
| | | private double customLongitude; |
| | | |
| | | /** |
| | | * 纬度 |
| | | */ |
| | | @Schema(description = "èªå®ä¹çº¬åº¦") |
| | | private double customLatitude; |
| | | |
| | | /** |
| | | * ç»åº¦ GCJ02 |
| | | */ |
| | | @Schema(description = "GCJ02åæ ç³»ç»åº¦") |
| | |
| | | * æ¯å¦å«æé³é¢ |
| | | */ |
| | | @Schema(description = "æ¯å¦å«æé³é¢") |
| | | private boolean hasAudio; |
| | | private Boolean hasAudio; |
| | | |
| | | /** |
| | | * æ è®°ééçç±»åï¼0->彿 éé 1->ç´ææµéé 2->ä¸å¡åç»/èæç»ç»/è¡æ¿åºå |
| | |
| | | public void setStreamIdentification(String streamIdentification) { |
| | | this.streamIdentification = streamIdentification; |
| | | } |
| | | |
| | | public double getCustomLongitude() { |
| | | return customLongitude; |
| | | } |
| | | |
| | | public void setCustomLongitude(double customLongitude) { |
| | | this.customLongitude = customLongitude; |
| | | } |
| | | |
| | | public double getCustomLatitude() { |
| | | return customLatitude; |
| | | } |
| | | |
| | | public void setCustomLatitude(double customLatitude) { |
| | | this.customLatitude = customLatitude; |
| | | } |
| | | } |
| | |
| | | |
| | | import com.genersoft.iot.vmp.service.bean.RequestPushStreamMsg; |
| | | |
| | | import com.genersoft.iot.vmp.common.VideoManagerConstants; |
| | | |
| | | public class SendRtpItem { |
| | | |
| | | /** |
| | |
| | | * å¹³å°id |
| | | */ |
| | | private String platformId; |
| | | |
| | | /** |
| | | * å¹³å°åç§° |
| | | */ |
| | | private String platformName; |
| | | |
| | | /** |
| | | * 对åºè®¾å¤id |
| | |
| | | private boolean tcpActive; |
| | | |
| | | /** |
| | | * èªå·±æ¨æµä½¿ç¨çIP |
| | | */ |
| | | private String localIp; |
| | | |
| | | /** |
| | | * èªå·±æ¨æµä½¿ç¨çç«¯å£ |
| | | */ |
| | | private int localPort; |
| | |
| | | /** |
| | | * invite ç callId |
| | | */ |
| | | private String CallId; |
| | | private String callId; |
| | | |
| | | /** |
| | | * invite ç fromTag |
| | |
| | | */ |
| | | private String receiveStream; |
| | | |
| | | /** |
| | | * ä¸çº§çç¹æç±»å |
| | | */ |
| | | private String sessionName; |
| | | |
| | | public static SendRtpItem getInstance(RequestPushStreamMsg requestPushStreamMsg) { |
| | | SendRtpItem sendRtpItem = new SendRtpItem(); |
| | | sendRtpItem.setMediaServerId(requestPushStreamMsg.getMediaServerId()); |
| | |
| | | sendRtpItem.setUsePs(requestPushStreamMsg.isPs()); |
| | | sendRtpItem.setOnlyAudio(requestPushStreamMsg.isOnlyAudio()); |
| | | return sendRtpItem; |
| | | |
| | | |
| | | } |
| | | |
| | | public static SendRtpItem getInstance(String app, String stream, String ssrc, String dstIp, Integer dstPort, boolean tcp, int sendLocalPort, Integer pt) { |
| | |
| | | } |
| | | |
| | | public String getCallId() { |
| | | return CallId; |
| | | return callId; |
| | | } |
| | | |
| | | public void setCallId(String callId) { |
| | | CallId = callId; |
| | | this.callId = callId; |
| | | } |
| | | |
| | | public InviteStreamType getPlayType() { |
| | |
| | | this.receiveStream = receiveStream; |
| | | } |
| | | |
| | | public String getPlatformName() { |
| | | return platformName; |
| | | } |
| | | |
| | | public void setPlatformName(String platformName) { |
| | | this.platformName = platformName; |
| | | } |
| | | |
| | | public String getLocalIp() { |
| | | return localIp; |
| | | } |
| | | |
| | | public void setLocalIp(String localIp) { |
| | | this.localIp = localIp; |
| | | } |
| | | |
| | | public String getSessionName() { |
| | | return sessionName; |
| | | } |
| | | |
| | | public void setSessionName(String sessionName) { |
| | | this.sessionName = sessionName; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | | return "SendRtpItem{" + |
| | |
| | | ", port=" + port + |
| | | ", ssrc='" + ssrc + '\'' + |
| | | ", platformId='" + platformId + '\'' + |
| | | ", platformName='" + platformName + '\'' + |
| | | ", deviceId='" + deviceId + '\'' + |
| | | ", app='" + app + '\'' + |
| | | ", channelId='" + channelId + '\'' + |
| | |
| | | ", stream='" + stream + '\'' + |
| | | ", tcp=" + tcp + |
| | | ", tcpActive=" + tcpActive + |
| | | ", localIp='" + localIp + '\'' + |
| | | ", localPort=" + localPort + |
| | | ", mediaServerId='" + mediaServerId + '\'' + |
| | | ", serverId='" + serverId + '\'' + |
| | | ", CallId='" + CallId + '\'' + |
| | | ", CallId='" + callId + '\'' + |
| | | ", fromTag='" + fromTag + '\'' + |
| | | ", toTag='" + toTag + '\'' + |
| | | ", pt=" + pt + |
| | |
| | | ", rtcp=" + rtcp + |
| | | ", playType=" + playType + |
| | | ", receiveStream='" + receiveStream + '\'' + |
| | | ", sessionName='" + sessionName + '\'' + |
| | | '}'; |
| | | } |
| | | |
| | | public String getRedisKey() { |
| | | String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + |
| | | serverId + "_" |
| | | + mediaServerId + "_" |
| | | + platformId + "_" |
| | | + channelId + "_" |
| | | + stream + "_" |
| | | + callId; |
| | | return key; |
| | | } |
| | | } |
| | |
| | | ParentPlatform parentPlatform = null; |
| | | |
| | | Map<String, List<ParentPlatform>> parentPlatformMap = new HashMap<>(); |
| | | Map<String, DeviceChannel> channelMap = new HashMap<>(); |
| | | if (!ObjectUtils.isEmpty(event.getPlatformId())) { |
| | | subscribe = subscribeHolder.getCatalogSubscribe(event.getPlatformId()); |
| | | if (subscribe == null) { |
| | |
| | | for (DeviceChannel deviceChannel : event.getDeviceChannels()) { |
| | | List<ParentPlatform> parentPlatformsForGB = storager.queryPlatFormListForGBWithGBId(deviceChannel.getChannelId(), platforms); |
| | | parentPlatformMap.put(deviceChannel.getChannelId(), parentPlatformsForGB); |
| | | channelMap.put(deviceChannel.getChannelId(), deviceChannel); |
| | | } |
| | | } |
| | | }else if (event.getGbStreams() != null) { |
| | |
| | | } |
| | | logger.info("[Catalogäºä»¶: {}]å¹³å°ï¼{}ï¼å½±åéé{}", event.getType(), platform.getServerGBId(), gbId); |
| | | List<DeviceChannel> deviceChannelList = new ArrayList<>(); |
| | | DeviceChannel deviceChannel = storager.queryChannelInParentPlatform(platform.getServerGBId(), gbId); |
| | | DeviceChannel deviceChannel = channelMap.get(gbId); |
| | | deviceChannelList.add(deviceChannel); |
| | | GbStream gbStream = storager.queryStreamInParentPlatform(platform.getServerGBId(), gbId); |
| | | if(gbStream != null){ |
| | |
| | | Integer finalIndex = index; |
| | | String catalogXmlContent = getCatalogXmlContentForCatalogAddOrUpdate(parentPlatform, channels, |
| | | deviceChannels.size(), type, subscribeInfo); |
| | | System.out.println(catalogXmlContent); |
| | | logger.info("[åéNOTIFYéç¥]ç±»åï¼ {}ï¼åéæ°éï¼ {}", type, channels.size()); |
| | | sendNotify(parentPlatform, catalogXmlContent, subscribeInfo, eventResult -> { |
| | | logger.error("åéNOTIFYéç¥æ¶æ¯å¤±è´¥ãé误ï¼{} {}", eventResult.statusCode, eventResult.msg); |
| | |
| | | |
| | | private String getCatalogXmlContentForCatalogAddOrUpdate(ParentPlatform parentPlatform, List<DeviceChannel> channels, int sumNum, String type, SubscribeInfo subscribeInfo) { |
| | | StringBuffer catalogXml = new StringBuffer(600); |
| | | |
| | | String characterSet = parentPlatform.getCharacterSet(); |
| | | catalogXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n") |
| | | .append("<Notify>\r\n") |
| | |
| | | .append("<Owner> " + channel.getOwner()+ "</Owner>\r\n") |
| | | .append("<CivilCode>" + channel.getCivilCode() + "</CivilCode>\r\n") |
| | | .append("<Address>" + channel.getAddress() + "</Address>\r\n"); |
| | | catalogXml.append("<Longitude>" + channel.getLongitude() + "</Longitude>\r\n"); |
| | | catalogXml.append("<Latitude>" + channel.getLatitude() + "</Latitude>\r\n"); |
| | | } |
| | | if (!"presence".equals(subscribeInfo.getEventType())) { |
| | | catalogXml.append("<Event>" + type + "</Event>\r\n"); |
| | |
| | | import com.google.common.primitives.Bytes; |
| | | import gov.nist.javax.sip.message.SIPRequest; |
| | | import gov.nist.javax.sip.message.SIPResponse; |
| | | import org.apache.commons.lang3.ArrayUtils; |
| | | import org.dom4j.Document; |
| | | import org.dom4j.DocumentException; |
| | | import org.dom4j.Element; |
| | |
| | | return getRootElement(evt, "gb2312"); |
| | | } |
| | | public Element getRootElement(RequestEvent evt, String charset) throws DocumentException { |
| | | |
| | | if (charset == null) { |
| | | charset = "gb2312"; |
| | | } |
| | |
| | | import com.genersoft.iot.vmp.media.service.IMediaServerService; |
| | | import com.genersoft.iot.vmp.service.IDeviceService; |
| | | import com.genersoft.iot.vmp.service.IPlayService; |
| | | import com.genersoft.iot.vmp.service.bean.RequestPushStreamMsg; |
| | | import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener; |
| | | import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; |
| | | import com.genersoft.iot.vmp.service.redisMsg.IRedisRpcService; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| | | import com.genersoft.iot.vmp.vmanager.bean.WVPResult; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.InitializingBean; |
| | |
| | | |
| | | @Autowired |
| | | private IRedisCatchStorage redisCatchStorage; |
| | | @Autowired |
| | | private IRedisRpcService redisRpcService; |
| | | |
| | | @Autowired |
| | | private UserSetting userSetting; |
| | |
| | | private DynamicTask dynamicTask; |
| | | |
| | | @Autowired |
| | | private RedisGbPlayMsgListener redisGbPlayMsgListener; |
| | | |
| | | @Autowired |
| | | private IPlayService playService; |
| | | |
| | | |
| | |
| | | logger.info("[æ¶å°ACK]ï¼ æ¥èª->{}", fromUserId); |
| | | SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, null, callIdHeader.getCallId()); |
| | | if (sendRtpItem == null) { |
| | | logger.warn("[æ¶å°ACK]ï¼æªæ¾å°æ¥èª{}ï¼ç®æ 为({})çæ¨æµä¿¡æ¯",fromUserId, toUserId); |
| | | logger.warn("[æ¶å°ACK]ï¼æªæ¾å°æ¥èª{}ï¼callId: {}", fromUserId, callIdHeader.getCallId()); |
| | | return; |
| | | } |
| | | // tcp䏻卿¶ï¼æ¤æ¶æ¯çº§èä¸çº§å¹³å°ï¼å¨åå¤200okæ¶ï¼æ¬å°å·²ç»è¯·æ±zlmå¼å¯çå¬ï¼è·³è¿ä¸é¢æ¥éª¤ |
| | |
| | | |
| | | if (parentPlatform != null) { |
| | | if (!userSetting.getServerId().equals(sendRtpItem.getServerId())) { |
| | | RequestPushStreamMsg requestPushStreamMsg = RequestPushStreamMsg.getInstance(sendRtpItem); |
| | | redisGbPlayMsgListener.sendMsgForStartSendRtpStream(sendRtpItem.getServerId(), requestPushStreamMsg, () -> { |
| | | playService.startSendRtpStreamFailHand(sendRtpItem, parentPlatform, callIdHeader); |
| | | }); |
| | | WVPResult wvpResult = redisRpcService.startSendRtp(sendRtpItem.getRedisKey(), sendRtpItem); |
| | | if (wvpResult.getCode() == 0) { |
| | | RequestPushStreamMsg requestPushStreamMsg = RequestPushStreamMsg.getInstance(sendRtpItem); |
| | | redisGbPlayMsgListener.sendMsgForStartSendRtpStream(sendRtpItem.getServerId(), requestPushStreamMsg, () -> { |
| | | playService.startSendRtpStreamFailHand(sendRtpItem, parentPlatform, callIdHeader); |
| | | }); |
| | | } |
| | | } else { |
| | | try { |
| | | if (sendRtpItem.isTcpActive()) { |
| | |
| | | import com.genersoft.iot.vmp.media.bean.MediaServer; |
| | | import com.genersoft.iot.vmp.media.service.IMediaServerService; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; |
| | | import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| | | import com.genersoft.iot.vmp.service.*; |
| | | import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; |
| | | import com.genersoft.iot.vmp.service.bean.RequestStopPushStreamMsg; |
| | | import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener; |
| | | import com.genersoft.iot.vmp.service.redisMsg.IRedisRpcService; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| | | import gov.nist.javax.sip.message.SIPRequest; |
| | |
| | | private IStreamPushService pushService; |
| | | |
| | | @Autowired |
| | | private RedisGbPlayMsgListener redisGbPlayMsgListener; |
| | | private IRedisRpcService redisRpcService; |
| | | |
| | | |
| | | @Override |
| | | public void afterPropertiesSet() throws Exception { |
| | |
| | | if (userSetting.getUseCustomSsrcForParentInvite()) { |
| | | mediaServerService.releaseSsrc(mediaInfo.getId(), sendRtpItem.getSsrc()); |
| | | } |
| | | |
| | | ParentPlatform platform = platformService.queryPlatformByServerGBId(sendRtpItem.getPlatformId()); |
| | | if (platform != null) { |
| | | MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0, |
| | | sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getChannelId(), |
| | | sendRtpItem.getPlatformId(), platform.getName(), userSetting.getServerId(), sendRtpItem.getMediaServerId()); |
| | | messageForPushChannel.setPlatFormIndex(platform.getId()); |
| | | redisCatchStorage.sendPlatformStopPlayMsg(messageForPushChannel); |
| | | }else { |
| | | logger.info("[ä¸çº§å¹³å°åæ¢è§ç] æªæ¾å°å¹³å°{}çä¿¡æ¯ï¼åéredisæ¶æ¯å¤±è´¥", sendRtpItem.getPlatformId()); |
| | | } |
| | | }else { |
| | | logger.info("[ä¸çº§å¹³å°åæ¢è§ç] æªæ¾å°å¹³å°{}çä¿¡æ¯ï¼åéredisæ¶æ¯å¤±è´¥", sendRtpItem.getPlatformId()); |
| | | } |
| | | }else { |
| | | MediaServer mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); |
| | |
| | | import com.genersoft.iot.vmp.service.IPlayService; |
| | | import com.genersoft.iot.vmp.service.IStreamProxyService; |
| | | import com.genersoft.iot.vmp.service.IStreamPushService; |
| | | import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; |
| | | import com.genersoft.iot.vmp.service.redisMsg.IRedisRpcService; |
| | | import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; |
| | | import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.*; |
| | | 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; |
| | | import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; |
| | | import com.genersoft.iot.vmp.service.bean.SSRCInfo; |
| | | import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener; |
| | | import com.genersoft.iot.vmp.service.redisMsg.RedisPushStreamResponseListener; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| | |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.InitializingBean; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.sdp.*; |
| | |
| | | import java.util.Map; |
| | | import java.util.Random; |
| | | import java.util.Vector; |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * SIPå½ä»¤ç±»åï¼ INVITEè¯·æ± |
| | |
| | | private IRedisCatchStorage redisCatchStorage; |
| | | |
| | | @Autowired |
| | | private IInviteStreamService inviteStreamService; |
| | | private IRedisRpcService redisRpcService; |
| | | |
| | | @Autowired |
| | | private RedisTemplate<Object, Object> redisTemplate; |
| | | |
| | | @Autowired |
| | | private SSRCFactory ssrcFactory; |
| | | |
| | | @Autowired |
| | | private DynamicTask dynamicTask; |
| | | |
| | | @Autowired |
| | | private RedisPushStreamResponseListener redisPushStreamResponseListener; |
| | | |
| | | @Autowired |
| | | private IPlayService playService; |
| | |
| | | private UserSetting userSetting; |
| | | |
| | | @Autowired |
| | | private ZLMMediaListManager mediaListManager; |
| | | |
| | | @Autowired |
| | | private SipConfig config; |
| | | |
| | | |
| | | @Autowired |
| | | private RedisGbPlayMsgListener redisGbPlayMsgListener; |
| | | |
| | | @Autowired |
| | | private VideoStreamSessionManager streamSession; |
| | | |
| | | @Autowired |
| | | private SendRtpPortManager sendRtpPortManager; |
| | | |
| | | @Autowired |
| | | private RedisPushStreamResponseListener redisPushStreamResponseListener; |
| | | |
| | | |
| | | @Override |
| | |
| | | |
| | | } |
| | | } else if (gbStream != null) { |
| | | |
| | | String ssrc; |
| | | if (userSetting.getUseCustomSsrcForParentInvite() || gb28181Sdp.getSsrc() == null) { |
| | | // ä¸çº§å¹³å°ç¹ææ¶ä¸ä½¿ç¨ä¸çº§å¹³å°æå®çssrcï¼ä½¿ç¨èªå®ä¹çssrcï¼åè彿 ææ¡£-ç¹æå¤å设å¤åªä½æµSSRCå¤çæ¹å¼ |
| | | ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId()); |
| | | }else { |
| | | ssrc = gb28181Sdp.getSsrc(); |
| | | SendRtpItem sendRtpItem = new SendRtpItem(); |
| | | if (!userSetting.getUseCustomSsrcForParentInvite() && gb28181Sdp.getSsrc() != null) { |
| | | sendRtpItem.setSsrc(gb28181Sdp.getSsrc()); |
| | | } |
| | | |
| | | if (tcpActive != null) { |
| | | sendRtpItem.setTcpActive(tcpActive); |
| | | } |
| | | sendRtpItem.setTcp(mediaTransmissionTCP); |
| | | sendRtpItem.setRtcp(platform.isRtcp()); |
| | | sendRtpItem.setPlatformName(platform.getName()); |
| | | sendRtpItem.setPlatformId(platform.getServerGBId()); |
| | | sendRtpItem.setMediaServerId(mediaServerItem.getId()); |
| | | sendRtpItem.setChannelId(channelId); |
| | | sendRtpItem.setIp(addressStr); |
| | | sendRtpItem.setPort(port); |
| | | sendRtpItem.setUsePs(true); |
| | | sendRtpItem.setApp(gbStream.getApp()); |
| | | sendRtpItem.setStream(gbStream.getStream()); |
| | | sendRtpItem.setCallId(callIdHeader.getCallId()); |
| | | sendRtpItem.setFromTag(request.getFromTag()); |
| | | sendRtpItem.setOnlyAudio(false); |
| | | sendRtpItem.setStatus(0); |
| | | sendRtpItem.setSessionName(sessionName); |
| | | // æ¸
çå¯è½åå¨çç¼åé¿å
ç¨å°æ§çæ°æ® |
| | | List<SendRtpItem> sendRtpItemList = redisCatchStorage.querySendRTPServer(platform.getServerGBId(), channelId, gbStream.getStream()); |
| | | if (!sendRtpItemList.isEmpty()) { |
| | | for (SendRtpItem rtpItem : sendRtpItemList) { |
| | | redisCatchStorage.deleteSendRTPServer(rtpItem); |
| | | } |
| | | } |
| | | if ("push".equals(gbStream.getStreamType())) { |
| | | sendRtpItem.setPlayType(InviteStreamType.PUSH); |
| | | if (streamPushItem != null) { |
| | | // ä»redisæ¥è¯¢æ¯å¦æ£å¨æ¥æ¶è¿ä¸ªæ¨æµ |
| | | StreamPushItem pushListItem = redisCatchStorage.getPushListItem(gbStream.getApp(), gbStream.getStream()); |
| | | if (pushListItem != null) { |
| | | pushListItem.setSelf(userSetting.getServerId().equals(pushListItem.getServerId())); |
| | | // æ¨æµç¶æ |
| | | pushStream(evt, request, gbStream, pushListItem, platform, callIdHeader, mediaServerItem, port, tcpActive, |
| | | mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); |
| | | sendRtpItem.setServerId(pushListItem.getSeverId()); |
| | | sendRtpItem.setMediaServerId(pushListItem.getMediaServerId()); |
| | | |
| | | StreamPushItem transform = streamPushService.transform(pushListItem); |
| | | transform.setSelf(userSetting.getServerId().equals(pushListItem.getSeverId())); |
| | | redisCatchStorage.updateSendRTPSever(sendRtpItem); |
| | | // å¼å§æ¨æµ |
| | | sendPushStream(sendRtpItem, mediaServerItem, platform, request); |
| | | }else { |
| | | // æªæ¨æµ æèµ· |
| | | notifyStreamOnline(evt, request, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive, |
| | | mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); |
| | | if (!platform.isStartOfflinePush()) { |
| | | // å¹³å°è®¾ç½®ä¸å
³éäºæèµ·ç¦»çº¿çæ¨æµåç´æ¥åå¤ |
| | | try { |
| | | logger.info("[ä¸çº§ç¹æ] å¤±è´¥ï¼æ¨æµè®¾å¤æªæ¨æµï¼channel: {}, app: {}, stream: {}", sendRtpItem.getChannelId(), sendRtpItem.getApp(), sendRtpItem.getStream()); |
| | | responseAck(request, Response.TEMPORARILY_UNAVAILABLE, "channel stream not pushing"); |
| | | } catch (SipException | InvalidArgumentException | ParseException e) { |
| | | logger.error("[å½ä»¤åé失败] invite ééæªæ¨æµ: {}", e.getMessage()); |
| | | } |
| | | return; |
| | | } |
| | | notifyPushStreamOnline(sendRtpItem, mediaServerItem, platform, request); |
| | | } |
| | | } |
| | | } else if ("proxy".equals(gbStream.getStreamType())) { |
| | | if (null != proxyByAppAndStream) { |
| | | if (sendRtpItem.getSsrc() == null) { |
| | | // ä¸çº§å¹³å°ç¹ææ¶ä¸ä½¿ç¨ä¸çº§å¹³å°æå®çssrcï¼ä½¿ç¨èªå®ä¹çssrcï¼åè彿 ææ¡£-ç¹æå¤å设å¤åªä½æµSSRCå¤çæ¹å¼ |
| | | String ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId()); |
| | | sendRtpItem.setSsrc(ssrc); |
| | | } |
| | | if (proxyByAppAndStream.isStatus()) { |
| | | pushProxyStream(evt, request, gbStream, platform, callIdHeader, mediaServerItem, port, tcpActive, |
| | | mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); |
| | | sendProxyStream(sendRtpItem, mediaServerItem, platform, request); |
| | | } else { |
| | | //å¼å¯ä»£çææµ |
| | | notifyStreamOnline(evt, request, gbStream, null, platform, callIdHeader, mediaServerItem, port, tcpActive, |
| | | mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); |
| | | notifyProxyStreamOnline(sendRtpItem, mediaServerItem, platform, request); |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
| | | } |
| | | } |
| | |
| | | /** |
| | | * å®ææ¨æµ |
| | | */ |
| | | private void pushProxyStream(RequestEvent evt, SIPRequest request, GbStream gbStream, ParentPlatform platform, |
| | | CallIdHeader callIdHeader, MediaServer mediaServer, |
| | | int port, Boolean tcpActive, boolean mediaTransmissionTCP, |
| | | String channelId, String addressStr, String ssrc, String requesterId) { |
| | | Boolean streamReady = mediaServerService.isStreamReady(mediaServer, gbStream.getApp(), gbStream.getStream()); |
| | | private void sendProxyStream(SendRtpItem sendRtpItem, MediaServerItem mediaServerItem, ParentPlatform platform, SIPRequest request) { |
| | | Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, sendRtpItem.getApp(), sendRtpItem.getStream()); |
| | | if (streamReady != null && streamReady) { |
| | | |
| | | // èªå¹³å°å
容 |
| | | SendRtpItem sendRtpItem = mediaServerService.createSendRtpItem(mediaServer, addressStr, port, ssrc, requesterId, |
| | | gbStream.getApp(), gbStream.getStream(), channelId, mediaTransmissionTCP, platform.isRtcp()); |
| | | |
| | | if (sendRtpItem == null) { |
| | | logger.warn("æå¡å¨ç«¯å£èµæºä¸è¶³"); |
| | | try { |
| | | responseAck(request, Response.BUSY_HERE); |
| | | } catch (SipException | InvalidArgumentException | ParseException e) { |
| | | logger.error("[å½ä»¤åé失败] invite æå¡å¨ç«¯å£èµæºä¸è¶³: {}", e.getMessage()); |
| | | } |
| | | return; |
| | | } |
| | | if (tcpActive != null) { |
| | | sendRtpItem.setTcpActive(tcpActive); |
| | | } |
| | | sendRtpItem.setPlayType(InviteStreamType.PUSH); |
| | | // åå
¥redisï¼ è¶
æ¶æ¶åå¤ |
| | | sendRtpItem.setStatus(1); |
| | | sendRtpItem.setCallId(callIdHeader.getCallId()); |
| | | sendRtpItem.setFromTag(request.getFromTag()); |
| | | |
| | | SIPResponse response = sendStreamAck(mediaServer, request, sendRtpItem, platform, evt); |
| | | if (response != null) { |
| | | sendRtpItem.setToTag(response.getToTag()); |
| | | } |
| | | redisCatchStorage.updateSendRTPSever(sendRtpItem); |
| | | |
| | | } |
| | | |
| | | } |
| | | |
| | | private void pushStream(RequestEvent evt, SIPRequest request, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform, |
| | | CallIdHeader callIdHeader, MediaServer mediaServerItem, |
| | | int port, Boolean tcpActive, boolean mediaTransmissionTCP, |
| | | String channelId, String addressStr, String ssrc, String requesterId) { |
| | | // æ¨æµ |
| | | if (streamPushItem.isSelf()) { |
| | | Boolean streamReady = mediaServerService.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream()); |
| | | if (streamReady != null && streamReady) { |
| | | // èªå¹³å°å
容 |
| | | SendRtpItem sendRtpItem = mediaServerService.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId, |
| | | gbStream.getApp(), gbStream.getStream(), channelId, mediaTransmissionTCP, platform.isRtcp()); |
| | | |
| | | if (sendRtpItem == null) { |
| | | int localPort = sendRtpPortManager.getNextPort(mediaServerItem); |
| | | if (localPort == 0) { |
| | | logger.warn("æå¡å¨ç«¯å£èµæºä¸è¶³"); |
| | | try { |
| | | responseAck(request, Response.BUSY_HERE); |
| | |
| | | } |
| | | return; |
| | | } |
| | | if (tcpActive != null) { |
| | | sendRtpItem.setTcpActive(tcpActive); |
| | | sendRtpItem.setPlayType(InviteStreamType.PROXY); |
| | | // åå
¥redisï¼ è¶
æ¶æ¶åå¤ |
| | | sendRtpItem.setStatus(1); |
| | | sendRtpItem.setLocalIp(mediaServerItem.getSdpIp()); |
| | | |
| | | SIPResponse response = sendStreamAck(mediaServer, request, sendRtpItem, platform, evt); |
| | | if (response != null) { |
| | | sendRtpItem.setToTag(response.getToTag()); |
| | | } |
| | | redisCatchStorage.updateSendRTPSever(sendRtpItem); |
| | | } |
| | | } |
| | | |
| | | private void sendPushStream(SendRtpItem sendRtpItem, MediaServerItem mediaServerItem, ParentPlatform platform, SIPRequest request) { |
| | | // æ¨æµ |
| | | if (sendRtpItem.getServerId().equals(userSetting.getServerId())) { |
| | | Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, sendRtpItem.getApp(), sendRtpItem.getStream()); |
| | | if (streamReady != null && streamReady) { |
| | | // èªå¹³å°å
容 |
| | | int localPort = sendRtpPortManager.getNextPort(mediaServerItem); |
| | | if (localPort == 0) { |
| | | logger.warn("æå¡å¨ç«¯å£èµæºä¸è¶³"); |
| | | try { |
| | | responseAck(request, Response.BUSY_HERE); |
| | | } catch (SipException | InvalidArgumentException | ParseException e) { |
| | | logger.error("[å½ä»¤åé失败] invite æå¡å¨ç«¯å£èµæºä¸è¶³: {}", e.getMessage()); |
| | | } |
| | | return; |
| | | } |
| | | sendRtpItem.setPlayType(InviteStreamType.PUSH); |
| | | // åå
¥redisï¼ è¶
æ¶æ¶åå¤ |
| | | sendRtpItem.setStatus(1); |
| | | sendRtpItem.setCallId(callIdHeader.getCallId()); |
| | | |
| | | sendRtpItem.setFromTag(request.getFromTag()); |
| | | SIPResponse response = sendStreamAck(mediaServerItem, request, sendRtpItem, platform, evt); |
| | | SIPResponse response = sendStreamAck(request, sendRtpItem, platform); |
| | | if (response != null) { |
| | | sendRtpItem.setToTag(response.getToTag()); |
| | | } |
| | | if (sendRtpItem.getSsrc() == null) { |
| | | // ä¸çº§å¹³å°ç¹ææ¶ä¸ä½¿ç¨ä¸çº§å¹³å°æå®çssrcï¼ä½¿ç¨èªå®ä¹çssrcï¼åè彿 ææ¡£-ç¹æå¤å设å¤åªä½æµSSRCå¤çæ¹å¼ |
| | | String ssrc = "Play".equalsIgnoreCase(sendRtpItem.getSessionName()) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId()); |
| | | sendRtpItem.setSsrc(ssrc); |
| | | } |
| | | redisCatchStorage.updateSendRTPSever(sendRtpItem); |
| | | |
| | | } else { |
| | | // ä¸å¨çº¿ æèµ· |
| | | notifyStreamOnline(evt, request, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive, |
| | | mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); |
| | | notifyPushStreamOnline(sendRtpItem, mediaServerItem, platform, request); |
| | | } |
| | | |
| | | } else { |
| | | // å
¶ä»å¹³å°å
容 |
| | | otherWvpPushStream(evt, request, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive, |
| | | mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); |
| | | otherWvpPushStream(sendRtpItem, request, platform); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * éç¥æµä¸çº¿ |
| | | */ |
| | | private void notifyStreamOnline(RequestEvent evt, SIPRequest request, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform, |
| | | CallIdHeader callIdHeader, MediaServer mediaServerItem, |
| | | int port, Boolean tcpActive, boolean mediaTransmissionTCP, |
| | | String channelId, String addressStr, String ssrc, String requesterId) { |
| | | if ("proxy".equals(gbStream.getStreamType())) { |
| | | // TODO æ§å¶å¯ç¨ä»¥ä½¿è®¾å¤ä¸çº¿ |
| | | logger.info("[ app={}, stream={} ]ééæªæ¨æµï¼å¯ç¨æµåå¼å§æ¨æµ", gbStream.getApp(), gbStream.getStream()); |
| | | // ç嬿µä¸çº¿ |
| | | Hook hook = Hook.getInstance(HookType.on_media_arrival, gbStream.getApp(), gbStream.getStream(), mediaServerItem.getId()); |
| | | this.hookSubscribe.addSubscribe(hook, (hookData) -> { |
| | | logger.info("[ä¸çº§ç¹æ]ææµä»£çå·²ç»å°±ç»ªï¼ {}/{}", hookData.getApp(), hookData.getStream()); |
| | | dynamicTask.stop(callIdHeader.getCallId()); |
| | | pushProxyStream(evt, request, gbStream, platform, callIdHeader, mediaServerItem, port, tcpActive, |
| | | mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); |
| | | }); |
| | | dynamicTask.startDelay(callIdHeader.getCallId(), () -> { |
| | | logger.info("[ app={}, stream={} ] çå¾
ææµä»£çæµè¶
æ¶", gbStream.getApp(), gbStream.getStream()); |
| | | this.hookSubscribe.removeSubscribe(hook); |
| | | }, userSetting.getPlatformPlayTimeout()); |
| | | boolean start = streamProxyService.start(gbStream.getApp(), gbStream.getStream()); |
| | | if (!start) { |
| | | try { |
| | | responseAck(request, Response.BUSY_HERE, "channel [" + gbStream.getGbId() + "] offline"); |
| | | } catch (SipException | InvalidArgumentException | ParseException e) { |
| | | logger.error("[å½ä»¤åé失败] invite ééæªæ¨æµ: {}", e.getMessage()); |
| | | } |
| | | this.hookSubscribe.removeSubscribe(hook); |
| | | dynamicTask.stop(callIdHeader.getCallId()); |
| | | private void notifyProxyStreamOnline(SendRtpItem sendRtpItem, MediaServerItem mediaServerItem, ParentPlatform platform, SIPRequest request) { |
| | | // TODO æ§å¶å¯ç¨ä»¥ä½¿è®¾å¤ä¸çº¿ |
| | | logger.info("[ app={}, stream={} ]ééæªæ¨æµï¼å¯ç¨æµåå¼å§æ¨æµ", sendRtpItem.getApp(), sendRtpItem.getStream()); |
| | | // ç嬿µä¸çº¿ |
| | | HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed(sendRtpItem.getApp(), sendRtpItem.getStream(), true, "rtsp", mediaServerItem.getId()); |
| | | zlmHttpHookSubscribe.addSubscribe(hookSubscribe, (mediaServerItemInUSe, hookParam) -> { |
| | | OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam)hookParam; |
| | | logger.info("[ä¸çº§ç¹æ]ææµä»£çå·²ç»å°±ç»ªï¼ {}/{}", streamChangedHookParam.getApp(), streamChangedHookParam.getStream()); |
| | | dynamicTask.stop(sendRtpItem.getCallId()); |
| | | sendProxyStream(sendRtpItem, mediaServerItem, platform, request); |
| | | }); |
| | | dynamicTask.startDelay(sendRtpItem.getCallId(), () -> { |
| | | logger.info("[ app={}, stream={} ] çå¾
ææµä»£çæµè¶
æ¶", sendRtpItem.getApp(), sendRtpItem.getStream()); |
| | | zlmHttpHookSubscribe.removeSubscribe(hookSubscribe); |
| | | }, userSetting.getPlatformPlayTimeout()); |
| | | boolean start = streamProxyService.start(sendRtpItem.getApp(), sendRtpItem.getStream()); |
| | | if (!start) { |
| | | try { |
| | | responseAck(request, Response.BUSY_HERE, "channel [" + sendRtpItem.getChannelId() + "] offline"); |
| | | } catch (SipException | InvalidArgumentException | ParseException e) { |
| | | logger.error("[å½ä»¤åé失败] invite ééæªæ¨æµ: {}", e.getMessage()); |
| | | } |
| | | } else if ("push".equals(gbStream.getStreamType())) { |
| | | if (!platform.isStartOfflinePush()) { |
| | | // å¹³å°è®¾ç½®ä¸å
³éäºæèµ·ç¦»çº¿çæ¨æµåç´æ¥åå¤ |
| | | try { |
| | | logger.info("[ä¸çº§ç¹æ] å¤±è´¥ï¼æ¨æµè®¾å¤æªæ¨æµï¼channel: {}, app: {}, stream: {}", gbStream.getGbId(), gbStream.getApp(), gbStream.getStream()); |
| | | responseAck(request, Response.TEMPORARILY_UNAVAILABLE, "channel stream not pushing"); |
| | | } catch (SipException | InvalidArgumentException | ParseException e) { |
| | | logger.error("[å½ä»¤åé失败] invite ééæªæ¨æµ: {}", e.getMessage()); |
| | | } |
| | | return; |
| | | } |
| | | // åéredisæ¶æ¯ä»¥ä½¿è®¾å¤ä¸çº¿ |
| | | logger.info("[ app={}, stream={} ]ééæªæ¨æµï¼åéredisä¿¡æ¯æ§å¶è®¾å¤å¼å§æ¨æµ", gbStream.getApp(), gbStream.getStream()); |
| | | |
| | | MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(1, |
| | | gbStream.getApp(), gbStream.getStream(), gbStream.getGbId(), gbStream.getPlatformId(), |
| | | platform.getName(), null, gbStream.getMediaServerId()); |
| | | redisCatchStorage.sendStreamPushRequestedMsg(messageForPushChannel); |
| | | // 设置è¶
æ¶ |
| | | dynamicTask.startDelay(callIdHeader.getCallId(), () -> { |
| | | logger.info("[ app={}, stream={} ] çå¾
设å¤å¼å§æ¨æµè¶
æ¶", gbStream.getApp(), gbStream.getStream()); |
| | | try { |
| | | redisPushStreamResponseListener.removeEvent(gbStream.getApp(), gbStream.getStream()); |
| | | mediaListManager.removedChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream()); |
| | | responseAck(request, Response.REQUEST_TIMEOUT); // è¶
æ¶ |
| | | } catch (SipException | InvalidArgumentException | ParseException e) { |
| | | logger.error("æªå¤ççå¼å¸¸ ", e); |
| | | } |
| | | }, userSetting.getPlatformPlayTimeout()); |
| | | // æ·»å çå¬ |
| | | int finalPort = port; |
| | | Boolean finalTcpActive = tcpActive; |
| | | |
| | | // æ·»å 卿¬æºä¸çº¿çéç¥ |
| | | mediaListManager.addChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream(), (app, stream, serverId) -> { |
| | | dynamicTask.stop(callIdHeader.getCallId()); |
| | | redisPushStreamResponseListener.removeEvent(gbStream.getApp(), gbStream.getStream()); |
| | | if (serverId.equals(userSetting.getServerId())) { |
| | | SendRtpItem sendRtpItem = mediaServerService.createSendRtpItem(mediaServerItem, addressStr, finalPort, ssrc, requesterId, |
| | | app, stream, channelId, mediaTransmissionTCP, platform.isRtcp()); |
| | | |
| | | if (sendRtpItem == null) { |
| | | logger.warn("ä¸çº§ç¹æ¶å建sendRTPItem失败ï¼å¯è½æ¯æå¡å¨ç«¯å£èµæºä¸è¶³"); |
| | | try { |
| | | responseAck(request, Response.BUSY_HERE); |
| | | } catch (SipException e) { |
| | | logger.error("æªå¤ççå¼å¸¸ ", e); |
| | | } catch (InvalidArgumentException e) { |
| | | logger.error("æªå¤ççå¼å¸¸ ", e); |
| | | } catch (ParseException e) { |
| | | logger.error("æªå¤ççå¼å¸¸ ", e); |
| | | } |
| | | return; |
| | | } |
| | | if (finalTcpActive != null) { |
| | | sendRtpItem.setTcpActive(finalTcpActive); |
| | | } |
| | | sendRtpItem.setPlayType(InviteStreamType.PUSH); |
| | | // åå
¥redisï¼ è¶
æ¶æ¶åå¤ |
| | | sendRtpItem.setStatus(1); |
| | | sendRtpItem.setCallId(callIdHeader.getCallId()); |
| | | |
| | | sendRtpItem.setFromTag(request.getFromTag()); |
| | | SIPResponse response = sendStreamAck(mediaServerItem, request, sendRtpItem, platform, evt); |
| | | if (response != null) { |
| | | sendRtpItem.setToTag(response.getToTag()); |
| | | } |
| | | redisCatchStorage.updateSendRTPSever(sendRtpItem); |
| | | } else { |
| | | // å
¶ä»å¹³å°å
容 |
| | | otherWvpPushStream(evt, request, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive, |
| | | mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); |
| | | } |
| | | }); |
| | | |
| | | // æ·»å åå¤çæç»æè
é误çéç¥ |
| | | redisPushStreamResponseListener.addEvent(gbStream.getApp(), gbStream.getStream(), response -> { |
| | | if (response.getCode() != 0) { |
| | | dynamicTask.stop(callIdHeader.getCallId()); |
| | | mediaListManager.removedChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream()); |
| | | try { |
| | | responseAck(request, Response.TEMPORARILY_UNAVAILABLE, response.getMsg()); |
| | | } catch (SipException | InvalidArgumentException | ParseException e) { |
| | | logger.error("[å½ä»¤åé失败] 彿 级è ç¹æåå¤: {}", e.getMessage()); |
| | | } |
| | | } |
| | | }); |
| | | zlmHttpHookSubscribe.removeSubscribe(hookSubscribe); |
| | | dynamicTask.stop(sendRtpItem.getCallId()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æ¥èªå
¶ä»wvpçæ¨æµ |
| | | * éç¥æµä¸çº¿ |
| | | */ |
| | | private void otherWvpPushStream(RequestEvent evt, SIPRequest request, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform, |
| | | CallIdHeader callIdHeader, MediaServer mediaServerItem, |
| | | int port, Boolean tcpActive, boolean mediaTransmissionTCP, |
| | | String channelId, String addressStr, String ssrc, String requesterId) { |
| | | logger.info("[级èç¹æ]ç´ææµæ¥èªå
¶ä»å¹³å°ï¼åéredisæ¶æ¯"); |
| | | // åéredisæ¶æ¯ |
| | | redisGbPlayMsgListener.sendMsg(streamPushItem.getServerId(), streamPushItem.getMediaServerId(), |
| | | streamPushItem.getApp(), streamPushItem.getStream(), addressStr, port, ssrc, requesterId, |
| | | channelId, mediaTransmissionTCP, platform.isRtcp(),platform.getName(), responseSendItemMsg -> { |
| | | SendRtpItem sendRtpItem = responseSendItemMsg.getSendRtpItem(); |
| | | if (sendRtpItem == null || responseSendItemMsg.getMediaServerItem() == null) { |
| | | logger.warn("æå¡å¨ç«¯å£èµæºä¸è¶³"); |
| | | try { |
| | | responseAck(request, Response.BUSY_HERE); |
| | | } catch (SipException e) { |
| | | logger.error("æªå¤ççå¼å¸¸ ", e); |
| | | } catch (InvalidArgumentException e) { |
| | | logger.error("æªå¤ççå¼å¸¸ ", e); |
| | | } catch (ParseException e) { |
| | | logger.error("æªå¤ççå¼å¸¸ ", e); |
| | | } |
| | | return; |
| | | } |
| | | // æ¶å°sendItem |
| | | if (tcpActive != null) { |
| | | sendRtpItem.setTcpActive(tcpActive); |
| | | } |
| | | sendRtpItem.setPlayType(InviteStreamType.PUSH); |
| | | // åå
¥redisï¼ è¶
æ¶æ¶åå¤ |
| | | sendRtpItem.setStatus(1); |
| | | sendRtpItem.setCallId(callIdHeader.getCallId()); |
| | | |
| | | sendRtpItem.setFromTag(request.getFromTag()); |
| | | SIPResponse response = sendStreamAck(responseSendItemMsg.getMediaServerItem(), request, sendRtpItem, platform, evt); |
| | | if (response != null) { |
| | | sendRtpItem.setToTag(response.getToTag()); |
| | | } |
| | | redisCatchStorage.updateSendRTPSever(sendRtpItem); |
| | | }, (wvpResult) -> { |
| | | |
| | | // é误 |
| | | if (wvpResult.getCode() == RedisGbPlayMsgListener.ERROR_CODE_OFFLINE) { |
| | | // 离线 |
| | | // æ¥è¯¢æ¯å¦å¨æ¬æºä¸çº¿äº |
| | | StreamPushItem currentStreamPushItem = streamPushService.getPush(streamPushItem.getApp(), streamPushItem.getStream()); |
| | | if (currentStreamPushItem.isPushIng()) { |
| | | // å¨çº¿ç¶æ |
| | | pushStream(evt, request, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive, |
| | | mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); |
| | | |
| | | } else { |
| | | // ä¸å¨çº¿ æèµ· |
| | | notifyStreamOnline(evt, request, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive, |
| | | mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); |
| | | } |
| | | } |
| | | private void notifyPushStreamOnline(SendRtpItem sendRtpItem, MediaServerItem mediaServerItem, ParentPlatform platform, SIPRequest request) { |
| | | // åéredisæ¶æ¯ä»¥ä½¿è®¾å¤ä¸çº¿ï¼æµä¸çº¿å被 |
| | | logger.info("[ app={}, stream={} ]ééæªæ¨æµï¼åéredisä¿¡æ¯æ§å¶è®¾å¤å¼å§æ¨æµ", sendRtpItem.getApp(), sendRtpItem.getStream()); |
| | | MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(1, |
| | | sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getChannelId(), sendRtpItem.getPlatformId(), |
| | | platform.getName(), userSetting.getServerId(), sendRtpItem.getMediaServerId()); |
| | | redisCatchStorage.sendStreamPushRequestedMsg(messageForPushChannel); |
| | | // 设置è¶
æ¶ |
| | | dynamicTask.startDelay(sendRtpItem.getCallId(), () -> { |
| | | redisRpcService.stopWaitePushStreamOnline(sendRtpItem); |
| | | logger.info("[ app={}, stream={} ] çå¾
设å¤å¼å§æ¨æµè¶
æ¶", sendRtpItem.getApp(), sendRtpItem.getStream()); |
| | | try { |
| | | responseAck(request, Response.REQUEST_TIMEOUT); // è¶
æ¶ |
| | | } catch (SipException | InvalidArgumentException | ParseException e) { |
| | | logger.error("æªå¤ççå¼å¸¸ ", e); |
| | | } |
| | | }, userSetting.getPlatformPlayTimeout()); |
| | | // |
| | | long key = redisRpcService.waitePushStreamOnline(sendRtpItem, (sendRtpItemKey) -> { |
| | | dynamicTask.stop(sendRtpItem.getCallId()); |
| | | if (sendRtpItemKey == null) { |
| | | logger.warn("[级èç¹æ] çå¾
æ¨æµå¾å°ç»ææªç©ºï¼ {}/{}", sendRtpItem.getApp(), sendRtpItem.getStream()); |
| | | try { |
| | | responseAck(request, Response.BUSY_HERE); |
| | | } catch (SipException | InvalidArgumentException | ParseException e) { |
| | | logger.error("æªå¤ççå¼å¸¸ ", e); |
| | | } |
| | | return; |
| | | } |
| | | SendRtpItem sendRtpItemFromRedis = (SendRtpItem)redisTemplate.opsForValue().get(sendRtpItemKey); |
| | | if (sendRtpItemFromRedis == null) { |
| | | logger.warn("[级èç¹æ] çå¾
æ¨æµ, æªæ¾å°redisä¸ç¼åçåæµä¿¡æ¯ï¼ {}/{}", sendRtpItem.getApp(), sendRtpItem.getStream()); |
| | | try { |
| | | responseAck(request, Response.BUSY_HERE); |
| | | } catch (SipException | InvalidArgumentException | ParseException e) { |
| | | logger.error("æªå¤ççå¼å¸¸ ", e); |
| | | } |
| | | return; |
| | | } |
| | | if (sendRtpItemFromRedis.getServerId().equals(userSetting.getServerId())) { |
| | | logger.info("[级èç¹æ] çå¾
çæ¨æµå¨æ¬å¹³å°ä¸çº¿ {}/{}", sendRtpItem.getApp(), sendRtpItem.getStream()); |
| | | int localPort = sendRtpPortManager.getNextPort(mediaServerItem); |
| | | if (localPort == 0) { |
| | | logger.warn("ä¸çº§ç¹æ¶å建sendRTPItem失败ï¼å¯è½æ¯æå¡å¨ç«¯å£èµæºä¸è¶³"); |
| | | try { |
| | | responseAck(request, Response.BUSY_HERE); |
| | | } catch (InvalidArgumentException | ParseException | SipException e) { |
| | | logger.error("[å½ä»¤åé失败] 彿 级è ç¹æåå¤ BUSY_HERE: {}", e.getMessage()); |
| | | } catch (SipException | InvalidArgumentException | ParseException e) { |
| | | logger.error("æªå¤ççå¼å¸¸ ", e); |
| | | } |
| | | }); |
| | | return; |
| | | } |
| | | sendRtpItem.setLocalPort(localPort); |
| | | if (!ObjectUtils.isEmpty(platform.getSendStreamIp())) { |
| | | sendRtpItem.setLocalIp(platform.getSendStreamIp()); |
| | | } |
| | | |
| | | // åå
¥redisï¼ è¶
æ¶æ¶åå¤ |
| | | sendRtpItem.setStatus(1); |
| | | SIPResponse response = sendStreamAck(request, sendRtpItem, platform); |
| | | if (response != null) { |
| | | sendRtpItem.setToTag(response.getToTag()); |
| | | } |
| | | redisCatchStorage.updateSendRTPSever(sendRtpItem); |
| | | } else { |
| | | // å
¶ä»å¹³å°å
容 |
| | | otherWvpPushStream(sendRtpItemFromRedis, request, platform); |
| | | } |
| | | }); |
| | | // æ·»å åå¤çæç»æè
é误çéç¥ |
| | | // redisæ¶æ¯ä¾å¦ï¼ PUBLISH VM_MSG_STREAM_PUSH_RESPONSE '{"code":1,"msg":"失败","app":"1","stream":"2"}' |
| | | redisPushStreamResponseListener.addEvent(sendRtpItem.getApp(), sendRtpItem.getStream(), response -> { |
| | | if (response.getCode() != 0) { |
| | | dynamicTask.stop(sendRtpItem.getCallId()); |
| | | redisRpcService.stopWaitePushStreamOnline(sendRtpItem); |
| | | redisRpcService.removeCallback(key); |
| | | try { |
| | | responseAck(request, Response.TEMPORARILY_UNAVAILABLE, response.getMsg()); |
| | | } catch (SipException | InvalidArgumentException | ParseException e) { |
| | | logger.error("[å½ä»¤åé失败] 彿 级è ç¹æåå¤: {}", e.getMessage()); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | |
| | | public SIPResponse sendStreamAck(MediaServer mediaServerItem, SIPRequest request, SendRtpItem sendRtpItem, ParentPlatform platform, RequestEvent evt) { |
| | | |
| | | String sdpIp = mediaServerItem.getSdpIp(); |
| | | |
| | | /** |
| | | * æ¥èªå
¶ä»wvpçæ¨æµ |
| | | */ |
| | | private void otherWvpPushStream(SendRtpItem sendRtpItem, SIPRequest request, ParentPlatform platform) { |
| | | logger.info("[级èç¹æ] æ¥èªå
¶ä»wvpçæ¨æµ {}/{}", sendRtpItem.getApp(), sendRtpItem.getStream()); |
| | | sendRtpItem = redisRpcService.getSendRtpItem(sendRtpItem.getRedisKey()); |
| | | if (sendRtpItem == null) { |
| | | return; |
| | | } |
| | | // åå
¥redisï¼ è¶
æ¶æ¶åå¤ |
| | | sendRtpItem.setStatus(1); |
| | | SIPResponse response = sendStreamAck(request, sendRtpItem, platform); |
| | | if (response != null) { |
| | | sendRtpItem.setToTag(response.getToTag()); |
| | | } |
| | | redisCatchStorage.updateSendRTPSever(sendRtpItem); |
| | | } |
| | | |
| | | public SIPResponse sendStreamAck(MediaServerItem mediaServerItem, SIPRequest request, SendRtpItem sendRtpItem, ParentPlatform platform, RequestEvent evt) { |
| | | |
| | | String sdpIp = sendRtpItem.getLocalIp(); |
| | | if (!ObjectUtils.isEmpty(platform.getSendStreamIp())) { |
| | | sdpIp = platform.getSendStreamIp(); |
| | | } |
| | |
| | | package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; |
| | | |
| | | import com.genersoft.iot.vmp.conf.CivilCodeFileConf; |
| | | import com.genersoft.iot.vmp.conf.DynamicTask; |
| | | import com.genersoft.iot.vmp.conf.SipConfig; |
| | | import com.genersoft.iot.vmp.conf.UserSetting; |
| | | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| | |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import javax.sip.RequestEvent; |
| | | import javax.sip.header.FromHeader; |
| | | import java.util.ArrayList; |
| | | import java.util.Iterator; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | |
| | | |
| | | private final static Logger logger = LoggerFactory.getLogger(NotifyRequestForCatalogProcessor.class); |
| | | |
| | | private final List<DeviceChannel> updateChannelOnlineList = new CopyOnWriteArrayList<>(); |
| | | private final List<DeviceChannel> updateChannelOfflineList = new CopyOnWriteArrayList<>(); |
| | | private final Map<String, DeviceChannel> updateChannelMap = new ConcurrentHashMap<>(); |
| | | |
| | | private final Map<String, DeviceChannel> addChannelMap = new ConcurrentHashMap<>(); |
| | |
| | | private IDeviceChannelService deviceChannelService; |
| | | |
| | | @Autowired |
| | | private DynamicTask dynamicTask; |
| | | |
| | | @Autowired |
| | | private CivilCodeFileConf civilCodeFileConf; |
| | | |
| | | @Autowired |
| | | private SipConfig sipConfig; |
| | | |
| | | private final static String talkKey = "notify-request-for-catalog-task"; |
| | | @Transactional |
| | | public void process(List<RequestEvent> evtList) { |
| | | if (evtList.isEmpty()) { |
| | | return; |
| | | } |
| | | for (RequestEvent evt : evtList) { |
| | | try { |
| | | long start = System.currentTimeMillis(); |
| | | FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME); |
| | | String deviceId = SipUtils.getUserIdFromFromHeader(fromHeader); |
| | | |
| | | public void process(RequestEvent evt) { |
| | | try { |
| | | long start = System.currentTimeMillis(); |
| | | FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME); |
| | | String deviceId = SipUtils.getUserIdFromFromHeader(fromHeader); |
| | | Device device = redisCatchStorage.getDevice(deviceId); |
| | | if (device == null || !device.isOnLine()) { |
| | | logger.warn("[æ¶å°ç®å½è®¢é
]ï¼{}, 使¯è®¾å¤å·²ç»ç¦»çº¿", (device != null ? device.getDeviceId():"" )); |
| | | return; |
| | | } |
| | | Element rootElement = getRootElement(evt, device.getCharset()); |
| | | if (rootElement == null) { |
| | | logger.warn("[ æ¶å°ç®å½è®¢é
] content cannot be null, {}", evt.getRequest()); |
| | | return; |
| | | } |
| | | Element deviceListElement = rootElement.element("DeviceList"); |
| | | if (deviceListElement == null) { |
| | | return; |
| | | } |
| | | Iterator<Element> deviceListIterator = deviceListElement.elementIterator(); |
| | | if (deviceListIterator != null) { |
| | | |
| | | Device device = redisCatchStorage.getDevice(deviceId); |
| | | if (device == null || !device.isOnLine()) { |
| | | logger.warn("[æ¶å°ç®å½è®¢é
]ï¼{}, 使¯è®¾å¤å·²ç»ç¦»çº¿", (device != null ? device.getDeviceId():"" )); |
| | | return; |
| | | } |
| | | Element rootElement = getRootElement(evt, device.getCharset()); |
| | | if (rootElement == null) { |
| | | logger.warn("[ æ¶å°ç®å½è®¢é
] content cannot be null, {}", evt.getRequest()); |
| | | return; |
| | | } |
| | | Element deviceListElement = rootElement.element("DeviceList"); |
| | | if (deviceListElement == null) { |
| | | return; |
| | | } |
| | | Iterator<Element> deviceListIterator = deviceListElement.elementIterator(); |
| | | if (deviceListIterator != null) { |
| | | |
| | | // éåDeviceList |
| | | while (deviceListIterator.hasNext()) { |
| | | Element itemDevice = deviceListIterator.next(); |
| | | Element channelDeviceElement = itemDevice.element("DeviceID"); |
| | | if (channelDeviceElement == null) { |
| | | continue; |
| | | } |
| | | Element eventElement = itemDevice.element("Event"); |
| | | String event; |
| | | if (eventElement == null) { |
| | | logger.warn("[æ¶å°ç®å½è®¢é
]ï¼{}, 使¯Event为空, 设为é»è®¤å¼ ADD", (device != null ? device.getDeviceId():"" )); |
| | | event = CatalogEvent.ADD; |
| | | }else { |
| | | event = eventElement.getText().toUpperCase(); |
| | | } |
| | | DeviceChannel channel = XmlUtil.channelContentHandler(itemDevice, device, event); |
| | | if (channel == null) { |
| | | logger.info("[æ¶å°ç®å½è®¢é
]ï¼ä½æ¯è§£æå¤±è´¥ {}", new String(evt.getRequest().getRawContent())); |
| | | continue; |
| | | } |
| | | if (channel.getParentId() != null && channel.getParentId().equals(sipConfig.getId())) { |
| | | channel.setParentId(null); |
| | | } |
| | | channel.setDeviceId(device.getDeviceId()); |
| | | logger.info("[æ¶å°ç®å½è®¢é
]ï¼{}/{}", device.getDeviceId(), channel.getChannelId()); |
| | | switch (event) { |
| | | case CatalogEvent.ON: |
| | | // ä¸çº¿ |
| | | logger.info("[æ¶å°ééä¸çº¿éç¥] æ¥èªè®¾å¤: {}, éé {}", device.getDeviceId(), channel.getChannelId()); |
| | | updateChannelOnlineList.add(channel); |
| | | if (updateChannelOnlineList.size() > 300) { |
| | | executeSaveForOnline(); |
| | | } |
| | | if (userSetting.getDeviceStatusNotify()) { |
| | | // åéredisæ¶æ¯ |
| | | redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), channel.getChannelId(), true); |
| | | } |
| | | |
| | | break; |
| | | case CatalogEvent.OFF : |
| | | // 离线 |
| | | logger.info("[æ¶å°éé离线éç¥] æ¥èªè®¾å¤: {}, éé {}", device.getDeviceId(), channel.getChannelId()); |
| | | if (userSetting.getRefuseChannelStatusChannelFormNotify()) { |
| | | logger.info("[æ¶å°éé离线éç¥] 使¯å¹³å°å·²é
ç½®æç»æ¤æ¶æ¯ï¼æ¥èªè®¾å¤: {}, éé {}", device.getDeviceId(), channel.getChannelId()); |
| | | }else { |
| | | updateChannelOfflineList.add(channel); |
| | | if (updateChannelOfflineList.size() > 300) { |
| | | executeSaveForOffline(); |
| | | } |
| | | if (userSetting.getDeviceStatusNotify()) { |
| | | // åéredisæ¶æ¯ |
| | | redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), channel.getChannelId(), false); |
| | | } |
| | | } |
| | | break; |
| | | case CatalogEvent.VLOST: |
| | | // è§é¢ä¸¢å¤± |
| | | logger.info("[æ¶å°ééè§é¢ä¸¢å¤±éç¥] æ¥èªè®¾å¤: {}, éé {}", device.getDeviceId(), channel.getChannelId()); |
| | | if (userSetting.getRefuseChannelStatusChannelFormNotify()) { |
| | | logger.info("[æ¶å°ééè§é¢ä¸¢å¤±éç¥] 使¯å¹³å°å·²é
ç½®æç»æ¤æ¶æ¯ï¼æ¥èªè®¾å¤: {}, éé {}", device.getDeviceId(), channel.getChannelId()); |
| | | }else { |
| | | updateChannelOfflineList.add(channel); |
| | | if (updateChannelOfflineList.size() > 300) { |
| | | executeSaveForOffline(); |
| | | } |
| | | if (userSetting.getDeviceStatusNotify()) { |
| | | // åéredisæ¶æ¯ |
| | | redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), channel.getChannelId(), false); |
| | | } |
| | | } |
| | | break; |
| | | case CatalogEvent.DEFECT: |
| | | // æ
é |
| | | logger.info("[æ¶å°ééè§é¢æ
ééç¥] æ¥èªè®¾å¤: {}, éé {}", device.getDeviceId(), channel.getChannelId()); |
| | | if (userSetting.getRefuseChannelStatusChannelFormNotify()) { |
| | | logger.info("[æ¶å°ééè§é¢æ
ééç¥] 使¯å¹³å°å·²é
ç½®æç»æ¤æ¶æ¯ï¼æ¥èªè®¾å¤: {}, éé {}", device.getDeviceId(), channel.getChannelId()); |
| | | }else { |
| | | updateChannelOfflineList.add(channel); |
| | | if (updateChannelOfflineList.size() > 300) { |
| | | executeSaveForOffline(); |
| | | } |
| | | if (userSetting.getDeviceStatusNotify()) { |
| | | // åéredisæ¶æ¯ |
| | | redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), channel.getChannelId(), false); |
| | | } |
| | | } |
| | | break; |
| | | case CatalogEvent.ADD: |
| | | // å¢å |
| | | logger.info("[æ¶å°å¢å éééç¥] æ¥èªè®¾å¤: {}, éé {}", device.getDeviceId(), channel.getChannelId()); |
| | | // 夿æ¤é鿝å¦åå¨ |
| | | DeviceChannel deviceChannel = deviceChannelService.getOne(deviceId, channel.getChannelId()); |
| | | if (deviceChannel != null) { |
| | | logger.info("[å¢å éé] å·²åå¨ï¼ä¸åééç¥åªæ´æ°ï¼è®¾å¤: {}, éé {}", device.getDeviceId(), channel.getChannelId()); |
| | | channel.setId(deviceChannel.getId()); |
| | | updateChannelMap.put(channel.getChannelId(), channel); |
| | | if (updateChannelMap.keySet().size() > 300) { |
| | | executeSaveForUpdate(); |
| | | } |
| | | }else { |
| | | addChannelMap.put(channel.getChannelId(), channel); |
| | | if (userSetting.getDeviceStatusNotify()) { |
| | | // åéredisæ¶æ¯ |
| | | redisCatchStorage.sendChannelAddOrDelete(device.getDeviceId(), channel.getChannelId(), true); |
| | | } |
| | | |
| | | if (addChannelMap.keySet().size() > 300) { |
| | | executeSaveForAdd(); |
| | | } |
| | | } |
| | | |
| | | break; |
| | | case CatalogEvent.DEL: |
| | | // å é¤ |
| | | logger.info("[æ¶å°å é¤éééç¥] æ¥èªè®¾å¤: {}, éé {}", device.getDeviceId(), channel.getChannelId()); |
| | | deleteChannelList.add(channel); |
| | | if (userSetting.getDeviceStatusNotify()) { |
| | | // åéredisæ¶æ¯ |
| | | redisCatchStorage.sendChannelAddOrDelete(device.getDeviceId(), channel.getChannelId(), false); |
| | | } |
| | | if (deleteChannelList.size() > 300) { |
| | | executeSaveForDelete(); |
| | | } |
| | | break; |
| | | case CatalogEvent.UPDATE: |
| | | // æ´æ° |
| | | logger.info("[æ¶å°æ´æ°éééç¥] æ¥èªè®¾å¤: {}, éé {}", device.getDeviceId(), channel.getChannelId()); |
| | | // 夿æ¤é鿝å¦åå¨ |
| | | DeviceChannel deviceChannelForUpdate = deviceChannelService.getOne(deviceId, channel.getChannelId()); |
| | | if (deviceChannelForUpdate != null) { |
| | | channel.setId(deviceChannelForUpdate.getId()); |
| | | channel.setUpdateTime(DateUtil.getNow()); |
| | | updateChannelMap.put(channel.getChannelId(), channel); |
| | | if (updateChannelMap.keySet().size() > 300) { |
| | | executeSaveForUpdate(); |
| | | } |
| | | }else { |
| | | addChannelMap.put(channel.getChannelId(), channel); |
| | | if (addChannelMap.keySet().size() > 300) { |
| | | executeSaveForAdd(); |
| | | } |
| | | if (userSetting.getDeviceStatusNotify()) { |
| | | // åéredisæ¶æ¯ |
| | | redisCatchStorage.sendChannelAddOrDelete(device.getDeviceId(), channel.getChannelId(), true); |
| | | } |
| | | } |
| | | break; |
| | | default: |
| | | logger.warn("[ NotifyCatalog ] event not found ï¼ {}", event ); |
| | | |
| | | } |
| | | // 转åååä¿¡æ¯ |
| | | eventPublisher.catalogEventPublish(null, channel, event); |
| | | |
| | | if (!updateChannelMap.keySet().isEmpty() |
| | | || !addChannelMap.keySet().isEmpty() |
| | | || !updateChannelOnlineList.isEmpty() |
| | | || !updateChannelOfflineList.isEmpty() |
| | | || !deleteChannelList.isEmpty()) { |
| | | |
| | | if (!dynamicTask.contains(talkKey)) { |
| | | dynamicTask.startDelay(talkKey, this::executeSave, 1000); |
| | | // éåDeviceList |
| | | while (deviceListIterator.hasNext()) { |
| | | Element itemDevice = deviceListIterator.next(); |
| | | Element eventElement = itemDevice.element("Event"); |
| | | String event; |
| | | if (eventElement == null) { |
| | | logger.warn("[æ¶å°ç®å½è®¢é
]ï¼{}, 使¯Event为空, 设为é»è®¤å¼ ADD", (device != null ? device.getDeviceId():"" )); |
| | | event = CatalogEvent.ADD; |
| | | }else { |
| | | event = eventElement.getText().toUpperCase(); |
| | | } |
| | | DeviceChannel channel = XmlUtil.channelContentHandler(itemDevice, device, event); |
| | | if (channel == null) { |
| | | logger.info("[æ¶å°ç®å½è®¢é
]ï¼ä½æ¯è§£æå¤±è´¥ {}", new String(evt.getRequest().getRawContent())); |
| | | continue; |
| | | } |
| | | if (channel.getParentId() != null && channel.getParentId().equals(sipConfig.getId())) { |
| | | channel.setParentId(null); |
| | | } |
| | | channel.setDeviceId(device.getDeviceId()); |
| | | logger.info("[æ¶å°ç®å½è®¢é
]ï¼{}, {}/{}",event, device.getDeviceId(), channel.getChannelId()); |
| | | switch (event) { |
| | | case CatalogEvent.ON: |
| | | // ä¸çº¿ |
| | | deviceChannelService.online(channel); |
| | | if (userSetting.getDeviceStatusNotify()) { |
| | | // åéredisæ¶æ¯ |
| | | redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), channel.getChannelId(), true); |
| | | } |
| | | |
| | | break; |
| | | case CatalogEvent.OFF : |
| | | case CatalogEvent.VLOST: |
| | | case CatalogEvent.DEFECT: |
| | | // 离线 |
| | | if (userSetting.getRefuseChannelStatusChannelFormNotify()) { |
| | | logger.info("[ç®å½è®¢é
] 离线 使¯å¹³å°å·²é
ç½®æç»æ¤æ¶æ¯ï¼æ¥èªè®¾å¤: {}, éé {}", device.getDeviceId(), channel.getChannelId()); |
| | | }else { |
| | | deviceChannelService.offline(channel); |
| | | if (userSetting.getDeviceStatusNotify()) { |
| | | // åéredisæ¶æ¯ |
| | | redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), channel.getChannelId(), false); |
| | | } |
| | | } |
| | | break; |
| | | case CatalogEvent.DEL: |
| | | // å é¤ |
| | | deviceChannelService.delete(channel); |
| | | if (userSetting.getDeviceStatusNotify()) { |
| | | // åéredisæ¶æ¯ |
| | | redisCatchStorage.sendChannelAddOrDelete(device.getDeviceId(), channel.getChannelId(), false); |
| | | } |
| | | break; |
| | | case CatalogEvent.ADD: |
| | | case CatalogEvent.UPDATE: |
| | | // æ´æ° |
| | | channel.setUpdateTime(DateUtil.getNow()); |
| | | deviceChannelService.updateChannel(deviceId,channel); |
| | | if (userSetting.getDeviceStatusNotify()) { |
| | | // åéredisæ¶æ¯ |
| | | redisCatchStorage.sendChannelAddOrDelete(device.getDeviceId(), channel.getChannelId(), true); |
| | | } |
| | | break; |
| | | default: |
| | | logger.warn("[ NotifyCatalog ] event not found ï¼ {}", event ); |
| | | |
| | | } |
| | | // 转åååä¿¡æ¯ |
| | | eventPublisher.catalogEventPublish(null, channel, event); |
| | | } |
| | | } |
| | | } catch (DocumentException e) { |
| | | logger.error("æªå¤ççå¼å¸¸ ", e); |
| | | } |
| | | } catch (DocumentException e) { |
| | | logger.error("æªå¤ççå¼å¸¸ ", e); |
| | | } |
| | | } |
| | | |
| | | private void executeSave(){ |
| | | try { |
| | | executeSaveForAdd(); |
| | | } catch (Exception e) { |
| | | logger.error("[å卿¶å°çå¢å éé] å¼å¸¸ï¼ ", e ); |
| | | } |
| | | try { |
| | | executeSaveForUpdate(); |
| | | } catch (Exception e) { |
| | | logger.error("[å卿¶å°çæ´æ°éé] å¼å¸¸ï¼ ", e ); |
| | | } |
| | | try { |
| | | executeSaveForDelete(); |
| | | } catch (Exception e) { |
| | | logger.error("[å卿¶å°çå é¤éé] å¼å¸¸ï¼ ", e ); |
| | | } |
| | | try { |
| | | executeSaveForOnline(); |
| | | } catch (Exception e) { |
| | | logger.error("[å卿¶å°çééä¸çº¿] å¼å¸¸ï¼ ", e ); |
| | | } |
| | | try { |
| | | executeSaveForOffline(); |
| | | } catch (Exception e) { |
| | | logger.error("[å卿¶å°çéé离线] å¼å¸¸ï¼ ", e ); |
| | | } |
| | | dynamicTask.stop(talkKey); |
| | | } |
| | | |
| | | private void executeSaveForUpdate(){ |
| | | if (!updateChannelMap.values().isEmpty()) { |
| | | ArrayList<DeviceChannel> deviceChannels = new ArrayList<>(updateChannelMap.values()); |
| | | updateChannelMap.clear(); |
| | | deviceChannelService.batchUpdateChannel(deviceChannels); |
| | | } |
| | | |
| | | } |
| | | |
| | | private void executeSaveForAdd(){ |
| | | if (!addChannelMap.values().isEmpty()) { |
| | | ArrayList<DeviceChannel> deviceChannels = new ArrayList<>(addChannelMap.values()); |
| | | addChannelMap.clear(); |
| | | deviceChannelService.batchAddChannel(deviceChannels); |
| | | } |
| | | } |
| | | |
| | | private void executeSaveForDelete(){ |
| | | if (!deleteChannelList.isEmpty()) { |
| | | deviceChannelService.deleteChannels(deleteChannelList); |
| | | deleteChannelList.clear(); |
| | | } |
| | | } |
| | | |
| | | private void executeSaveForOnline(){ |
| | | if (!updateChannelOnlineList.isEmpty()) { |
| | | deviceChannelService.channelsOnline(updateChannelOnlineList); |
| | | updateChannelOnlineList.clear(); |
| | | } |
| | | } |
| | | |
| | | private void executeSaveForOffline(){ |
| | | if (!updateChannelOfflineList.isEmpty()) { |
| | | deviceChannelService.channelsOffline(updateChannelOfflineList); |
| | | updateChannelOfflineList.clear(); |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; |
| | | |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import com.genersoft.iot.vmp.conf.UserSetting; |
| | | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| | | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| | | import com.genersoft.iot.vmp.gb28181.bean.MobilePosition; |
| | | import com.genersoft.iot.vmp.gb28181.event.EventPublisher; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; |
| | | import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; |
| | | import com.genersoft.iot.vmp.gb28181.utils.SipUtils; |
| | | import com.genersoft.iot.vmp.service.IDeviceChannelService; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | | import com.genersoft.iot.vmp.utils.DateUtil; |
| | | import org.dom4j.DocumentException; |
| | | import org.dom4j.Element; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.ObjectUtils; |
| | | |
| | | import javax.sip.RequestEvent; |
| | | import javax.sip.header.FromHeader; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | |
| | | /** |
| | | * SIPå½ä»¤ç±»åï¼ NOTIFY请æ±ä¸çç§»å¨ä½ç½®è¯·æ±å¤ç |
| | | */ |
| | | @Component |
| | | public class NotifyRequestForMobilePositionProcessor extends SIPRequestProcessorParent { |
| | | |
| | | |
| | | private final static Logger logger = LoggerFactory.getLogger(NotifyRequestForMobilePositionProcessor.class); |
| | | |
| | | |
| | | @Autowired |
| | | private UserSetting userSetting; |
| | | |
| | | @Autowired |
| | | private EventPublisher eventPublisher; |
| | | |
| | | @Autowired |
| | | private IRedisCatchStorage redisCatchStorage; |
| | | |
| | | @Autowired |
| | | private IDeviceChannelService deviceChannelService; |
| | | |
| | | @Transactional |
| | | public void process(List<RequestEvent> eventList) { |
| | | if (eventList.isEmpty()) { |
| | | return; |
| | | } |
| | | Map<String, DeviceChannel> updateChannelMap = new ConcurrentHashMap<>(); |
| | | List<MobilePosition> addMobilePositionList = new ArrayList<>(); |
| | | for (RequestEvent evt : eventList) { |
| | | try { |
| | | FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME); |
| | | String deviceId = SipUtils.getUserIdFromFromHeader(fromHeader); |
| | | long startTime = System.currentTimeMillis(); |
| | | // åå¤ 200 OK |
| | | Element rootElement = getRootElement(evt); |
| | | if (rootElement == null) { |
| | | logger.error("å¤çMobilePositionç§»å¨ä½ç½®Notifyæ¶æªè·åå°æ¶æ¯ä½,{}", evt.getRequest()); |
| | | return; |
| | | } |
| | | Device device = redisCatchStorage.getDevice(deviceId); |
| | | if (device == null) { |
| | | logger.error("å¤çMobilePositionç§»å¨ä½ç½®Notifyæ¶æªè·åå°device,{}", deviceId); |
| | | return; |
| | | } |
| | | MobilePosition mobilePosition = new MobilePosition(); |
| | | mobilePosition.setDeviceId(device.getDeviceId()); |
| | | mobilePosition.setDeviceName(device.getName()); |
| | | mobilePosition.setCreateTime(DateUtil.getNow()); |
| | | List<Element> elements = rootElement.elements(); |
| | | for (Element element : elements) { |
| | | switch (element.getName()){ |
| | | case "DeviceID": |
| | | String channelId = element.getStringValue(); |
| | | if (!deviceId.equals(channelId)) { |
| | | mobilePosition.setChannelId(channelId); |
| | | } |
| | | continue; |
| | | case "Time": |
| | | String timeVal = element.getStringValue(); |
| | | if (ObjectUtils.isEmpty(timeVal)) { |
| | | mobilePosition.setTime(DateUtil.getNow()); |
| | | } else { |
| | | mobilePosition.setTime(SipUtils.parseTime(timeVal)); |
| | | } |
| | | continue; |
| | | case "Longitude": |
| | | mobilePosition.setLongitude(Double.parseDouble(element.getStringValue())); |
| | | continue; |
| | | case "Latitude": |
| | | mobilePosition.setLatitude(Double.parseDouble(element.getStringValue())); |
| | | continue; |
| | | case "Speed": |
| | | String speedVal = element.getStringValue(); |
| | | if (NumericUtil.isDouble(speedVal)) { |
| | | mobilePosition.setSpeed(Double.parseDouble(speedVal)); |
| | | } else { |
| | | mobilePosition.setSpeed(0.0); |
| | | } |
| | | continue; |
| | | case "Direction": |
| | | String directionVal = element.getStringValue(); |
| | | if (NumericUtil.isDouble(directionVal)) { |
| | | mobilePosition.setDirection(Double.parseDouble(directionVal)); |
| | | } else { |
| | | mobilePosition.setDirection(0.0); |
| | | } |
| | | continue; |
| | | case "Altitude": |
| | | String altitudeVal = element.getStringValue(); |
| | | if (NumericUtil.isDouble(altitudeVal)) { |
| | | mobilePosition.setAltitude(Double.parseDouble(altitudeVal)); |
| | | } else { |
| | | mobilePosition.setAltitude(0.0); |
| | | } |
| | | continue; |
| | | |
| | | } |
| | | } |
| | | |
| | | // logger.info("[æ¶å°ç§»å¨ä½ç½®è®¢é
éç¥]ï¼{}/{}->{}.{}, æ¶é´ï¼ {}", mobilePosition.getDeviceId(), mobilePosition.getChannelId(), |
| | | // mobilePosition.getLongitude(), mobilePosition.getLatitude(), System.currentTimeMillis() - startTime); |
| | | mobilePosition.setReportSource("Mobile Position"); |
| | | |
| | | // æ´æ°device channel çç»çº¬åº¦ |
| | | DeviceChannel deviceChannel = new DeviceChannel(); |
| | | deviceChannel.setDeviceId(device.getDeviceId()); |
| | | deviceChannel.setLongitude(mobilePosition.getLongitude()); |
| | | deviceChannel.setLatitude(mobilePosition.getLatitude()); |
| | | deviceChannel.setGpsTime(mobilePosition.getTime()); |
| | | updateChannelMap.put(deviceId + mobilePosition.getChannelId(), deviceChannel); |
| | | addMobilePositionList.add(mobilePosition); |
| | | |
| | | |
| | | // åå
³èäºè¯¥ééå¹¶ä¸å¼å¯ç§»å¨ä½ç½®è®¢é
çä¸çº§å¹³å°åéç§»å¨ä½ç½®è®¢é
æ¶æ¯ |
| | | try { |
| | | eventPublisher.mobilePositionEventPublish(mobilePosition); |
| | | }catch (Exception e) { |
| | | logger.error("[åä¸çº§è½¬åç§»å¨ä½ç½®å¤±è´¥] ", e); |
| | | } |
| | | if (mobilePosition.getChannelId().equals(mobilePosition.getDeviceId()) || mobilePosition.getChannelId() == null) { |
| | | List<DeviceChannel> channels = deviceChannelService.queryChaneListByDeviceId(mobilePosition.getDeviceId()); |
| | | channels.forEach(channel -> { |
| | | // åéredisæ¶æ¯ã éç¥ä½ç½®ä¿¡æ¯çåå |
| | | JSONObject jsonObject = new JSONObject(); |
| | | jsonObject.put("time", DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(mobilePosition.getTime())); |
| | | jsonObject.put("serial", channel.getDeviceId()); |
| | | jsonObject.put("code", channel.getChannelId()); |
| | | jsonObject.put("longitude", mobilePosition.getLongitude()); |
| | | jsonObject.put("latitude", mobilePosition.getLatitude()); |
| | | jsonObject.put("altitude", mobilePosition.getAltitude()); |
| | | jsonObject.put("direction", mobilePosition.getDirection()); |
| | | jsonObject.put("speed", mobilePosition.getSpeed()); |
| | | redisCatchStorage.sendMobilePositionMsg(jsonObject); |
| | | }); |
| | | }else { |
| | | // åéredisæ¶æ¯ã éç¥ä½ç½®ä¿¡æ¯çåå |
| | | JSONObject jsonObject = new JSONObject(); |
| | | jsonObject.put("time", DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(mobilePosition.getTime())); |
| | | jsonObject.put("serial", mobilePosition.getDeviceId()); |
| | | jsonObject.put("code", mobilePosition.getChannelId()); |
| | | jsonObject.put("longitude", mobilePosition.getLongitude()); |
| | | jsonObject.put("latitude", mobilePosition.getLatitude()); |
| | | jsonObject.put("altitude", mobilePosition.getAltitude()); |
| | | jsonObject.put("direction", mobilePosition.getDirection()); |
| | | jsonObject.put("speed", mobilePosition.getSpeed()); |
| | | redisCatchStorage.sendMobilePositionMsg(jsonObject); |
| | | } |
| | | } catch (DocumentException e) { |
| | | logger.error("æªå¤ççå¼å¸¸ ", e); |
| | | } |
| | | } |
| | | if(!updateChannelMap.isEmpty()) { |
| | | List<DeviceChannel> channels = new ArrayList<>(updateChannelMap.values()); |
| | | logger.info("[ç§»å¨ä½ç½®è®¢é
]æ´æ°ééä½ç½®ï¼ {}", channels.size()); |
| | | deviceChannelService.batchUpdateChannelGPS(channels); |
| | | updateChannelMap.clear(); |
| | | } |
| | | if (userSetting.isSavePositionHistory() && !addMobilePositionList.isEmpty()) { |
| | | try { |
| | | logger.info("[ç§»å¨ä½ç½®è®¢é
] æ·»å éé轨迹ç¹ä½ï¼ {}", addMobilePositionList.size()); |
| | | deviceChannelService.batchAddMobilePosition(addMobilePositionList); |
| | | }catch (Exception e) { |
| | | logger.info("[ç§»å¨ä½ç½®è®¢é
] bæ·»å éé轨迹ç¹ä½ä¿åå¤±è´¥ï¼ {}", addMobilePositionList.size()); |
| | | } |
| | | addMobilePositionList.clear(); |
| | | } |
| | | } |
| | | } |
| | |
| | | import org.springframework.beans.factory.InitializingBean; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Qualifier; |
| | | import org.springframework.scheduling.annotation.Async; |
| | | import org.springframework.scheduling.annotation.Scheduled; |
| | | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.util.ObjectUtils; |
| | |
| | | import javax.sip.header.FromHeader; |
| | | import javax.sip.message.Response; |
| | | import java.text.ParseException; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.concurrent.ConcurrentLinkedQueue; |
| | | |
| | |
| | | @Autowired |
| | | private NotifyRequestForCatalogProcessor notifyRequestForCatalogProcessor; |
| | | |
| | | @Autowired |
| | | private NotifyRequestForMobilePositionProcessor notifyRequestForMobilePositionProcessor; |
| | | |
| | | private ConcurrentLinkedQueue<HandlerCatchData> taskQueue = new ConcurrentLinkedQueue<>(); |
| | | |
| | | @Qualifier("taskExecutor") |
| | |
| | | responseAck((SIPRequest) evt.getRequest(), Response.BUSY_HERE, null, null); |
| | | logger.error("[notify] å¾
å¤çæ¶æ¯éå已满 {}ï¼è¿å486 BUSY_HEREï¼æ¶æ¯ä¸åå¤ç", userSetting.getMaxNotifyCountQueue()); |
| | | return; |
| | | }else { |
| | | } else { |
| | | responseAck((SIPRequest) evt.getRequest(), Response.OK, null, null); |
| | | } |
| | | |
| | | }catch (SipException | InvalidArgumentException | ParseException e) { |
| | | } catch (SipException | InvalidArgumentException | ParseException e) { |
| | | logger.error("æªå¤ççå¼å¸¸ ", e); |
| | | } |
| | | boolean runed = !taskQueue.isEmpty(); |
| | | logger.info("[notify] å¾
å¤çæ¶æ¯æ°éï¼ {}", taskQueue.size()); |
| | | taskQueue.offer(new HandlerCatchData(evt, null, null)); |
| | | if (!runed) { |
| | | taskExecutor.execute(()-> { |
| | | while (!taskQueue.isEmpty()) { |
| | | try { |
| | | HandlerCatchData take = taskQueue.poll(); |
| | | if (take == null) { |
| | | continue; |
| | | } |
| | | Element rootElement = getRootElement(take.getEvt()); |
| | | if (rootElement == null) { |
| | | logger.error("å¤çNOTIFYæ¶æ¯æ¶æªè·åå°æ¶æ¯ä½,{}", take.getEvt().getRequest()); |
| | | continue; |
| | | } |
| | | String cmd = XmlUtil.getText(rootElement, "CmdType"); |
| | | |
| | | if (CmdType.CATALOG.equals(cmd)) { |
| | | logger.info("æ¥æ¶å°Catalogéç¥"); |
| | | notifyRequestForCatalogProcessor.process(take.getEvt()); |
| | | } else if (CmdType.ALARM.equals(cmd)) { |
| | | logger.info("æ¥æ¶å°Alarméç¥"); |
| | | processNotifyAlarm(take.getEvt()); |
| | | } else if (CmdType.MOBILE_POSITION.equals(cmd)) { |
| | | logger.info("æ¥æ¶å°MobilePositionéç¥"); |
| | | processNotifyMobilePosition(take.getEvt()); |
| | | } else { |
| | | logger.info("æ¥æ¶å°æ¶æ¯ï¼" + cmd); |
| | | } |
| | | } catch (DocumentException e) { |
| | | logger.error("å¤çNOTIFYæ¶æ¯æ¶é误", e); |
| | | } |
| | | } |
| | | @Scheduled(fixedRate = 200) //æ¯200æ¯«ç§æ§è¡ä¸æ¬¡ |
| | | public void executeTaskQueue(){ |
| | | if (taskQueue.isEmpty()) { |
| | | return; |
| | | } |
| | | try { |
| | | List<RequestEvent> catalogEventList = new ArrayList<>(); |
| | | List<RequestEvent> alarmEventList = new ArrayList<>(); |
| | | List<RequestEvent> mobilePositionEventList = new ArrayList<>(); |
| | | for (HandlerCatchData take : taskQueue) { |
| | | if (take == null) { |
| | | continue; |
| | | } |
| | | }); |
| | | Element rootElement = getRootElement(take.getEvt()); |
| | | if (rootElement == null) { |
| | | logger.error("å¤çNOTIFYæ¶æ¯æ¶æªè·åå°æ¶æ¯ä½,{}", take.getEvt().getRequest()); |
| | | continue; |
| | | } |
| | | String cmd = XmlUtil.getText(rootElement, "CmdType"); |
| | | |
| | | if (CmdType.CATALOG.equals(cmd)) { |
| | | catalogEventList.add(take.getEvt()); |
| | | } else if (CmdType.ALARM.equals(cmd)) { |
| | | alarmEventList.add(take.getEvt()); |
| | | } else if (CmdType.MOBILE_POSITION.equals(cmd)) { |
| | | mobilePositionEventList.add(take.getEvt()); |
| | | } else { |
| | | logger.info("æ¥æ¶å°æ¶æ¯ï¼" + cmd); |
| | | } |
| | | } |
| | | taskQueue.clear(); |
| | | if (!alarmEventList.isEmpty()) { |
| | | processNotifyAlarm(alarmEventList); |
| | | } |
| | | if (!catalogEventList.isEmpty()) { |
| | | notifyRequestForCatalogProcessor.process(catalogEventList); |
| | | } |
| | | if (!mobilePositionEventList.isEmpty()) { |
| | | notifyRequestForMobilePositionProcessor.process(mobilePositionEventList); |
| | | } |
| | | } catch (DocumentException e) { |
| | | logger.error("å¤çNOTIFYæ¶æ¯æ¶é误", e); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * å¤çMobilePositionç§»å¨ä½ç½®Notify |
| | | * |
| | | * @param evt |
| | | */ |
| | | private void processNotifyMobilePosition(RequestEvent evt) { |
| | | @Async("taskExecutor") |
| | | public void processNotifyMobilePosition(RequestEvent evt) { |
| | | try { |
| | | FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME); |
| | | String deviceId = SipUtils.getUserIdFromFromHeader(fromHeader); |
| | | |
| | | // åå¤ 200 OK |
| | | Element rootElement = getRootElement(evt); |
| | | if (rootElement == null) { |
| | |
| | | if (device == null) { |
| | | logger.warn("[mobilePositionç§»å¨ä½ç½®Notify] æªæ¾å°éé{}æå±ç设å¤", channelId); |
| | | return; |
| | | } |
| | | // å
¼å®¹è®¾å¤é¨å设å¤ä¸æ¥æ¯ééç¼å·ä¸è®¾å¤ç¼å·ä¸è´çæ
åµ |
| | | if(deviceId.equals(channelId)) { |
| | | List<DeviceChannel> deviceChannels = deviceChannelService.queryChaneListByDeviceId(deviceId); |
| | | if (deviceChannels.size() == 1) { |
| | | channelId = deviceChannels.get(0).getChannelId(); |
| | | } |
| | | } |
| | | if (!ObjectUtils.isEmpty(device.getName())) { |
| | | mobilePosition.setDeviceName(device.getName()); |
| | |
| | | } else { |
| | | mobilePosition.setAltitude(0.0); |
| | | } |
| | | logger.info("[æ¶å°ç§»å¨ä½ç½®è®¢é
éç¥]ï¼{}/{}->{}.{}", mobilePosition.getDeviceId(), mobilePosition.getChannelId(), |
| | | mobilePosition.getLongitude(), mobilePosition.getLatitude()); |
| | | // logger.info("[æ¶å°ç§»å¨ä½ç½®è®¢é
éç¥]ï¼{}/{}->{}.{}", mobilePosition.getDeviceId(), mobilePosition.getChannelId(), |
| | | // mobilePosition.getLongitude(), mobilePosition.getLatitude()); |
| | | mobilePosition.setReportSource("Mobile Position"); |
| | | |
| | | // æ´æ°device channel çç»çº¬åº¦ |
| | |
| | | deviceChannel.setLongitude(mobilePosition.getLongitude()); |
| | | deviceChannel.setLatitude(mobilePosition.getLatitude()); |
| | | deviceChannel.setGpsTime(mobilePosition.getTime()); |
| | | deviceChannel = deviceChannelService.updateGps(deviceChannel, device); |
| | | |
| | | mobilePosition.setLongitudeWgs84(deviceChannel.getLongitudeWgs84()); |
| | | mobilePosition.setLatitudeWgs84(deviceChannel.getLatitudeWgs84()); |
| | | mobilePosition.setLongitudeGcj02(deviceChannel.getLongitudeGcj02()); |
| | | mobilePosition.setLatitudeGcj02(deviceChannel.getLatitudeGcj02()); |
| | | // deviceChannel = deviceChannelService.updateGps(deviceChannel, device); |
| | | // |
| | | // mobilePosition.setLongitudeWgs84(deviceChannel.getLongitudeWgs84()); |
| | | // mobilePosition.setLatitudeWgs84(deviceChannel.getLatitudeWgs84()); |
| | | // mobilePosition.setLongitudeGcj02(deviceChannel.getLongitudeGcj02()); |
| | | // mobilePosition.setLatitudeGcj02(deviceChannel.getLatitudeGcj02()); |
| | | |
| | | deviceChannelService.updateChannelGPS(device, deviceChannel, mobilePosition); |
| | | |
| | |
| | | |
| | | /*** |
| | | * å¤çalarmè®¾å¤æ¥è¦Notify |
| | | * |
| | | * @param evt |
| | | */ |
| | | private void processNotifyAlarm(RequestEvent evt) { |
| | | private void processNotifyAlarm(List<RequestEvent> evtList) { |
| | | if (!sipConfig.isAlarm()) { |
| | | return; |
| | | } |
| | | try { |
| | | FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME); |
| | | String deviceId = SipUtils.getUserIdFromFromHeader(fromHeader); |
| | | if (!evtList.isEmpty()) { |
| | | for (RequestEvent evt : evtList) { |
| | | try { |
| | | FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME); |
| | | String deviceId = SipUtils.getUserIdFromFromHeader(fromHeader); |
| | | |
| | | Element rootElement = getRootElement(evt); |
| | | if (rootElement == null) { |
| | | logger.error("å¤çalarmè®¾å¤æ¥è¦Notifyæ¶æªè·åå°æ¶æ¯ä½{}", evt.getRequest()); |
| | | return; |
| | | } |
| | | Element deviceIdElement = rootElement.element("DeviceID"); |
| | | String channelId = deviceIdElement.getText().toString(); |
| | | Element rootElement = getRootElement(evt); |
| | | if (rootElement == null) { |
| | | logger.error("å¤çalarmè®¾å¤æ¥è¦Notifyæ¶æªè·åå°æ¶æ¯ä½{}", evt.getRequest()); |
| | | return; |
| | | } |
| | | Element deviceIdElement = rootElement.element("DeviceID"); |
| | | String channelId = deviceIdElement.getText().toString(); |
| | | |
| | | Device device = redisCatchStorage.getDevice(deviceId); |
| | | if (device == null) { |
| | | logger.warn("[ NotifyAlarm ] æªæ¾å°è®¾å¤ï¼{}", deviceId); |
| | | return; |
| | | } |
| | | rootElement = getRootElement(evt, device.getCharset()); |
| | | if (rootElement == null) { |
| | | logger.warn("[ NotifyAlarm ] content cannot be null, {}", evt.getRequest()); |
| | | return; |
| | | } |
| | | DeviceAlarm deviceAlarm = new DeviceAlarm(); |
| | | deviceAlarm.setDeviceId(deviceId); |
| | | deviceAlarm.setAlarmPriority(XmlUtil.getText(rootElement, "AlarmPriority")); |
| | | deviceAlarm.setAlarmMethod(XmlUtil.getText(rootElement, "AlarmMethod")); |
| | | String alarmTime = XmlUtil.getText(rootElement, "AlarmTime"); |
| | | if (alarmTime == null) { |
| | | logger.warn("[ NotifyAlarm ] AlarmTime cannot be null"); |
| | | return; |
| | | } |
| | | deviceAlarm.setAlarmTime(DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(alarmTime)); |
| | | if (XmlUtil.getText(rootElement, "AlarmDescription") == null) { |
| | | deviceAlarm.setAlarmDescription(""); |
| | | } else { |
| | | deviceAlarm.setAlarmDescription(XmlUtil.getText(rootElement, "AlarmDescription")); |
| | | } |
| | | if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Longitude"))) { |
| | | deviceAlarm.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude"))); |
| | | } else { |
| | | deviceAlarm.setLongitude(0.00); |
| | | } |
| | | if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Latitude"))) { |
| | | deviceAlarm.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude"))); |
| | | } else { |
| | | deviceAlarm.setLatitude(0.00); |
| | | } |
| | | logger.info("[æ¶å°Notify-Alarm]ï¼{}/{}", device.getDeviceId(), deviceAlarm.getChannelId()); |
| | | if ("4".equals(deviceAlarm.getAlarmMethod())) { |
| | | MobilePosition mobilePosition = new MobilePosition(); |
| | | mobilePosition.setChannelId(channelId); |
| | | mobilePosition.setCreateTime(DateUtil.getNow()); |
| | | mobilePosition.setDeviceId(deviceAlarm.getDeviceId()); |
| | | mobilePosition.setTime(deviceAlarm.getAlarmTime()); |
| | | mobilePosition.setLongitude(deviceAlarm.getLongitude()); |
| | | mobilePosition.setLatitude(deviceAlarm.getLatitude()); |
| | | mobilePosition.setReportSource("GPS Alarm"); |
| | | Device device = redisCatchStorage.getDevice(deviceId); |
| | | if (device == null) { |
| | | logger.warn("[ NotifyAlarm ] æªæ¾å°è®¾å¤ï¼{}", deviceId); |
| | | return; |
| | | } |
| | | rootElement = getRootElement(evt, device.getCharset()); |
| | | if (rootElement == null) { |
| | | logger.warn("[ NotifyAlarm ] content cannot be null, {}", evt.getRequest()); |
| | | return; |
| | | } |
| | | DeviceAlarm deviceAlarm = new DeviceAlarm(); |
| | | deviceAlarm.setDeviceId(deviceId); |
| | | deviceAlarm.setAlarmPriority(XmlUtil.getText(rootElement, "AlarmPriority")); |
| | | deviceAlarm.setAlarmMethod(XmlUtil.getText(rootElement, "AlarmMethod")); |
| | | String alarmTime = XmlUtil.getText(rootElement, "AlarmTime"); |
| | | if (alarmTime == null) { |
| | | logger.warn("[ NotifyAlarm ] AlarmTime cannot be null"); |
| | | return; |
| | | } |
| | | deviceAlarm.setAlarmTime(DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(alarmTime)); |
| | | if (XmlUtil.getText(rootElement, "AlarmDescription") == null) { |
| | | deviceAlarm.setAlarmDescription(""); |
| | | } else { |
| | | deviceAlarm.setAlarmDescription(XmlUtil.getText(rootElement, "AlarmDescription")); |
| | | } |
| | | if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Longitude"))) { |
| | | deviceAlarm.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude"))); |
| | | } else { |
| | | deviceAlarm.setLongitude(0.00); |
| | | } |
| | | if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Latitude"))) { |
| | | deviceAlarm.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude"))); |
| | | } else { |
| | | deviceAlarm.setLatitude(0.00); |
| | | } |
| | | logger.info("[æ¶å°Notify-Alarm]ï¼{}/{}", device.getDeviceId(), deviceAlarm.getChannelId()); |
| | | if ("4".equals(deviceAlarm.getAlarmMethod())) { |
| | | MobilePosition mobilePosition = new MobilePosition(); |
| | | mobilePosition.setChannelId(channelId); |
| | | mobilePosition.setCreateTime(DateUtil.getNow()); |
| | | mobilePosition.setDeviceId(deviceAlarm.getDeviceId()); |
| | | mobilePosition.setTime(deviceAlarm.getAlarmTime()); |
| | | mobilePosition.setLongitude(deviceAlarm.getLongitude()); |
| | | mobilePosition.setLatitude(deviceAlarm.getLatitude()); |
| | | mobilePosition.setReportSource("GPS Alarm"); |
| | | |
| | | // æ´æ°device channel çç»çº¬åº¦ |
| | | DeviceChannel deviceChannel = new DeviceChannel(); |
| | | deviceChannel.setDeviceId(device.getDeviceId()); |
| | | deviceChannel.setChannelId(channelId); |
| | | deviceChannel.setLongitude(mobilePosition.getLongitude()); |
| | | deviceChannel.setLatitude(mobilePosition.getLatitude()); |
| | | deviceChannel.setGpsTime(mobilePosition.getTime()); |
| | | // æ´æ°device channel çç»çº¬åº¦ |
| | | DeviceChannel deviceChannel = new DeviceChannel(); |
| | | deviceChannel.setDeviceId(device.getDeviceId()); |
| | | deviceChannel.setChannelId(channelId); |
| | | deviceChannel.setLongitude(mobilePosition.getLongitude()); |
| | | deviceChannel.setLatitude(mobilePosition.getLatitude()); |
| | | deviceChannel.setGpsTime(mobilePosition.getTime()); |
| | | |
| | | deviceChannel = deviceChannelService.updateGps(deviceChannel, device); |
| | | deviceChannel = deviceChannelService.updateGps(deviceChannel, device); |
| | | |
| | | mobilePosition.setLongitudeWgs84(deviceChannel.getLongitudeWgs84()); |
| | | mobilePosition.setLatitudeWgs84(deviceChannel.getLatitudeWgs84()); |
| | | mobilePosition.setLongitudeGcj02(deviceChannel.getLongitudeGcj02()); |
| | | mobilePosition.setLatitudeGcj02(deviceChannel.getLatitudeGcj02()); |
| | | mobilePosition.setLongitudeWgs84(deviceChannel.getLongitudeWgs84()); |
| | | mobilePosition.setLatitudeWgs84(deviceChannel.getLatitudeWgs84()); |
| | | mobilePosition.setLongitudeGcj02(deviceChannel.getLongitudeGcj02()); |
| | | mobilePosition.setLatitudeGcj02(deviceChannel.getLatitudeGcj02()); |
| | | |
| | | deviceChannelService.updateChannelGPS(device, deviceChannel, mobilePosition); |
| | | deviceChannelService.updateChannelGPS(device, deviceChannel, mobilePosition); |
| | | } |
| | | |
| | | // åå¤200 OK |
| | | if (redisCatchStorage.deviceIsOnline(deviceId)) { |
| | | publisher.deviceAlarmEventPublish(deviceAlarm); |
| | | } |
| | | } catch (DocumentException e) { |
| | | logger.error("æªå¤ççå¼å¸¸ ", e); |
| | | } |
| | | } |
| | | |
| | | // åå¤200 OK |
| | | if (redisCatchStorage.deviceIsOnline(deviceId)) { |
| | | publisher.deviceAlarmEventPublish(deviceAlarm); |
| | | } |
| | | } catch (DocumentException e) { |
| | | logger.error("æªå¤ççå¼å¸¸ ", e); |
| | | } |
| | | } |
| | | |
| | |
| | | public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) { |
| | | this.redisCatchStorage = redisCatchStorage; |
| | | } |
| | | |
| | | @Scheduled(fixedRate = 10000) //æ¯1ç§æ§è¡ä¸æ¬¡ |
| | | public void execute(){ |
| | | logger.info("[å¾
å¤çNotifyæ¶æ¯æ°é]: {}", taskQueue.size()); |
| | | } |
| | | } |
| | |
| | | String status = getText(itemDevice, "Status"); |
| | | if (status != null) { |
| | | // ONLINE OFFLINE HIKVISION DS-7716N-E4 NVRçå
¼å®¹æ§å¤ç |
| | | if (status.equals("ON") || status.equals("On") || status.equals("ONLINE") || status.equals("OK")) { |
| | | if (status.equalsIgnoreCase("ON") || status.equalsIgnoreCase("On") || status.equalsIgnoreCase("ONLINE") || status.equalsIgnoreCase("OK")) { |
| | | deviceChannel.setStatus(true); |
| | | } |
| | | if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) { |
| | | if (status.equalsIgnoreCase("OFF") || status.equalsIgnoreCase("Off") || status.equalsIgnoreCase("OFFLINE")) { |
| | | deviceChannel.setStatus(false); |
| | | } |
| | | }else { |
| | | deviceChannel.setStatus(true); |
| | | } |
| | | |
| | | // logger.info("ç¶æåç¬¦ä¸²ï¼ {}", status); |
| | | // logger.info("ç¶æç»æï¼ {}", deviceChannel.isStatus()); |
| | | // ç»åº¦ |
| | | String longitude = getText(itemDevice, "Longitude"); |
| | | if (NumericUtil.isDouble(longitude)) { |
| | |
| | | import com.genersoft.iot.vmp.conf.UserSetting;
|
| | | import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
| | | import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager;
|
| | | import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
|
| | | import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager;
|
| | | import com.genersoft.iot.vmp.gb28181.session.SSRCFactory;
|
| | | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
| | | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
| | |
| | | import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerKeepaliveEvent;
|
| | | import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerStartEvent;
|
| | | import com.genersoft.iot.vmp.service.*;
|
| | | import com.genersoft.iot.vmp.service.bean.SSRCInfo;
|
| | | import com.genersoft.iot.vmp.service.redisMsg.IRedisRpcService;
|
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
| | | import org.slf4j.Logger;
|
| | |
| | | @Autowired
|
| | | private IRedisCatchStorage redisCatchStorage;
|
| | |
|
| | |
|
| | | @Autowired
|
| | | private IRedisRpcService redisRpcService;
|
| | |
|
| | | @Autowired
|
| | | private IInviteStreamService inviteStreamService;
|
| | |
|
| | |
| | |
|
| | | @Autowired
|
| | | private EventPublisher eventPublisher;
|
| | |
|
| | | @Autowired
|
| | | private ZLMMediaListManager zlmMediaListManager;
|
| | |
|
| | | @Autowired
|
| | | private HookSubscribe subscribe;
|
| | |
| | |
|
| | | @Autowired
|
| | | private ApplicationEventPublisher applicationEventPublisher;
|
| | |
|
| | | @Autowired
|
| | | private IStreamPushService streamPushService;
|
| | |
|
| | | /**
|
| | | * æå¡å¨å®æ¶ä¸æ¥æ¶é´ï¼ä¸æ¥é´éå¯é
ç½®ï¼é»è®¤10s䏿¥ä¸æ¬¡
|
| | |
| | | if (mediaServer == null) {
|
| | | return new HookResultForOnPublish(0, "success");
|
| | | }
|
| | | // æ¨æµé´æçå¤ç
|
| | | if (!"rtp".equals(param.getApp())) {
|
| | | StreamProxyItem stream = streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream());
|
| | | if (stream != null) {
|
| | | HookResultForOnPublish result = HookResultForOnPublish.SUCCESS();
|
| | | result.setEnable_audio(stream.isEnableAudio());
|
| | | result.setEnable_mp4(stream.isEnableMp4());
|
| | | return result;
|
| | | }
|
| | | if (userSetting.getPushAuthority()) {
|
| | | // æ¨æµé´æ
|
| | | if (param.getParams() == null) {
|
| | | logger.info("æ¨æµé´æå¤±è´¥ï¼ 缺å°å¿
è¦åæ°ï¼sign=md5(user表çpushKey)");
|
| | | return new HookResultForOnPublish(401, "Unauthorized");
|
| | | }
|
| | | Map<String, String> paramMap = urlParamToMap(param.getParams());
|
| | | String sign = paramMap.get("sign");
|
| | | if (sign == null) {
|
| | | logger.info("æ¨æµé´æå¤±è´¥ï¼ 缺å°å¿
è¦åæ°ï¼sign=md5(user表çpushKey)");
|
| | | return new HookResultForOnPublish(401, "Unauthorized");
|
| | | }
|
| | | // æ¨æµèªå®ä¹ææ¾é´æç
|
| | | String callId = paramMap.get("callId");
|
| | | // é´æé
ç½®
|
| | | boolean hasAuthority = userService.checkPushAuthority(callId, sign);
|
| | | if (!hasAuthority) {
|
| | | logger.info("æ¨æµé´æå¤±è´¥ï¼ sign æ æé: callId={}. sign={}", callId, sign);
|
| | | return new HookResultForOnPublish(401, "Unauthorized");
|
| | | }
|
| | | StreamAuthorityInfo streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(param);
|
| | | streamAuthorityInfo.setCallId(callId);
|
| | | streamAuthorityInfo.setSign(sign);
|
| | | // é´æéè¿
|
| | | redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo);
|
| | | }
|
| | | } else {
|
| | | zlmMediaListManager.sendStreamEvent(param.getApp(), param.getStream(), param.getMediaServerId());
|
| | | }
|
| | |
|
| | |
|
| | | HookResultForOnPublish result = HookResultForOnPublish.SUCCESS();
|
| | | result.setEnable_audio(true);
|
| | | taskExecutor.execute(() -> {
|
| | | ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_publish, json);
|
| | | if (subscribe != null) {
|
| | | subscribe.response(mediaInfo, param);
|
| | | }
|
| | | });
|
| | |
|
| | | ResultForOnPublish resultForOnPublish = mediaService.authenticatePublish(mediaServer, param.getApp(), param.getStream(), param.getParams());
|
| | | if (resultForOnPublish != null) {
|
| | |
| | | MediaDepartureEvent mediaDepartureEvent = MediaDepartureEvent.getInstance(this, param, mediaServer);
|
| | | applicationEventPublisher.publishEvent(mediaDepartureEvent);
|
| | | }
|
| | |
|
| | | JSONObject json = (JSONObject) JSON.toJSON(param);
|
| | | taskExecutor.execute(() -> {
|
| | | ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_stream_changed, json);
|
| | | MediaServerItem mediaInfo = mediaServerService.getOne(param.getMediaServerId());
|
| | | if (mediaInfo == null) {
|
| | | logger.info("[ZLM HOOK] æµååæªæ¾å°ZLM, {}", param.getMediaServerId());
|
| | | return;
|
| | | }
|
| | | if (subscribe != null) {
|
| | | subscribe.response(mediaInfo, param);
|
| | | }
|
| | |
|
| | | List<OnStreamChangedHookParam.MediaTrack> tracks = param.getTracks();
|
| | | // TODO éææ¤å¤é»è¾
|
| | | if (param.isRegist()) {
|
| | | // å¤çæµæ³¨åçé´æä¿¡æ¯ï¼ æµæ³¨éè¿éä¸åå é¤é´æä¿¡æ¯ï¼ä¸æ¬¡æ¥äºæ°çé´æä¿¡æ¯ä¼å¯¹å°±çè¿è¡è¦ç
|
| | | if (param.getOriginType() == OriginType.RTMP_PUSH.ordinal()
|
| | | || param.getOriginType() == OriginType.RTSP_PUSH.ordinal()
|
| | | || param.getOriginType() == OriginType.RTC_PUSH.ordinal()) {
|
| | | StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(param.getApp(), param.getStream());
|
| | | if (streamAuthorityInfo == null) {
|
| | | streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(param);
|
| | | } else {
|
| | | streamAuthorityInfo.setOriginType(param.getOriginType());
|
| | | streamAuthorityInfo.setOriginTypeStr(param.getOriginTypeStr());
|
| | | }
|
| | | redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo);
|
| | | }
|
| | | }
|
| | | if ("rtsp".equals(param.getSchema())) {
|
| | | logger.info("æµååï¼æ³¨å->{}, app->{}, stream->{}", param.isRegist(), param.getApp(), param.getStream());
|
| | | if (param.isRegist()) {
|
| | | mediaServerService.addCount(param.getMediaServerId());
|
| | | } else {
|
| | | mediaServerService.removeCount(param.getMediaServerId());
|
| | | }
|
| | |
|
| | | int updateStatusResult = streamProxyService.updateStatus(param.isRegist(), param.getApp(), param.getStream());
|
| | | if (updateStatusResult > 0) {
|
| | |
|
| | | }
|
| | |
|
| | | if ("rtp".equals(param.getApp()) && !param.isRegist()) {
|
| | | InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, param.getStream());
|
| | | if (inviteInfo != null && (inviteInfo.getType() == InviteSessionType.PLAY || inviteInfo.getType() == InviteSessionType.PLAYBACK)) {
|
| | | inviteStreamService.removeInviteInfo(inviteInfo);
|
| | | storager.stopPlay(inviteInfo.getDeviceId(), inviteInfo.getChannelId());
|
| | | }
|
| | | } else if ("broadcast".equals(param.getApp())) {
|
| | | // è¯é³å¯¹è®²æ¨æµ streaméè¦æ»¡è¶³æ ¼å¼deviceId_channelId
|
| | | if (param.getStream().indexOf("_") > 0) {
|
| | | String[] streamArray = param.getStream().split("_");
|
| | | if (streamArray.length == 2) {
|
| | | String deviceId = streamArray[0];
|
| | | String channelId = streamArray[1];
|
| | | Device device = deviceService.getDevice(deviceId);
|
| | | if (device != null) {
|
| | | if (param.isRegist()) {
|
| | | if (audioBroadcastManager.exit(deviceId, channelId)) {
|
| | | playService.stopAudioBroadcast(deviceId, channelId);
|
| | | }
|
| | | // å¼å¯è¯é³å¯¹è®²éé
|
| | | try {
|
| | | playService.audioBroadcastCmd(device, channelId, mediaInfo, param.getApp(), param.getStream(), 60, false, (msg) -> {
|
| | | logger.info("[è¯é³å¯¹è®²] ééå»ºç«æå, device: {}, channel: {}", deviceId, channelId);
|
| | | });
|
| | | } catch (InvalidArgumentException | ParseException | SipException e) {
|
| | | logger.error("[å½ä»¤åé失败] è¯é³å¯¹è®²: {}", e.getMessage());
|
| | | }
|
| | | } else {
|
| | | // æµæ³¨é
|
| | | playService.stopAudioBroadcast(deviceId, channelId);
|
| | | }
|
| | | } else {
|
| | | logger.info("[è¯é³å¯¹è®²] æªæ¾å°è®¾å¤ï¼{}", deviceId);
|
| | | }
|
| | | }
|
| | | }
|
| | | } else if ("talk".equals(param.getApp())) {
|
| | | // è¯é³å¯¹è®²æ¨æµ streaméè¦æ»¡è¶³æ ¼å¼deviceId_channelId
|
| | | if (param.getStream().indexOf("_") > 0) {
|
| | | String[] streamArray = param.getStream().split("_");
|
| | | if (streamArray.length == 2) {
|
| | | String deviceId = streamArray[0];
|
| | | String channelId = streamArray[1];
|
| | | Device device = deviceService.getDevice(deviceId);
|
| | | if (device != null) {
|
| | | if (param.isRegist()) {
|
| | | if (audioBroadcastManager.exit(deviceId, channelId)) {
|
| | | playService.stopAudioBroadcast(deviceId, channelId);
|
| | | }
|
| | | // å¼å¯è¯é³å¯¹è®²éé
|
| | | playService.talkCmd(device, channelId, mediaInfo, param.getStream(), (msg) -> {
|
| | | logger.info("[è¯é³å¯¹è®²] ééå»ºç«æå, device: {}, channel: {}", deviceId, channelId);
|
| | | });
|
| | | } else {
|
| | | // æµæ³¨é
|
| | | playService.stopTalk(device, channelId, param.isRegist());
|
| | | }
|
| | | } else {
|
| | | logger.info("[è¯é³å¯¹è®²] æªæ¾å°è®¾å¤ï¼{}", deviceId);
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | } else {
|
| | | if (!"rtp".equals(param.getApp())) {
|
| | | String type = OriginType.values()[param.getOriginType()].getType();
|
| | | if (param.isRegist()) {
|
| | | StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(
|
| | | param.getApp(), param.getStream());
|
| | | String callId = null;
|
| | | if (streamAuthorityInfo != null) {
|
| | | callId = streamAuthorityInfo.getCallId();
|
| | | }
|
| | | StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaInfo,
|
| | | param.getApp(), param.getStream(), tracks, callId);
|
| | | param.setStreamInfo(new StreamContent(streamInfoByAppAndStream));
|
| | | redisCatchStorage.addStream(mediaInfo, type, param.getApp(), param.getStream(), param);
|
| | | if (param.getOriginType() == OriginType.RTSP_PUSH.ordinal()
|
| | | || param.getOriginType() == OriginType.RTMP_PUSH.ordinal()
|
| | | || param.getOriginType() == OriginType.RTC_PUSH.ordinal()) {
|
| | | param.setSeverId(userSetting.getServerId());
|
| | | zlmMediaListManager.addPush(param);
|
| | |
|
| | | // å使°æ®ï¼èªå·±ç³»ç»ä¸èªç¨
|
| | | redisCatchStorage.addPushListItem(param.getApp(), param.getStream(), param);
|
| | | }
|
| | | } else {
|
| | | // å
¼å®¹æµæ³¨éæ¶ç±»åä»redisè®°å½è·å
|
| | | OnStreamChangedHookParam onStreamChangedHookParam = redisCatchStorage.getStreamInfo(
|
| | | param.getApp(), param.getStream(), param.getMediaServerId());
|
| | | if (onStreamChangedHookParam != null) {
|
| | | type = OriginType.values()[onStreamChangedHookParam.getOriginType()].getType();
|
| | | redisCatchStorage.removeStream(mediaInfo.getId(), type, param.getApp(), param.getStream());
|
| | | if ("PUSH".equalsIgnoreCase(type)) {
|
| | | // å使°æ®ï¼èªå·±ç³»ç»ä¸èªç¨
|
| | | redisCatchStorage.removePushListItem(param.getApp(), param.getStream(), param.getMediaServerId());
|
| | | }
|
| | | }
|
| | | GbStream gbStream = storager.getGbStream(param.getApp(), param.getStream());
|
| | | if (gbStream != null) {
|
| | | // eventPublisher.catalogEventPublishForStream(null, gbStream, CatalogEvent.OFF);
|
| | | }
|
| | | zlmMediaListManager.removeMedia(param.getApp(), param.getStream());
|
| | | }
|
| | | GbStream gbStream = storager.getGbStream(param.getApp(), param.getStream());
|
| | | if (gbStream != null) {
|
| | | if (userSetting.isUsePushingAsStatus()) {
|
| | | eventPublisher.catalogEventPublishForStream(null, gbStream, param.isRegist() ? CatalogEvent.ON : CatalogEvent.OFF);
|
| | | }
|
| | | }
|
| | | if (type != null) {
|
| | | // åéæµååredisæ¶æ¯
|
| | | JSONObject jsonObject = new JSONObject();
|
| | | jsonObject.put("serverId", userSetting.getServerId());
|
| | | jsonObject.put("app", param.getApp());
|
| | | jsonObject.put("stream", param.getStream());
|
| | | jsonObject.put("register", param.isRegist());
|
| | | jsonObject.put("mediaServerId", param.getMediaServerId());
|
| | | redisCatchStorage.sendStreamChangeMsg(type, jsonObject);
|
| | | }
|
| | | }
|
| | | }
|
| | | if (!param.isRegist()) {
|
| | | List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByStream(param.getStream());
|
| | | if (!sendRtpItems.isEmpty()) {
|
| | | for (SendRtpItem sendRtpItem : sendRtpItems) {
|
| | | if (sendRtpItem == null) {
|
| | | continue;
|
| | | }
|
| | |
|
| | | if (sendRtpItem.getApp().equals(param.getApp())) {
|
| | | logger.info(sendRtpItem.toString());
|
| | | if (userSetting.getServerId().equals(sendRtpItem.getServerId())) {
|
| | | MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0,
|
| | | sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getChannelId(),
|
| | | sendRtpItem.getPlatformId(), null, userSetting.getServerId(), param.getMediaServerId());
|
| | | // éç¥å
¶ä»wvp忢念
|
| | | redisCatchStorage.sendPushStreamClose(messageForPushChannel);
|
| | | }else {
|
| | | String platformId = sendRtpItem.getPlatformId();
|
| | | ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId);
|
| | | Device device = deviceService.getDevice(platformId);
|
| | |
|
| | | try {
|
| | | if (platform != null) {
|
| | | commanderFroPlatform.streamByeCmd(platform, sendRtpItem);
|
| | | redisCatchStorage.deleteSendRTPServer(platformId, sendRtpItem.getChannelId(),
|
| | | sendRtpItem.getCallId(), sendRtpItem.getStream());
|
| | | } else {
|
| | | cmder.streamByeCmd(device, sendRtpItem.getChannelId(), param.getStream(), sendRtpItem.getCallId());
|
| | | if (sendRtpItem.getPlayType().equals(InviteStreamType.BROADCAST)
|
| | | || sendRtpItem.getPlayType().equals(InviteStreamType.TALK)) {
|
| | | AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId());
|
| | | if (audioBroadcastCatch != null) {
|
| | | // æ¥èªä¸çº§å¹³å°çåæ¢å¯¹è®²
|
| | | logger.info("[åæ¢å¯¹è®²] æ¥èªä¸çº§ï¼å¹³å°ï¼{}, ééï¼{}", sendRtpItem.getDeviceId(), sendRtpItem.getChannelId());
|
| | | audioBroadcastManager.del(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId());
|
| | | }
|
| | | }
|
| | | }
|
| | | } catch (SipException | InvalidArgumentException | ParseException |
|
| | | SsrcTransactionNotFoundException e) {
|
| | | logger.error("[å½ä»¤åé失败] åéBYE: {}", e.getMessage());
|
| | | }
|
| | | }
|
| | |
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | });
|
| | | return HookResult.SUCCESS();
|
| | | }
|
| | |
|
| | |
| | | logger.info("[ZLM HOOK]æµæ 人è§çï¼{}->{}->{}/{}", param.getMediaServerId(), param.getSchema(),
|
| | | param.getApp(), param.getStream());
|
| | | JSONObject ret = new JSONObject();
|
| | | ret.put("code", 0);
|
| | | // 彿 ç±»åçæµ
|
| | | if ("rtp".equals(param.getApp())) {
|
| | | ret.put("close", userSetting.getStreamOnDemand());
|
| | | // 彿 æµï¼ ç¹æ/å½ååæ¾/å½åä¸è½½
|
| | | InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, param.getStream());
|
| | | // ç¹æ
|
| | | if (inviteInfo != null) {
|
| | | // å½åä¸è½½
|
| | | if (inviteInfo.getType() == InviteSessionType.DOWNLOAD) {
|
| | | ret.put("close", false);
|
| | | return ret;
|
| | | }
|
| | | // æ¶å°æ 人è§çè¯´ææµä¹æ²¡æå¨å¾ä¸çº§æ¨é
|
| | | if (redisCatchStorage.isChannelSendingRTP(inviteInfo.getChannelId())) {
|
| | | List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByChannelId(
|
| | | inviteInfo.getChannelId());
|
| | | if (!sendRtpItems.isEmpty()) {
|
| | | for (SendRtpItem sendRtpItem : sendRtpItems) {
|
| | | ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId());
|
| | | try {
|
| | | commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId());
|
| | | } catch (SipException | InvalidArgumentException | ParseException e) {
|
| | | logger.error("[å½ä»¤åé失败] 彿 级è åéBYE: {}", e.getMessage());
|
| | | }
|
| | | redisCatchStorage.deleteSendRTPServer(parentPlatform.getServerGBId(), sendRtpItem.getChannelId(),
|
| | | sendRtpItem.getCallId(), sendRtpItem.getStream());
|
| | | if (InviteStreamType.PUSH == sendRtpItem.getPlayType()) {
|
| | | MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0,
|
| | | sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getChannelId(),
|
| | | sendRtpItem.getPlatformId(), parentPlatform.getName(), userSetting.getServerId(), sendRtpItem.getMediaServerId());
|
| | | messageForPushChannel.setPlatFormIndex(parentPlatform.getId());
|
| | | redisCatchStorage.sendPlatformStopPlayMsg(messageForPushChannel);
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | Device device = deviceService.getDevice(inviteInfo.getDeviceId());
|
| | | if (device != null) {
|
| | | try {
|
| | | // 夿¥è¯¢ä¸æ¬¡é²æ¢å·²ç»è¢«å¤çäº
|
| | | InviteInfo info = inviteStreamService.getInviteInfo(inviteInfo.getType(),
|
| | | inviteInfo.getDeviceId(), inviteInfo.getChannelId(), inviteInfo.getStream());
|
| | | if (info != null) {
|
| | | cmder.streamByeCmd(device, inviteInfo.getChannelId(),
|
| | | inviteInfo.getStream(), null);
|
| | | } else {
|
| | | logger.info("[æ 人è§ç] æªæ¾å°è®¾å¤çç¹æä¿¡æ¯ï¼ {}ï¼ æµï¼{}", inviteInfo.getDeviceId(), param.getStream());
|
| | | }
|
| | | } catch (InvalidArgumentException | ParseException | SipException |
|
| | | SsrcTransactionNotFoundException e) {
|
| | | logger.error("[æ 人è§ç]ç¹æï¼ åéBYE失败 {}", e.getMessage());
|
| | | }
|
| | | } else {
|
| | | logger.info("[æ 人è§ç] æªæ¾å°è®¾å¤ï¼ {}ï¼æµï¼{}", inviteInfo.getDeviceId(), param.getStream());
|
| | | }
|
| | |
|
| | | boolean close = mediaService.closeStreamOnNoneReader(param.getMediaServerId(), param.getApp(), param.getStream(), param.getSchema());
|
| | | ret.put("code", close);
|
| | |
| | | if (!"rtp".equals(param.getApp())) {
|
| | | return HookResult.SUCCESS();
|
| | | }
|
| | | try {
|
| | | MediaSendRtpStoppedEvent event = new MediaSendRtpStoppedEvent(this);
|
| | | MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId());
|
| | | if (mediaServerItem != null) {
|
| | | event.setMediaServer(mediaServerItem);
|
| | | applicationEventPublisher.publishEvent(event);
|
| | | taskExecutor.execute(() -> {
|
| | | List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByStream(param.getStream());
|
| | | if (sendRtpItems.size() > 0) {
|
| | | for (SendRtpItem sendRtpItem : sendRtpItems) {
|
| | | ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId());
|
| | | ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc());
|
| | | try {
|
| | | commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId());
|
| | | } catch (SipException | InvalidArgumentException | ParseException e) {
|
| | | logger.error("[å½ä»¤åé失败] 彿 级è åéBYE: {}", e.getMessage());
|
| | | }
|
| | | redisCatchStorage.deleteSendRTPServer(parentPlatform.getServerGBId(), sendRtpItem.getChannelId(),
|
| | | sendRtpItem.getCallId(), sendRtpItem.getStream());
|
| | | }
|
| | | }
|
| | | }catch (Exception e) {
|
| | | logger.info("[ZLM-HOOK-rtpåéå
³é] åééç¥å¤±è´¥ ", e);
|
| | | }
|
| | | });
|
| | |
|
| | | return HookResult.SUCCESS();
|
| | | }
|
| | |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | public JSONObject stopSendRtpStream(MediaServerItem mediaServerItem, SendRtpItem sendRtpItem) { |
| | | Map<String, Object> param = new HashMap<>(); |
| | | param.put("vhost", "__defaultVhost__"); |
| | | param.put("app", sendRtpItem.getApp()); |
| | | param.put("stream", sendRtpItem.getStream()); |
| | | param.put("ssrc", sendRtpItem.getSsrc()); |
| | | return zlmresTfulUtils.stopSendRtp(mediaServerItem, param); |
| | | } |
| | | } |
| | |
| | | package com.genersoft.iot.vmp.media.zlm.dto; |
| | | |
| | | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
| | | |
| | | import java.text.ParseException; |
| | | |
| | | /** |
| | |
| | | */ |
| | | public interface ChannelOnlineEvent { |
| | | |
| | | void run(String app, String stream, String serverId) throws ParseException; |
| | | void run(SendRtpItem sendRtpItem) throws ParseException; |
| | | } |
| | |
| | | void updateChannelGPS(Device device, DeviceChannel deviceChannel, MobilePosition mobilePosition); |
| | | |
| | | void stopPlay(String deviceId, String channelId); |
| | | void batchUpdateChannelGPS(List<DeviceChannel> channelList); |
| | | |
| | | void batchAddMobilePosition(List<MobilePosition> addMobilePositionList); |
| | | |
| | | void online(DeviceChannel channel); |
| | | |
| | | void offline(DeviceChannel channel); |
| | | |
| | | void delete(DeviceChannel channel); |
| | | } |
| | |
| | | Map<String, StreamPushItem> getAllAppAndStreamMap(); |
| | | |
| | | |
| | | void updatePush(OnStreamChangedHookParam param); |
| | | } |
| | |
| | | messageForPushChannel.setGbId(gbId); |
| | | messageForPushChannel.setApp(app); |
| | | messageForPushChannel.setStream(stream); |
| | | messageForPushChannel.setServerId(serverId); |
| | | messageForPushChannel.setMediaServerId(mediaServerId); |
| | | messageForPushChannel.setPlatFormId(platFormId); |
| | | messageForPushChannel.setPlatFormName(platFormName); |
| | |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.ObjectUtils; |
| | | |
| | | import java.util.ArrayList; |
| | |
| | | } |
| | | |
| | | @Override |
| | | public void online(DeviceChannel channel) { |
| | | channelMapper.online(channel.getDeviceId(), channel.getChannelId()); |
| | | } |
| | | |
| | | @Override |
| | | public int channelsOffline(List<DeviceChannel> channels) { |
| | | return channelMapper.batchOffline(channels); |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public void offline(DeviceChannel channel) { |
| | | channelMapper.offline(channel.getDeviceId(), channel.getChannelId()); |
| | | } |
| | | |
| | | @Override |
| | | public void delete(DeviceChannel channel) { |
| | | channelMapper.del(channel.getDeviceId(), channel.getChannelId()); |
| | | } |
| | | |
| | | @Override |
| | |
| | | public void stopPlay(String deviceId, String channelId) { |
| | | channelMapper.stopPlay(deviceId, channelId); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional |
| | | public void batchUpdateChannelGPS(List<DeviceChannel> channelList) { |
| | | for (DeviceChannel deviceChannel : channelList) { |
| | | deviceChannel.setUpdateTime(DateUtil.getNow()); |
| | | if (deviceChannel.getGpsTime() == null) { |
| | | deviceChannel.setGpsTime(DateUtil.getNow()); |
| | | } |
| | | } |
| | | int count = 1000; |
| | | if (channelList.size() > count) { |
| | | for (int i = 0; i < channelList.size(); i+=count) { |
| | | int toIndex = i+count; |
| | | if ( i + count > channelList.size()) { |
| | | toIndex = channelList.size(); |
| | | } |
| | | List<DeviceChannel> channels = channelList.subList(i, toIndex); |
| | | channelMapper.batchUpdatePosition(channels); |
| | | } |
| | | }else { |
| | | channelMapper.batchUpdatePosition(channelList); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional |
| | | public void batchAddMobilePosition(List<MobilePosition> mobilePositions) { |
| | | // int count = 500; |
| | | // if (mobilePositions.size() > count) { |
| | | // for (int i = 0; i < mobilePositions.size(); i+=count) { |
| | | // int toIndex = i+count; |
| | | // if ( i + count > mobilePositions.size()) { |
| | | // toIndex = mobilePositions.size(); |
| | | // } |
| | | // List<MobilePosition> mobilePositionsSub = mobilePositions.subList(i, toIndex); |
| | | // deviceMobilePositionMapper.batchadd(mobilePositionsSub); |
| | | // } |
| | | // }else { |
| | | // deviceMobilePositionMapper.batchadd(mobilePositions); |
| | | // } |
| | | deviceMobilePositionMapper.batchadd(mobilePositions); |
| | | } |
| | | } |
| | |
| | | removeMobilePositionSubscribe(deviceInStore, result->{ |
| | | // å¼å¯è®¢é
|
| | | deviceInStore.setSubscribeCycleForMobilePosition(device.getSubscribeCycleForMobilePosition()); |
| | | deviceInStore.setMobilePositionSubmissionInterval(device.getMobilePositionSubmissionInterval()); |
| | | addMobilePositionSubscribe(deviceInStore); |
| | | // å 为æ¯å¼æ¥æ§è¡ï¼éè¦å¨è¿éæ´æ°ä¸æ°æ® |
| | | deviceMapper.updateCustom(deviceInStore); |
| | |
| | | }else { |
| | | // å¼å¯è®¢é
|
| | | deviceInStore.setSubscribeCycleForMobilePosition(device.getSubscribeCycleForMobilePosition()); |
| | | deviceInStore.setMobilePositionSubmissionInterval(device.getMobilePositionSubmissionInterval()); |
| | | addMobilePositionSubscribe(deviceInStore); |
| | | } |
| | | |
| | | }else if (device.getSubscribeCycleForMobilePosition() == 0) { |
| | | // åæ¶è®¢é
|
| | | deviceInStore.setSubscribeCycleForMobilePosition(0); |
| | | deviceInStore.setMobilePositionSubmissionInterval(0); |
| | | removeMobilePositionSubscribe(deviceInStore, null); |
| | | } |
| | | } |
| | |
| | | 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 RedisGbPlayMsgListener redisGbPlayMsgListener; |
| | | |
| | | |
| | | @Qualifier("taskExecutor") |
| | | @Autowired |
| | | private ThreadPoolTaskExecutor taskExecutor; |
| | | |
| | | @Autowired |
| | | private ZlmHttpHookSubscribe hookSubscribe; |
| | | |
| | | @Autowired |
| | | private SSRCFactory ssrcFactory; |
| | |
| | | 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); |
| | |
| | | public Map<String, StreamPushItem> getAllAppAndStreamMap() { |
| | | return streamPushMapper.getAllAppAndStreamMap(); |
| | | } |
| | | |
| | | @Override |
| | | public void updatePush(OnStreamChangedHookParam param) { |
| | | StreamPushItem transform = transform(param); |
| | | StreamPushItem pushInDb = getPush(param.getApp(), param.getStream()); |
| | | transform.setPushIng(param.isRegist()); |
| | | transform.setUpdateTime(DateUtil.getNow()); |
| | | transform.setPushTime(DateUtil.getNow()); |
| | | transform.setSelf(userSetting.getServerId().equals(param.getSeverId())); |
| | | if (pushInDb == null) { |
| | | transform.setCreateTime(DateUtil.getNow()); |
| | | streamPushMapper.add(transform); |
| | | }else { |
| | | streamPushMapper.update(transform); |
| | | gbStreamMapper.updateMediaServer(param.getApp(), param.getStream(), param.getMediaServerId()); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.genersoft.iot.vmp.service.redisMsg; |
| | | |
| | | import com.genersoft.iot.vmp.common.CommonCallback; |
| | | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
| | | import com.genersoft.iot.vmp.vmanager.bean.WVPResult; |
| | | |
| | | public interface IRedisRpcService { |
| | | |
| | | SendRtpItem getSendRtpItem(String sendRtpItemKey); |
| | | |
| | | WVPResult startSendRtp(String sendRtpItemKey, SendRtpItem sendRtpItem); |
| | | |
| | | WVPResult stopSendRtp(String sendRtpItemKey); |
| | | |
| | | long waitePushStreamOnline(SendRtpItem sendRtpItem, CommonCallback<String> callback); |
| | | |
| | | void stopWaitePushStreamOnline(SendRtpItem sendRtpItem); |
| | | |
| | | void rtpSendStopped(String sendRtpItemKey); |
| | | |
| | | void removeCallback(long key); |
| | | } |
old mode 100755
new mode 100644
New file |
| | |
| | | package com.genersoft.iot.vmp.service.redisMsg.control; |
| | | |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import com.genersoft.iot.vmp.conf.UserSetting; |
| | | import com.genersoft.iot.vmp.conf.redis.RedisRpcConfig; |
| | | import com.genersoft.iot.vmp.conf.redis.bean.RedisRpcMessage; |
| | | import com.genersoft.iot.vmp.conf.redis.bean.RedisRpcRequest; |
| | | import com.genersoft.iot.vmp.conf.redis.bean.RedisRpcResponse; |
| | | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| | | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
| | | import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; |
| | | import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; |
| | | 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.service.IMediaServerService; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| | | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| | | import com.genersoft.iot.vmp.vmanager.bean.WVPResult; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.sip.InvalidArgumentException; |
| | | import javax.sip.SipException; |
| | | import java.text.ParseException; |
| | | |
| | | /** |
| | | * å
¶ä»wvpåèµ·çrpcè°ç¨ï¼è¿éçæ¹æ³è¢« RedisRpcConfig éè¿åå°å¯»æ¾å¯¹åºçæ¹æ³åç§°è°ç¨ |
| | | */ |
| | | @Component |
| | | public class RedisRpcController { |
| | | |
| | | private final static Logger logger = LoggerFactory.getLogger(RedisRpcController.class); |
| | | |
| | | @Autowired |
| | | private SSRCFactory ssrcFactory; |
| | | |
| | | @Autowired |
| | | private IMediaServerService mediaServerService; |
| | | |
| | | @Autowired |
| | | private SendRtpPortManager sendRtpPortManager; |
| | | |
| | | @Autowired |
| | | private IRedisCatchStorage redisCatchStorage; |
| | | |
| | | @Autowired |
| | | private UserSetting userSetting; |
| | | |
| | | @Autowired |
| | | private ZlmHttpHookSubscribe hookSubscribe; |
| | | |
| | | @Autowired |
| | | private ZLMServerFactory zlmServerFactory; |
| | | |
| | | |
| | | @Autowired |
| | | private RedisTemplate<Object, Object> redisTemplate; |
| | | |
| | | |
| | | @Autowired |
| | | private ISIPCommanderForPlatform commanderFroPlatform; |
| | | |
| | | |
| | | @Autowired |
| | | private IVideoManagerStorage storager; |
| | | |
| | | |
| | | /** |
| | | * è·ååæµçä¿¡æ¯ |
| | | */ |
| | | public RedisRpcResponse getSendRtpItem(RedisRpcRequest request) { |
| | | String sendRtpItemKey = request.getParam().toString(); |
| | | SendRtpItem sendRtpItem = (SendRtpItem) redisTemplate.opsForValue().get(sendRtpItemKey); |
| | | if (sendRtpItem == null) { |
| | | logger.info("[redis-rpc] è·ååæµçä¿¡æ¯, æªæ¾å°redisä¸çåæµä¿¡æ¯ï¼ keyï¼{}", sendRtpItemKey); |
| | | RedisRpcResponse response = request.getResponse(); |
| | | response.setStatusCode(200); |
| | | return response; |
| | | } |
| | | logger.info("[redis-rpc] è·ååæµçä¿¡æ¯ï¼ {}/{}, ç®æ å°åï¼ {}ï¼{}", sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort()); |
| | | // æ¥è¯¢æ¬çº§æ¯å¦æè¿ä¸ªæµ |
| | | MediaServerItem mediaServerItem = mediaServerService.getMediaServerByAppAndStream(sendRtpItem.getApp(), sendRtpItem.getStream()); |
| | | if (mediaServerItem == null) { |
| | | RedisRpcResponse response = request.getResponse(); |
| | | response.setStatusCode(200); |
| | | } |
| | | // èªå¹³å°å
容 |
| | | int localPort = sendRtpPortManager.getNextPort(mediaServerItem); |
| | | if (localPort == 0) { |
| | | logger.info("[redis-rpc] getSendRtpItem->æå¡å¨ç«¯å£èµæºä¸è¶³" ); |
| | | RedisRpcResponse response = request.getResponse(); |
| | | response.setStatusCode(200); |
| | | } |
| | | // åå
¥redisï¼ è¶
æ¶æ¶åå¤ |
| | | sendRtpItem.setStatus(1); |
| | | sendRtpItem.setServerId(userSetting.getServerId()); |
| | | sendRtpItem.setLocalIp(mediaServerItem.getSdpIp()); |
| | | if (sendRtpItem.getSsrc() == null) { |
| | | // ä¸çº§å¹³å°ç¹ææ¶ä¸ä½¿ç¨ä¸çº§å¹³å°æå®çssrcï¼ä½¿ç¨èªå®ä¹çssrcï¼åè彿 ææ¡£-ç¹æå¤å设å¤åªä½æµSSRCå¤çæ¹å¼ |
| | | String ssrc = "Play".equalsIgnoreCase(sendRtpItem.getSessionName()) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId()); |
| | | sendRtpItem.setSsrc(ssrc); |
| | | } |
| | | redisCatchStorage.updateSendRTPSever(sendRtpItem); |
| | | redisTemplate.opsForValue().set(sendRtpItemKey, sendRtpItem); |
| | | RedisRpcResponse response = request.getResponse(); |
| | | response.setStatusCode(200); |
| | | response.setBody(sendRtpItemKey); |
| | | return response; |
| | | } |
| | | |
| | | /** |
| | | * ç嬿µä¸çº¿ |
| | | */ |
| | | public RedisRpcResponse waitePushStreamOnline(RedisRpcRequest request) { |
| | | SendRtpItem sendRtpItem = JSONObject.parseObject(request.getParam().toString(), SendRtpItem.class); |
| | | logger.info("[redis-rpc] ç嬿µä¸çº¿ï¼ {}/{}, ç®æ å°åï¼ {}ï¼{}", sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort()); |
| | | // æ¥è¯¢æ¬çº§æ¯å¦æè¿ä¸ªæµ |
| | | MediaServerItem mediaServerItem = mediaServerService.getMediaServerByAppAndStream(sendRtpItem.getApp(), sendRtpItem.getStream()); |
| | | if (mediaServerItem != null) { |
| | | logger.info("[redis-rpc] ç嬿µä¸çº¿æ¶åç°æµå·²åå¨ç´æ¥è¿åï¼ {}/{}, ç®æ å°åï¼ {}ï¼{}", sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort() ); |
| | | // 读åredisä¸çä¸çº§ç¹æä¿¡æ¯ï¼çæsendRtpItmåéåºå» |
| | | if (sendRtpItem.getSsrc() == null) { |
| | | // ä¸çº§å¹³å°ç¹ææ¶ä¸ä½¿ç¨ä¸çº§å¹³å°æå®çssrcï¼ä½¿ç¨èªå®ä¹çssrcï¼åè彿 ææ¡£-ç¹æå¤å设å¤åªä½æµSSRCå¤çæ¹å¼ |
| | | String ssrc = "Play".equalsIgnoreCase(sendRtpItem.getSessionName()) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId()); |
| | | sendRtpItem.setSsrc(ssrc); |
| | | } |
| | | sendRtpItem.setMediaServerId(mediaServerItem.getId()); |
| | | sendRtpItem.setLocalIp(mediaServerItem.getSdpIp()); |
| | | sendRtpItem.setServerId(userSetting.getServerId()); |
| | | |
| | | redisTemplate.opsForValue().set(sendRtpItem.getRedisKey(), sendRtpItem); |
| | | RedisRpcResponse response = request.getResponse(); |
| | | response.setBody(sendRtpItem.getRedisKey()); |
| | | response.setStatusCode(200); |
| | | } |
| | | // ç嬿µä¸çº¿ã æµä¸çº¿ç´æ¥åésendRtpItemæ¶æ¯ç»å®é
ç信令å¤çè
|
| | | HookSubscribeForStreamChange hook = HookSubscribeFactory.on_stream_changed( |
| | | sendRtpItem.getApp(), sendRtpItem.getStream(), true, "rtsp", null); |
| | | |
| | | hookSubscribe.addSubscribe(hook, (MediaServerItem mediaServerItemInUse, HookParam hookParam) -> { |
| | | logger.info("[redis-rpc] ç嬿µä¸çº¿ï¼æµå·²ä¸çº¿ï¼ {}/{}, ç®æ å°åï¼ {}ï¼{}", sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort()); |
| | | // 读åredisä¸çä¸çº§ç¹æä¿¡æ¯ï¼çæsendRtpItmåéåºå» |
| | | if (sendRtpItem.getSsrc() == null) { |
| | | // ä¸çº§å¹³å°ç¹ææ¶ä¸ä½¿ç¨ä¸çº§å¹³å°æå®çssrcï¼ä½¿ç¨èªå®ä¹çssrcï¼åè彿 ææ¡£-ç¹æå¤å设å¤åªä½æµSSRCå¤çæ¹å¼ |
| | | String ssrc = "Play".equalsIgnoreCase(sendRtpItem.getSessionName()) ? ssrcFactory.getPlaySsrc(mediaServerItemInUse.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItemInUse.getId()); |
| | | sendRtpItem.setSsrc(ssrc); |
| | | } |
| | | sendRtpItem.setMediaServerId(mediaServerItemInUse.getId()); |
| | | sendRtpItem.setLocalIp(mediaServerItemInUse.getSdpIp()); |
| | | sendRtpItem.setServerId(userSetting.getServerId()); |
| | | |
| | | redisTemplate.opsForValue().set(sendRtpItem.getRedisKey(), sendRtpItem); |
| | | RedisRpcResponse response = request.getResponse(); |
| | | response.setBody(sendRtpItem.getRedisKey()); |
| | | response.setStatusCode(200); |
| | | // æå¨åéç»æ |
| | | sendResponse(response); |
| | | hookSubscribe.removeSubscribe(hook); |
| | | |
| | | }); |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * 忢ç嬿µä¸çº¿ |
| | | */ |
| | | public RedisRpcResponse stopWaitePushStreamOnline(RedisRpcRequest request) { |
| | | SendRtpItem sendRtpItem = JSONObject.parseObject(request.getParam().toString(), SendRtpItem.class); |
| | | logger.info("[redis-rpc] 忢ç嬿µä¸çº¿ï¼ {}/{}, ç®æ å°åï¼ {}ï¼{}", sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort() ); |
| | | // ç嬿µä¸çº¿ã æµä¸çº¿ç´æ¥åésendRtpItemæ¶æ¯ç»å®é
ç信令å¤çè
|
| | | HookSubscribeForStreamChange hook = HookSubscribeFactory.on_stream_changed( |
| | | sendRtpItem.getApp(), sendRtpItem.getStream(), true, "rtsp", null); |
| | | hookSubscribe.removeSubscribe(hook); |
| | | RedisRpcResponse response = request.getResponse(); |
| | | response.setStatusCode(200); |
| | | return response; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * å¼å§åæµ |
| | | */ |
| | | public RedisRpcResponse startSendRtp(RedisRpcRequest request) { |
| | | String sendRtpItemKey = request.getParam().toString(); |
| | | SendRtpItem sendRtpItem = (SendRtpItem) redisTemplate.opsForValue().get(sendRtpItemKey); |
| | | RedisRpcResponse response = request.getResponse(); |
| | | response.setStatusCode(200); |
| | | if (sendRtpItem == null) { |
| | | logger.info("[redis-rpc] å¼å§åæµ, æªæ¾å°redisä¸çåæµä¿¡æ¯ï¼ keyï¼{}", sendRtpItemKey); |
| | | WVPResult wvpResult = WVPResult.fail(ErrorCode.ERROR100.getCode(), "æªæ¾å°redisä¸çåæµä¿¡æ¯"); |
| | | response.setBody(wvpResult); |
| | | return response; |
| | | } |
| | | logger.info("[redis-rpc] å¼å§åæµï¼ {}/{}, ç®æ å°åï¼ {}ï¼{}", sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort()); |
| | | MediaServerItem mediaServerItem = mediaServerService.getOne(sendRtpItem.getMediaServerId()); |
| | | if (mediaServerItem == null) { |
| | | logger.info("[redis-rpc] startSendRtp->æªæ¾å°MediaServerï¼ {}", sendRtpItem.getMediaServerId() ); |
| | | WVPResult wvpResult = WVPResult.fail(ErrorCode.ERROR100.getCode(), "æªæ¾å°MediaServer"); |
| | | response.setBody(wvpResult); |
| | | return response; |
| | | } |
| | | |
| | | Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, sendRtpItem.getApp(), sendRtpItem.getStream()); |
| | | if (!streamReady) { |
| | | logger.info("[redis-rpc] startSendRtp->æµä¸å¨çº¿ï¼ {}/{}", sendRtpItem.getApp(), sendRtpItem.getStream() ); |
| | | WVPResult wvpResult = WVPResult.fail(ErrorCode.ERROR100.getCode(), "æµä¸å¨çº¿"); |
| | | response.setBody(wvpResult); |
| | | return response; |
| | | } |
| | | JSONObject jsonObject = zlmServerFactory.startSendRtp(mediaServerItem, sendRtpItem); |
| | | if (jsonObject.getInteger("code") == 0) { |
| | | logger.info("[redis-rpc] åæµæåï¼ {}/{}, ç®æ å°åï¼ {}ï¼{}", sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort()); |
| | | WVPResult wvpResult = WVPResult.success(); |
| | | response.setBody(wvpResult); |
| | | }else { |
| | | logger.info("[redis-rpc] åæµå¤±è´¥ï¼ {}/{}, ç®æ å°åï¼ {}ï¼{}ï¼ {}", sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort(), jsonObject); |
| | | WVPResult wvpResult = WVPResult.fail(jsonObject.getInteger("code"), jsonObject.getString("msg")); |
| | | response.setBody(wvpResult); |
| | | } |
| | | return response; |
| | | } |
| | | |
| | | /** |
| | | * 忢念 |
| | | */ |
| | | public RedisRpcResponse stopSendRtp(RedisRpcRequest request) { |
| | | String sendRtpItemKey = request.getParam().toString(); |
| | | SendRtpItem sendRtpItem = (SendRtpItem) redisTemplate.opsForValue().get(sendRtpItemKey); |
| | | RedisRpcResponse response = request.getResponse(); |
| | | response.setStatusCode(200); |
| | | if (sendRtpItem == null) { |
| | | logger.info("[redis-rpc] åæ¢æ¨æµ, æªæ¾å°redisä¸çåæµä¿¡æ¯ï¼ keyï¼{}", sendRtpItemKey); |
| | | WVPResult wvpResult = WVPResult.fail(ErrorCode.ERROR100.getCode(), "æªæ¾å°redisä¸çåæµä¿¡æ¯"); |
| | | response.setBody(wvpResult); |
| | | return response; |
| | | } |
| | | logger.info("[redis-rpc] åæ¢æ¨æµï¼ {}/{}, ç®æ å°åï¼ {}ï¼{}", sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort() ); |
| | | MediaServerItem mediaServerItem = mediaServerService.getOne(sendRtpItem.getMediaServerId()); |
| | | if (mediaServerItem == null) { |
| | | logger.info("[redis-rpc] stopSendRtp->æªæ¾å°MediaServerï¼ {}", sendRtpItem.getMediaServerId() ); |
| | | WVPResult wvpResult = WVPResult.fail(ErrorCode.ERROR100.getCode(), "æªæ¾å°MediaServer"); |
| | | response.setBody(wvpResult); |
| | | return response; |
| | | } |
| | | JSONObject jsonObject = zlmServerFactory.stopSendRtpStream(mediaServerItem, sendRtpItem); |
| | | if (jsonObject.getInteger("code") == 0) { |
| | | logger.info("[redis-rpc] åæ¢æ¨æµæåï¼ {}/{}, ç®æ å°åï¼ {}ï¼{}", sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort() ); |
| | | response.setBody(WVPResult.success()); |
| | | return response; |
| | | }else { |
| | | int code = jsonObject.getInteger("code"); |
| | | String msg = jsonObject.getString("msg"); |
| | | logger.info("[redis-rpc] åæ¢æ¨æµå¤±è´¥ï¼ {}/{}, ç®æ å°åï¼ {}ï¼{}ï¼ codeï¼ {}, msg: {}", sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort(), code, msg ); |
| | | response.setBody(WVPResult.fail(code, msg)); |
| | | return response; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å
¶ä»wvpéç¥æ¨æµå·²ç»åæ¢äº |
| | | */ |
| | | public RedisRpcResponse rtpSendStopped(RedisRpcRequest request) { |
| | | String sendRtpItemKey = request.getParam().toString(); |
| | | SendRtpItem sendRtpItem = (SendRtpItem) redisTemplate.opsForValue().get(sendRtpItemKey); |
| | | RedisRpcResponse response = request.getResponse(); |
| | | response.setStatusCode(200); |
| | | if (sendRtpItem == null) { |
| | | logger.info("[redis-rpc] æ¨æµå·²ç»åæ¢, æªæ¾å°redisä¸çåæµä¿¡æ¯ï¼ keyï¼{}", sendRtpItemKey); |
| | | return response; |
| | | } |
| | | logger.info("[redis-rpc] æ¨æµå·²ç»åæ¢ï¼ {}/{}, ç®æ å°åï¼ {}ï¼{}", sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort() ); |
| | | String platformId = sendRtpItem.getPlatformId(); |
| | | ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId); |
| | | if (platform == null) { |
| | | return response; |
| | | } |
| | | try { |
| | | commanderFroPlatform.streamByeCmd(platform, sendRtpItem); |
| | | redisCatchStorage.deleteSendRTPServer(platformId, sendRtpItem.getChannelId(), |
| | | sendRtpItem.getCallId(), sendRtpItem.getStream()); |
| | | redisCatchStorage.sendPlatformStopPlayMsg(sendRtpItem, platform); |
| | | } catch (SipException | InvalidArgumentException | ParseException e) { |
| | | logger.error("[å½ä»¤åé失败] åéBYE: {}", e.getMessage()); |
| | | } |
| | | return response; |
| | | } |
| | | |
| | | private void sendResponse(RedisRpcResponse response){ |
| | | logger.info("[redis-rpc] >> {}", response); |
| | | response.setToId(userSetting.getServerId()); |
| | | RedisRpcMessage message = new RedisRpcMessage(); |
| | | message.setResponse(response); |
| | | redisTemplate.convertAndSend(RedisRpcConfig.REDIS_REQUEST_CHANNEL_KEY, message); |
| | | } |
| | | } |
New file |
| | |
| | | package com.genersoft.iot.vmp.service.redisMsg.service; |
| | | |
| | | import com.alibaba.fastjson2.JSON; |
| | | import com.genersoft.iot.vmp.common.CommonCallback; |
| | | import com.genersoft.iot.vmp.conf.UserSetting; |
| | | import com.genersoft.iot.vmp.conf.redis.RedisRpcConfig; |
| | | import com.genersoft.iot.vmp.conf.redis.bean.RedisRpcRequest; |
| | | import com.genersoft.iot.vmp.conf.redis.bean.RedisRpcResponse; |
| | | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
| | | import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; |
| | | 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.service.redisMsg.IRedisRpcService; |
| | | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| | | import com.genersoft.iot.vmp.vmanager.bean.WVPResult; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | @Service |
| | | public class RedisRpcServiceImpl implements IRedisRpcService { |
| | | |
| | | private final static Logger logger = LoggerFactory.getLogger(RedisRpcServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private RedisRpcConfig redisRpcConfig; |
| | | |
| | | @Autowired |
| | | private UserSetting userSetting; |
| | | |
| | | @Autowired |
| | | private ZlmHttpHookSubscribe hookSubscribe; |
| | | |
| | | @Autowired |
| | | private SSRCFactory ssrcFactory; |
| | | |
| | | @Autowired |
| | | private RedisTemplate<Object, Object> redisTemplate; |
| | | |
| | | private RedisRpcRequest buildRequest(String uri, Object param) { |
| | | RedisRpcRequest request = new RedisRpcRequest(); |
| | | request.setFromId(userSetting.getServerId()); |
| | | request.setParam(param); |
| | | request.setUri(uri); |
| | | return request; |
| | | } |
| | | |
| | | @Override |
| | | public SendRtpItem getSendRtpItem(String sendRtpItemKey) { |
| | | RedisRpcRequest request = buildRequest("getSendRtpItem", sendRtpItemKey); |
| | | RedisRpcResponse response = redisRpcConfig.request(request, 10); |
| | | if (response.getBody() == null) { |
| | | return null; |
| | | } |
| | | return (SendRtpItem)redisTemplate.opsForValue().get(response.getBody().toString()); |
| | | } |
| | | |
| | | @Override |
| | | public WVPResult startSendRtp(String sendRtpItemKey, SendRtpItem sendRtpItem) { |
| | | logger.info("[请æ±å
¶ä»WVP] å¼å§æ¨æµï¼wvpï¼{}ï¼ {}/{}", sendRtpItem.getServerId(), sendRtpItem.getApp(), sendRtpItem.getStream()); |
| | | RedisRpcRequest request = buildRequest("startSendRtp", sendRtpItemKey); |
| | | request.setToId(sendRtpItem.getServerId()); |
| | | RedisRpcResponse response = redisRpcConfig.request(request, 10); |
| | | return JSON.parseObject(response.getBody().toString(), WVPResult.class); |
| | | } |
| | | |
| | | @Override |
| | | public WVPResult stopSendRtp(String sendRtpItemKey) { |
| | | SendRtpItem sendRtpItem = (SendRtpItem)redisTemplate.opsForValue().get(sendRtpItemKey); |
| | | if (sendRtpItem == null) { |
| | | logger.info("[请æ±å
¶ä»WVP] åæ¢æ¨æµ, æªæ¾å°redisä¸çåæµä¿¡æ¯ï¼ keyï¼{}", sendRtpItemKey); |
| | | return WVPResult.fail(ErrorCode.ERROR100.getCode(), "æªæ¾å°åæµä¿¡æ¯"); |
| | | } |
| | | logger.info("[请æ±å
¶ä»WVP] åæ¢æ¨æµï¼wvpï¼{}ï¼ {}/{}", sendRtpItem.getServerId(), sendRtpItem.getApp(), sendRtpItem.getStream()); |
| | | RedisRpcRequest request = buildRequest("stopSendRtp", sendRtpItemKey); |
| | | request.setToId(sendRtpItem.getServerId()); |
| | | RedisRpcResponse response = redisRpcConfig.request(request, 10); |
| | | return JSON.parseObject(response.getBody().toString(), WVPResult.class); |
| | | } |
| | | |
| | | @Override |
| | | public long waitePushStreamOnline(SendRtpItem sendRtpItem, CommonCallback<String> callback) { |
| | | logger.info("[è¯·æ±ææWVPç嬿µä¸çº¿] {}/{}", sendRtpItem.getApp(), sendRtpItem.getStream()); |
| | | // ç嬿µä¸çº¿ã æµä¸çº¿ç´æ¥åésendRtpItemæ¶æ¯ç»å®é
ç信令å¤çè
|
| | | HookSubscribeForStreamChange hook = HookSubscribeFactory.on_stream_changed( |
| | | sendRtpItem.getApp(), sendRtpItem.getStream(), true, "rtsp", null); |
| | | RedisRpcRequest request = buildRequest("waitePushStreamOnline", sendRtpItem); |
| | | request.setToId(sendRtpItem.getServerId()); |
| | | hookSubscribe.addSubscribe(hook, (MediaServerItem mediaServerItemInUse, HookParam hookParam) -> { |
| | | |
| | | // 读åredisä¸çä¸çº§ç¹æä¿¡æ¯ï¼çæsendRtpItmåéåºå» |
| | | if (sendRtpItem.getSsrc() == null) { |
| | | // ä¸çº§å¹³å°ç¹ææ¶ä¸ä½¿ç¨ä¸çº§å¹³å°æå®çssrcï¼ä½¿ç¨èªå®ä¹çssrcï¼åè彿 ææ¡£-ç¹æå¤å设å¤åªä½æµSSRCå¤çæ¹å¼ |
| | | String ssrc = "Play".equalsIgnoreCase(sendRtpItem.getSessionName()) ? ssrcFactory.getPlaySsrc(mediaServerItemInUse.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItemInUse.getId()); |
| | | sendRtpItem.setSsrc(ssrc); |
| | | } |
| | | sendRtpItem.setMediaServerId(mediaServerItemInUse.getId()); |
| | | sendRtpItem.setLocalIp(mediaServerItemInUse.getSdpIp()); |
| | | sendRtpItem.setServerId(userSetting.getServerId()); |
| | | redisTemplate.opsForValue().set(sendRtpItem.getRedisKey(), sendRtpItem); |
| | | if (callback != null) { |
| | | callback.run(sendRtpItem.getRedisKey()); |
| | | } |
| | | hookSubscribe.removeSubscribe(hook); |
| | | redisRpcConfig.removeCallback(request.getSn()); |
| | | }); |
| | | |
| | | redisRpcConfig.request(request, response -> { |
| | | if (response.getBody() == null) { |
| | | logger.info("[è¯·æ±ææWVPç嬿µä¸çº¿] æµä¸çº¿,使¯æªæ¾å°åæµä¿¡æ¯ï¼{}/{}", sendRtpItem.getApp(), sendRtpItem.getStream()); |
| | | return; |
| | | } |
| | | logger.info("[è¯·æ±ææWVPç嬿µä¸çº¿] æµä¸çº¿ {}/{}->{}", sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.toString()); |
| | | |
| | | if (callback != null) { |
| | | callback.run(response.getBody().toString()); |
| | | } |
| | | hookSubscribe.removeSubscribe(hook); |
| | | }); |
| | | return request.getSn(); |
| | | } |
| | | |
| | | @Override |
| | | public void stopWaitePushStreamOnline(SendRtpItem sendRtpItem) { |
| | | logger.info("[忢WVPç嬿µä¸çº¿] {}/{}", sendRtpItem.getApp(), sendRtpItem.getStream()); |
| | | HookSubscribeForStreamChange hook = HookSubscribeFactory.on_stream_changed( |
| | | sendRtpItem.getApp(), sendRtpItem.getStream(), true, "rtsp", null); |
| | | hookSubscribe.removeSubscribe(hook); |
| | | RedisRpcRequest request = buildRequest("stopWaitePushStreamOnline", sendRtpItem); |
| | | request.setToId(sendRtpItem.getServerId()); |
| | | redisRpcConfig.request(request, 10); |
| | | } |
| | | |
| | | @Override |
| | | public void rtpSendStopped(String sendRtpItemKey) { |
| | | SendRtpItem sendRtpItem = (SendRtpItem)redisTemplate.opsForValue().get(sendRtpItemKey); |
| | | if (sendRtpItem == null) { |
| | | logger.info("[忢WVPç嬿µä¸çº¿] æªæ¾å°redisä¸çåæµä¿¡æ¯ï¼ keyï¼{}", sendRtpItemKey); |
| | | return; |
| | | } |
| | | RedisRpcRequest request = buildRequest("rtpSendStopped", sendRtpItemKey); |
| | | request.setToId(sendRtpItem.getServerId()); |
| | | redisRpcConfig.request(request, 10); |
| | | } |
| | | |
| | | @Override |
| | | public void removeCallback(long key) { |
| | | redisRpcConfig.removeCallback(key); |
| | | } |
| | | } |
| | |
| | | |
| | | void updateSendRTPSever(SendRtpItem sendRtpItem); |
| | | |
| | | List<SendRtpItem> querySendRTPServer(String platformGbId, String channelId, String streamId); |
| | | |
| | | /** |
| | | * æ¥è¯¢RTPæ¨éä¿¡æ¯ç¼å |
| | | * @param platformGbId |
| | |
| | | |
| | | void addDiskInfo(List<Map<String, Object>> diskInfo); |
| | | |
| | | void deleteSendRTPServer(SendRtpItem sendRtpItem); |
| | | |
| | | List<SendRtpItem> queryAllSendRTPServer(); |
| | | |
| | | List<Device> getAllDevices(); |
| | |
| | | |
| | | void sendPlatformStartPlayMsg(MessageForPushChannel messageForPushChannel); |
| | | |
| | | void sendPlatformStopPlayMsg(MessageForPushChannel messageForPushChannel); |
| | | void sendPlatformStopPlayMsg(SendRtpItem sendRtpItem, ParentPlatform platform); |
| | | |
| | | void addPushListItem(String app, String stream, MediaArrivalEvent param); |
| | | |
| | |
| | | |
| | | void sendPushStreamClose(MessageForPushChannel messageForPushChannel); |
| | | |
| | | void addWaiteSendRtpItem(SendRtpItem sendRtpItem, int platformPlayTimeout); |
| | | |
| | | SendRtpItem getWaiteSendRtpItem(String app, String stream); |
| | | |
| | | void sendStartSendRtp(SendRtpItem sendRtpItem); |
| | | |
| | | void sendPushStreamOnline(SendRtpItem sendRtpItem); |
| | | } |
| | |
| | | "<if test='status != null'>, status=#{status}</if>" + |
| | | "<if test='streamId != null'>, stream_id=#{streamId}</if>" + |
| | | "<if test='hasAudio != null'>, has_audio=#{hasAudio}</if>" + |
| | | ", custom_longitude=#{longitude}" + |
| | | ", custom_latitude=#{latitude}" + |
| | | "<if test='customLongitude != null'>, custom_longitude=#{customLongitude}</if>" + |
| | | "<if test='customLatitude != null'>, custom_latitude=#{customLatitude}</if>" + |
| | | "<if test='longitudeGcj02 != null'>, longitude_gcj02=#{longitudeGcj02}</if>" + |
| | | "<if test='latitudeGcj02 != null'>, latitude_gcj02=#{latitudeGcj02}</if>" + |
| | | "<if test='longitudeWgs84 != null'>, longitude_wgs84=#{longitudeWgs84}</if>" + |
| | |
| | | "dc.password, " + |
| | | "COALESCE(dc.custom_ptz_type, dc.ptz_type) AS ptz_type, " + |
| | | "dc.status, " + |
| | | "COALESCE(dc.custom_longitude, dc.longitude) AS longitude, " + |
| | | "COALESCE(dc.custom_latitude, dc.latitude) AS latitude, " + |
| | | "dc.longitude, " + |
| | | "dc.latitude, " + |
| | | "dc.custom_longitude, " + |
| | | "dc.custom_latitude, " + |
| | | "dc.stream_id, " + |
| | | "dc.device_id, " + |
| | | "dc.parental, " + |
| | |
| | | "<if test='item.hasAudio != null'>, has_audio=#{item.hasAudio}</if>" + |
| | | "<if test='item.longitude != null'>, longitude=#{item.longitude}</if>" + |
| | | "<if test='item.latitude != null'>, latitude=#{item.latitude}</if>" + |
| | | "<if test='item.customLongitude != null'>, custom_longitude=#{item.customLongitude}</if>" + |
| | | "<if test='item.customLatitude != null'>, custom_latitude=#{item.customLatitude}</if>" + |
| | | "<if test='item.longitudeGcj02 != null'>, longitude_gcj02=#{item.longitudeGcj02}</if>" + |
| | | "<if test='item.latitudeGcj02 != null'>, latitude_gcj02=#{item.latitudeGcj02}</if>" + |
| | | "<if test='item.longitudeWgs84 != null'>, longitude_wgs84=#{item.longitudeWgs84}</if>" + |
| | |
| | | " </script>"}) |
| | | int updatePosition(DeviceChannel deviceChannel); |
| | | |
| | | @Update({"<script>" + |
| | | "<foreach collection='deviceChannelList' item='item' separator=';'>" + |
| | | " UPDATE" + |
| | | " wvp_device_channel" + |
| | | " SET gps_time=#{item.gpsTime}" + |
| | | "<if test='item.longitude != null'>, longitude=#{item.longitude}</if>" + |
| | | "<if test='item.latitude != null'>, latitude=#{item.latitude}</if>" + |
| | | "<if test='item.longitudeGcj02 != null'>, longitude_gcj02=#{item.longitudeGcj02}</if>" + |
| | | "<if test='item.latitudeGcj02 != null'>, latitude_gcj02=#{item.latitudeGcj02}</if>" + |
| | | "<if test='item.longitudeWgs84 != null'>, longitude_wgs84=#{item.longitudeWgs84}</if>" + |
| | | "<if test='item.latitudeWgs84 != null'>, latitude_wgs84=#{item.latitudeWgs84}</if>" + |
| | | "WHERE device_id=#{item.deviceId} " + |
| | | " <if test='item.channelId != null' > AND channel_id=#{item.channelId}</if>" + |
| | | "</foreach>" + |
| | | "</script>"}) |
| | | int batchUpdatePosition(List<DeviceChannel> deviceChannelList); |
| | | |
| | | @Select("SELECT * FROM wvp_device_channel WHERE length(trim(stream_id)) > 0") |
| | | List<DeviceChannel> getAllChannelInPlay(); |
| | | |
| | |
| | | @Delete("DELETE FROM wvp_device_mobile_position WHERE device_id = #{deviceId}") |
| | | int clearMobilePositionsByDeviceId(String deviceId); |
| | | |
| | | |
| | | @Insert("<script> " + |
| | | "insert into wvp_device_mobile_position " + |
| | | "(device_id,channel_id, device_name,time,longitude,latitude,altitude,speed,direction,report_source," + |
| | | "longitude_gcj02,latitude_gcj02,longitude_wgs84,latitude_wgs84,create_time)"+ |
| | | "values " + |
| | | "<foreach collection='mobilePositions' index='index' item='item' separator=','> " + |
| | | "(#{item.deviceId}, #{item.channelId}, #{item.deviceName}, #{item.time}, #{item.longitude}, " + |
| | | "#{item.latitude}, #{item.altitude}, #{item.speed},#{item.direction}," + |
| | | "#{item.reportSource}, #{item.longitudeGcj02}, #{item.latitudeGcj02}, #{item.longitudeWgs84}, #{item.latitudeWgs84}, " + |
| | | "#{item.createTime}) " + |
| | | "</foreach> " + |
| | | "</script>") |
| | | void batchadd2(List<MobilePosition> mobilePositions); |
| | | |
| | | @Insert("<script> " + |
| | | "<foreach collection='mobilePositions' index='index' item='item' separator=','> " + |
| | | "insert into wvp_device_mobile_position " + |
| | | "(device_id,channel_id, device_name,time,longitude,latitude,altitude,speed,direction,report_source," + |
| | | "longitude_gcj02,latitude_gcj02,longitude_wgs84,latitude_wgs84,create_time)"+ |
| | | "values " + |
| | | "(#{item.deviceId}, #{item.channelId}, #{item.deviceName}, #{item.time}, #{item.longitude}, " + |
| | | "#{item.latitude}, #{item.altitude}, #{item.speed},#{item.direction}," + |
| | | "#{item.reportSource}, #{item.longitudeGcj02}, #{item.latitudeGcj02}, #{item.longitudeWgs84}, #{item.latitudeWgs84}, " + |
| | | "#{item.createTime}); " + |
| | | "</foreach> " + |
| | | "</script>") |
| | | void batchadd(List<MobilePosition> mobilePositions); |
| | | |
| | | } |
| | |
| | | import com.genersoft.iot.vmp.media.bean.MediaInfo; |
| | | import com.genersoft.iot.vmp.media.bean.MediaServer; |
| | | import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent; |
| | | import com.genersoft.iot.vmp.gb28181.bean.*; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; |
| | | import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; |
| | |
| | | |
| | | @Override |
| | | public void updateSendRTPSever(SendRtpItem sendRtpItem) { |
| | | redisTemplate.opsForValue().set(sendRtpItem.getRedisKey(), sendRtpItem); |
| | | } |
| | | |
| | | String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + |
| | | userSetting.getServerId() + "_" |
| | | + sendRtpItem.getMediaServerId() + "_" |
| | | + sendRtpItem.getPlatformId() + "_" |
| | | + sendRtpItem.getChannelId() + "_" |
| | | + sendRtpItem.getStream() + "_" |
| | | + sendRtpItem.getCallId(); |
| | | redisTemplate.opsForValue().set(key, sendRtpItem); |
| | | @Override |
| | | public List<SendRtpItem> querySendRTPServer(String platformGbId, String channelId, String streamId) { |
| | | String scanKey = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX |
| | | + userSetting.getServerId() + "_*_" |
| | | + platformGbId + "_" |
| | | + channelId + "_" |
| | | + streamId + "_" |
| | | + "*"; |
| | | List<SendRtpItem> result = new ArrayList<>(); |
| | | List<Object> scan = RedisUtil.scan(redisTemplate, scanKey); |
| | | if (!scan.isEmpty()) { |
| | | for (Object o : scan) { |
| | | String key = (String) o; |
| | | result.add(JsonUtil.redisJsonToObject(redisTemplate, key, SendRtpItem.class)); |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | |
| | | callId = "*"; |
| | | } |
| | | String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX |
| | | + userSetting.getServerId() + "_*_" |
| | | + "*_*_" |
| | | + platformGbId + "_" |
| | | + channelId + "_" |
| | | + streamId + "_" |
| | |
| | | List<Object> scan = RedisUtil.scan(redisTemplate, key); |
| | | if (scan.size() > 0) { |
| | | for (Object keyStr : scan) { |
| | | logger.info("[å é¤ redisçSendRTP]ï¼ {}", keyStr.toString()); |
| | | redisTemplate.delete(keyStr); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å é¤RTPæ¨éä¿¡æ¯ç¼å |
| | | */ |
| | | @Override |
| | | public void deleteSendRTPServer(SendRtpItem sendRtpItem) { |
| | | deleteSendRTPServer(sendRtpItem.getPlatformId(), sendRtpItem.getChannelId(),sendRtpItem.getCallId(), sendRtpItem.getStream()); |
| | | } |
| | | |
| | | @Override |
| | |
| | | @Override |
| | | public void sendMobilePositionMsg(JSONObject jsonObject) { |
| | | String key = VideoManagerConstants.VM_MSG_SUBSCRIBE_MOBILE_POSITION; |
| | | logger.info("[redisåééç¥] åé ç§»å¨ä½ç½® {}: {}", key, jsonObject.toString()); |
| | | // logger.info("[redisåééç¥] åé ç§»å¨ä½ç½® {}: {}", key, jsonObject.toString()); |
| | | redisTemplate.convertAndSend(key, jsonObject); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | @Override |
| | | public void sendPlatformStopPlayMsg(MessageForPushChannel msg) { |
| | | public void sendPlatformStopPlayMsg(SendRtpItem sendRtpItem, ParentPlatform platform) { |
| | | |
| | | MessageForPushChannel msg = MessageForPushChannel.getInstance(0, |
| | | sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getChannelId(), |
| | | sendRtpItem.getPlatformId(), platform.getName(), userSetting.getServerId(), sendRtpItem.getMediaServerId()); |
| | | msg.setPlatFormIndex(platform.getId()); |
| | | |
| | | String key = VideoManagerConstants.VM_MSG_STREAM_STOP_PLAY_NOTIFY; |
| | | logger.info("[redisåééç¥] åé ä¸çº§å¹³å°åæ¢è§ç {}: {}/{}->{}", key, msg.getApp(), msg.getStream(), msg.getPlatFormId()); |
| | | logger.info("[redisåééç¥] åé ä¸çº§å¹³å°åæ¢è§ç {}: {}/{}->{}", key, sendRtpItem.getApp(), sendRtpItem.getStream(), platform.getServerGBId()); |
| | | redisTemplate.convertAndSend(key, JSON.toJSON(msg)); |
| | | } |
| | | |
| | |
| | | logger.info("[redisåééç¥] åé 忢åä¸çº§æ¨æµ {}: {}/{}->{}", key, msg.getApp(), msg.getStream(), msg.getPlatFormId()); |
| | | redisTemplate.convertAndSend(key, JSON.toJSON(msg)); |
| | | } |
| | | |
| | | @Override |
| | | public void addWaiteSendRtpItem(SendRtpItem sendRtpItem, int platformPlayTimeout) { |
| | | String key = VideoManagerConstants.WAITE_SEND_PUSH_STREAM + sendRtpItem.getApp() + "_" + sendRtpItem.getStream(); |
| | | redisTemplate.opsForValue().set(key, sendRtpItem); |
| | | } |
| | | |
| | | @Override |
| | | public SendRtpItem getWaiteSendRtpItem(String app, String stream) { |
| | | String key = VideoManagerConstants.WAITE_SEND_PUSH_STREAM + app + "_" + stream; |
| | | return JsonUtil.redisJsonToObject(redisTemplate, key, SendRtpItem.class); |
| | | } |
| | | |
| | | @Override |
| | | public void sendStartSendRtp(SendRtpItem sendRtpItem) { |
| | | String key = VideoManagerConstants.START_SEND_PUSH_STREAM + sendRtpItem.getApp() + "_" + sendRtpItem.getStream(); |
| | | logger.info("[redisåééç¥] éç¥å
¶ä»WVPæ¨æµ {}: {}/{}->{}", key, sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getPlatformId()); |
| | | redisTemplate.convertAndSend(key, JSON.toJSON(sendRtpItem)); |
| | | } |
| | | |
| | | @Override |
| | | public void sendPushStreamOnline(SendRtpItem sendRtpItem) { |
| | | String key = VideoManagerConstants.VM_MSG_STREAM_PUSH_CLOSE_REQUESTED; |
| | | logger.info("[redisåééç¥] æµä¸çº¿ {}: {}/{}->{}", key, sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getPlatformId()); |
| | | redisTemplate.convertAndSend(key, JSON.toJSON(sendRtpItem)); |
| | | } |
| | | } |
| | |
| | | |
| | | import com.genersoft.iot.vmp.conf.UserSetting; |
| | | import com.genersoft.iot.vmp.conf.exception.ControllerException; |
| | | import com.genersoft.iot.vmp.conf.redis.RedisRpcConfig; |
| | | import com.genersoft.iot.vmp.conf.security.JwtUtils; |
| | | import com.genersoft.iot.vmp.service.ILogService; |
| | | import com.genersoft.iot.vmp.storager.dao.dto.LogDto; |
| | |
| | | logService.clear(); |
| | | } |
| | | |
| | | @Autowired |
| | | private RedisRpcConfig redisRpcConfig; |
| | | |
| | | @GetMapping("/test/count") |
| | | public Object count() { |
| | | return redisRpcConfig.getCallbackCount(); |
| | | } |
| | | |
| | | |
| | | |
| | | } |
| | |
| | | e.ptzType = e.ptzType + ""; |
| | | that.$set(e, "edit", false); |
| | | that.$set(e, "location", ""); |
| | | if (e.longitude && e.latitude) { |
| | | if (e.customLongitude && e.customLatitude) { |
| | | that.$set(e, "location", e.customLongitude + "," + e.customLatitude); |
| | | }else if (e.longitude && e.latitude) { |
| | | that.$set(e, "location", e.longitude + "," + e.latitude); |
| | | } |
| | | }); |
| | |
| | | e.ptzType = e.ptzType + ""; |
| | | this.$set(e, "edit", false); |
| | | this.$set(e, "location", ""); |
| | | if (e.longitude && e.latitude) { |
| | | if (e.customLongitude && e.customLatitude) { |
| | | this.$set(e, "location", e.customLongitude + "," + e.customLatitude); |
| | | }else if (e.longitude && e.latitude) { |
| | | this.$set(e, "location", e.longitude + "," + e.latitude); |
| | | } |
| | | }); |
| | |
| | | this.$message.warning("ä½ç½®ä¿¡æ¯æ ¼å¼æè¯¯ï¼ä¾ï¼117.234,36.378"); |
| | | return; |
| | | } else { |
| | | row.longitude = parseFloat(segements[0]); |
| | | row.latitude = parseFloat(segements[1]); |
| | | row.customLongitude = parseFloat(segements[0]); |
| | | row.custom_latitude = parseFloat(segements[1]); |
| | | if (!(row.longitude && row.latitude)) { |
| | | this.$message.warning("ä½ç½®ä¿¡æ¯æ ¼å¼æè¯¯ï¼ä¾ï¼117.234,36.378"); |
| | | return; |
| | |
| | | alter table wvp_device |
| | | drop switch_primary_sub_stream; |
| | | |
| | | # 第ä¸ä¸ªè¡¥ä¸å
|
| | | alter table wvp_platform |
| | | add send_stream_ip character varying(50); |
| | | add send_stream_ip character varying(50); |
| | | |
| | | alter table wvp_device |
| | | change on_line on_line bool default false; |
| | | |
| | | alter table wvp_device |
| | | change id id serial primary key; |
| | | |
| | | alter table wvp_device |
| | | change ssrc_check ssrc_check bool default false; |
| | |
| | | alter table wvp_device |
| | | drop switch_primary_sub_stream; |
| | | |
| | | # 第ä¸ä¸ªè¡¥ä¸å
|
| | | alter table wvp_platform |
| | | add send_stream_ip character varying(50); |
| | | add send_stream_ip character varying(50); |
| | | |
| | | alter table wvp_device |
| | | change on_line on_line bool default false; |
| | | |
| | | alter table wvp_device |
| | | change id id serial primary key; |
| | | |
| | | alter table wvp_device |
| | | change ssrc_check ssrc_check bool default false; |