| | |
| | | } |
| | | break; |
| | | case "query": |
| | | if (keyItemArray.length <= 5) return null; |
| | | if (keyItemArray.length <= 5) { |
| | | return null; |
| | | } |
| | | switch (keyItemArray[4]) { |
| | | case "devices": |
| | | if (keyItemArray.length < 7) return null; |
| | | if (keyItemArray.length < 7) { |
| | | return null; |
| | | } |
| | | switch (keyItemArray[6]) { |
| | | case "sync": |
| | | return "[设备查询] 同步设备通道"; |
| | |
| | | |
| | | import java.util.concurrent.ThreadPoolExecutor; |
| | | |
| | | /** |
| | | * ThreadPoolTask 配置类 |
| | | * @author lin |
| | | */ |
| | | @Configuration |
| | | @EnableAsync(proxyTargetClass = true) |
| | | public class ThreadPoolTaskConfig { |
| | |
| | | */ |
| | | private static final String threadNamePrefix = "wvp-"; |
| | | |
| | | /** |
| | | * |
| | | * @return |
| | | */ |
| | | @Bean("taskExecutor") // bean的名称,默认为首字母小写的方法名 |
| | | public ThreadPoolTaskExecutor taskExecutor() { |
| | | ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); |
| | |
| | | package com.genersoft.iot.vmp.conf; |
| | | |
| | | import io.swagger.models.auth.In; |
| | | import org.springframework.boot.context.properties.ConfigurationProperties; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | |
| | | |
| | | private Boolean seniorSdp = Boolean.FALSE; |
| | | |
| | | private Long playTimeout = 18000L; |
| | | private Integer playTimeout = 18000; |
| | | |
| | | private int platformPlayTimeout = 60000; |
| | | |
| | |
| | | return seniorSdp; |
| | | } |
| | | |
| | | public Long getPlayTimeout() { |
| | | public Integer getPlayTimeout() { |
| | | return playTimeout; |
| | | } |
| | | |
| | |
| | | this.seniorSdp = seniorSdp; |
| | | } |
| | | |
| | | public void setPlayTimeout(Long playTimeout) { |
| | | public void setPlayTimeout(Integer playTimeout) { |
| | | this.playTimeout = playTimeout; |
| | | } |
| | | |
| | |
| | | */ |
| | | public boolean doAuthenticateHashedPassword(Request request, String hashedPassword) { |
| | | AuthorizationHeader authHeader = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME); |
| | | if ( authHeader == null ) return false; |
| | | if ( authHeader == null ) { |
| | | return false; |
| | | } |
| | | String realm = authHeader.getRealm(); |
| | | String username = authHeader.getUsername(); |
| | | |
| | |
| | | */ |
| | | public boolean doAuthenticatePlainTextPassword(Request request, String pass) { |
| | | AuthorizationHeader authHeader = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME); |
| | | if ( authHeader == null ) return false; |
| | | if ( authHeader == null ) { |
| | | return false; |
| | | } |
| | | String realm = authHeader.getRealm().trim(); |
| | | String username = authHeader.getUsername().trim(); |
| | | |
| | |
| | | return gbStreamId; |
| | | } |
| | | |
| | | @Override |
| | | public void setGbStreamId(Integer gbStreamId) { |
| | | this.gbStreamId = gbStreamId; |
| | | } |
| | |
| | | mobilePositionMap.put(platformId, subscribeInfo); |
| | | String key = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + "MobilePosition_" + platformId; |
| | | // 添加任务处理GPS定时推送 |
| | | dynamicTask.startCron(key, new MobilePositionSubscribeHandlerTask(redisCatchStorage, sipCommanderForPlatform, storager, platformId, subscribeInfo.getSn(), key, this), subscribeInfo.getGpsInterval()); |
| | | dynamicTask.startCron(key, new MobilePositionSubscribeHandlerTask(redisCatchStorage, sipCommanderForPlatform, |
| | | storager, platformId, subscribeInfo.getSn(), key, this, dynamicTask), |
| | | subscribeInfo.getGpsInterval()); |
| | | String taskOverdueKey = taskOverduePrefix + "MobilePosition_" + platformId; |
| | | dynamicTask.stop(taskOverdueKey); |
| | | // 添加任务处理订阅过期 |
| | |
| | |
|
| | | logger.info("设备上线事件触发,deviceId:" + event.getDevice().getDeviceId() + ",from:" + event.getFrom());
|
| | | Device device = event.getDevice();
|
| | | if (device == null) return;
|
| | | if (device == null) {
|
| | | return;
|
| | | }
|
| | | String key = VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_" + event.getDevice().getDeviceId();
|
| | | Device deviceInStore = storager.queryVideoDevice(device.getDeviceId());
|
| | | device.setOnline(1);
|
| | |
| | | package com.genersoft.iot.vmp.gb28181.event.platformNotRegister; |
| | | |
| | | import com.genersoft.iot.vmp.conf.DynamicTask; |
| | | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| | | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; |
| | |
| | | private IVideoManagerStorage storager; |
| | | @Autowired |
| | | private ISIPCommanderForPlatform sipCommanderFroPlatform; |
| | | @Autowired |
| | | private DynamicTask dynamicTask; |
| | | |
| | | @Override |
| | | public void onApplicationEvent(PlatformCycleRegisterEvent event) { |
| | |
| | | logger.info("[ 平台未注册事件 ] 平台已经删除!!! 平台国标ID:" + event.getPlatformGbID()); |
| | | return; |
| | | } |
| | | Timer timer = new Timer(); |
| | | String taskKey = "platform-cycle-register" + parentPlatform.getServerGBId();; |
| | | SipSubscribe.Event okEvent = (responseEvent)->{ |
| | | timer.cancel(); |
| | | dynamicTask.stop(taskKey); |
| | | }; |
| | | sipCommanderFroPlatform.register(parentPlatform, null, okEvent); |
| | | timer.schedule(new TimerTask() { |
| | | @Override |
| | | public void run() { |
| | | logger.info("[平台注册]再次向平台注册,平台国标ID:" + event.getPlatformGbID()); |
| | | sipCommanderFroPlatform.register(parentPlatform, null, okEvent); |
| | | } |
| | | }, 15*1000 ,Long.parseLong(parentPlatform.getExpires())* 1000); |
| | | dynamicTask.startCron(taskKey, ()->{ |
| | | logger.info("[平台注册]再次向平台注册,平台国标ID:" + event.getPlatformGbID()); |
| | | sipCommanderFroPlatform.register(parentPlatform, null, okEvent); |
| | | }, Integer.parseInt(parentPlatform.getExpires())* 1000); |
| | | } |
| | | } |
| | |
| | | package com.genersoft.iot.vmp.gb28181.event.platformNotRegister; |
| | | |
| | | import com.genersoft.iot.vmp.conf.DynamicTask; |
| | | import com.genersoft.iot.vmp.conf.SipConfig; |
| | | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| | | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
| | |
| | | @Autowired |
| | | private SipConfig config; |
| | | |
| | | @Autowired |
| | | private DynamicTask dynamicTask; |
| | | |
| | | // @Autowired |
| | | // private RedisUtil redis; |
| | | |
| | |
| | | } |
| | | |
| | | } |
| | | Timer timer = new Timer(); |
| | | String taskKey = "platform-not-register-" + parentPlatform.getServerGBId(); |
| | | SipSubscribe.Event okEvent = (responseEvent)->{ |
| | | timer.cancel(); |
| | | dynamicTask.stop(taskKey); |
| | | }; |
| | | logger.info("[平台注册]平台国标ID:" + event.getPlatformGbID()); |
| | | sipCommanderFroPlatform.register(parentPlatform, null, okEvent); |
| | | // 设置注册失败则每隔15秒发起一次注册 |
| | | timer.schedule(new TimerTask() { |
| | | @Override |
| | | public void run() { |
| | | logger.info("[平台注册]再次向平台注册,平台国标ID:" + event.getPlatformGbID()); |
| | | sipCommanderFroPlatform.register(parentPlatform, null, okEvent); |
| | | } |
| | | }, config.getRegisterTimeInterval()* 1000, config.getRegisterTimeInterval()* 1000);//十五秒后再次发起注册 |
| | | dynamicTask.startCron(taskKey, ()->{ |
| | | logger.info("[平台注册]再次向平台注册,平台国标ID:" + event.getPlatformGbID()); |
| | | sipCommanderFroPlatform.register(parentPlatform, null, okEvent); |
| | | }, config.getRegisterTimeInterval()* 1000); |
| | | } |
| | | } |
| | |
| | | Map<String, List<ParentPlatform>> parentPlatformMap = new HashMap<>(); |
| | | if (event.getPlatformId() != null) { |
| | | parentPlatform = storager.queryParentPlatByServerGBId(event.getPlatformId()); |
| | | if (parentPlatform != null && !parentPlatform.isStatus())return; |
| | | if (parentPlatform != null && !parentPlatform.isStatus()) { |
| | | return; |
| | | } |
| | | subscribe = subscribeHolder.getCatalogSubscribe(event.getPlatformId()); |
| | | |
| | | if (subscribe == null) { |
| | |
| | | }else if (event.getGbStreams() != null) { |
| | | if (platforms.size() > 0) { |
| | | for (GbStream gbStream : event.getGbStreams()) { |
| | | if (gbStream == null || StringUtils.isEmpty(gbStream.getGbId())) continue; |
| | | if (gbStream == null || StringUtils.isEmpty(gbStream.getGbId())) { |
| | | continue; |
| | | } |
| | | List<ParentPlatform> parentPlatformsForGB = storager.queryPlatFormListForStreamWithGBId(gbStream.getApp(),gbStream.getStream(), platforms); |
| | | parentPlatformMap.put(gbStream.getGbId(), parentPlatformsForGB); |
| | | } |
| | |
| | | if (parentPlatforms != null && parentPlatforms.size() > 0) { |
| | | for (ParentPlatform platform : parentPlatforms) { |
| | | SubscribeInfo subscribeInfo = subscribeHolder.getCatalogSubscribe(platform.getServerGBId()); |
| | | if (subscribeInfo == null) continue; |
| | | if (subscribeInfo == null) { |
| | | continue; |
| | | } |
| | | logger.info("[Catalog事件: {}]平台:{},影响通道{}", event.getType(), platform.getServerGBId(), gbId); |
| | | List<DeviceChannel> deviceChannelList = new ArrayList<>(); |
| | | DeviceChannel deviceChannel = new DeviceChannel(); |
| | |
| | | if (parentPlatforms != null && parentPlatforms.size() > 0) { |
| | | for (ParentPlatform platform : parentPlatforms) { |
| | | SubscribeInfo subscribeInfo = subscribeHolder.getCatalogSubscribe(platform.getServerGBId()); |
| | | if (subscribeInfo == null) continue; |
| | | if (subscribeInfo == null) { |
| | | continue; |
| | | } |
| | | logger.info("[Catalog事件: {}]平台:{},影响通道{}", event.getType(), platform.getServerGBId(), gbId); |
| | | List<DeviceChannel> deviceChannelList = new ArrayList<>(); |
| | | DeviceChannel deviceChannel = storager.queryChannelInParentPlatform(platform.getServerGBId(), gbId); |
| | |
| | | |
| | | public List<DeviceChannel> get(String deviceId) { |
| | | CatalogData catalogData = data.get(deviceId); |
| | | if (catalogData == null) return null; |
| | | if (catalogData == null) { |
| | | return null; |
| | | } |
| | | return catalogData.getChannelList(); |
| | | } |
| | | |
| | | public int getTotal(String deviceId) { |
| | | CatalogData catalogData = data.get(deviceId); |
| | | if (catalogData == null) return 0; |
| | | if (catalogData == null) { |
| | | return 0; |
| | | } |
| | | return catalogData.getTotal(); |
| | | } |
| | | |
| | | public SyncStatus getSyncStatus(String deviceId) { |
| | | CatalogData catalogData = data.get(deviceId); |
| | | if (catalogData == null) return null; |
| | | if (catalogData == null) { |
| | | return null; |
| | | } |
| | | SyncStatus syncStatus = new SyncStatus(); |
| | | syncStatus.setCurrent(catalogData.getChannelList().size()); |
| | | syncStatus.setTotal(catalogData.getTotal()); |
| | |
| | | |
| | | public boolean isSyncRunning(String deviceId) { |
| | | CatalogData catalogData = data.get(deviceId); |
| | | if (catalogData == null) return false; |
| | | if (catalogData == null) { |
| | | return false; |
| | | } |
| | | return !catalogData.getStatus().equals(CatalogData.CatalogDataStatus.end); |
| | | } |
| | | |
| | |
| | | |
| | | public void setChannelSyncEnd(String deviceId, String errorMsg) { |
| | | CatalogData catalogData = data.get(deviceId); |
| | | if (catalogData == null)return; |
| | | if (catalogData == null) { |
| | | return; |
| | | } |
| | | catalogData.setStatus(CatalogData.CatalogDataStatus.end); |
| | | catalogData.setErrorMsg(errorMsg); |
| | | } |
| | |
| | |
|
| | | public ClientTransaction getTransactionByStream(String deviceId, String channelId, String stream){
|
| | | SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, null, stream);
|
| | | if (ssrcTransaction == null) return null;
|
| | | if (ssrcTransaction == null) {
|
| | | return null;
|
| | | }
|
| | | byte[] transactionByteArray = ssrcTransaction.getTransaction();
|
| | | ClientTransaction clientTransaction = (ClientTransaction)SerializeUtils.deSerialize(transactionByteArray);
|
| | | return clientTransaction;
|
| | |
| | |
|
| | | public SIPDialog getDialogByStream(String deviceId, String channelId, String stream){
|
| | | SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, null, stream);
|
| | | if (ssrcTransaction == null) return null;
|
| | | if (ssrcTransaction == null) {
|
| | | return null;
|
| | | }
|
| | | byte[] dialogByteArray = ssrcTransaction.getDialog();
|
| | | if (dialogByteArray == null) return null;
|
| | | if (dialogByteArray == null) {
|
| | | return null;
|
| | | }
|
| | | SIPDialog dialog = (SIPDialog)SerializeUtils.deSerialize(dialogByteArray);
|
| | | return dialog;
|
| | | }
|
| | |
|
| | | public SIPDialog getDialogByCallId(String deviceId, String channelId, String callID){
|
| | | SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, callID, null);
|
| | | if (ssrcTransaction == null) return null;
|
| | | if (ssrcTransaction == null) {
|
| | | return null;
|
| | | }
|
| | | byte[] dialogByteArray = ssrcTransaction.getDialog();
|
| | | if (dialogByteArray == null) return null;
|
| | | if (dialogByteArray == null) {
|
| | | return null;
|
| | | }
|
| | | SIPDialog dialog = (SIPDialog)SerializeUtils.deSerialize(dialogByteArray);
|
| | | return dialog;
|
| | | }
|
| | |
|
| | | public SsrcTransaction getSsrcTransaction(String deviceId, String channelId, String callId, String stream){
|
| | | if (StringUtils.isEmpty(callId)) callId ="*";
|
| | | if (StringUtils.isEmpty(stream)) stream ="*";
|
| | | if (StringUtils.isEmpty(callId)) {
|
| | | callId ="*";
|
| | | }
|
| | | if (StringUtils.isEmpty(stream)) {
|
| | | stream ="*";
|
| | | }
|
| | | String key = VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId() + "_" + deviceId + "_" + channelId + "_" + callId+ "_" + stream;
|
| | | List<Object> scanResult = redisUtil.scan(key);
|
| | | if (scanResult.size() == 0) return null;
|
| | | if (scanResult.size() == 0) {
|
| | | return null;
|
| | | }
|
| | | return (SsrcTransaction)redisUtil.get((String) scanResult.get(0));
|
| | | }
|
| | |
|
| | | public List<SsrcTransaction> getSsrcTransactionForAll(String deviceId, String channelId, String callId, String stream){
|
| | | if (StringUtils.isEmpty(deviceId)) deviceId ="*";
|
| | | if (StringUtils.isEmpty(channelId)) channelId ="*";
|
| | | if (StringUtils.isEmpty(callId)) callId ="*";
|
| | | if (StringUtils.isEmpty(stream)) stream ="*";
|
| | | if (StringUtils.isEmpty(deviceId)) {
|
| | | deviceId ="*";
|
| | | }
|
| | | if (StringUtils.isEmpty(channelId)) {
|
| | | channelId ="*";
|
| | | }
|
| | | if (StringUtils.isEmpty(callId)) {
|
| | | callId ="*";
|
| | | }
|
| | | if (StringUtils.isEmpty(stream)) {
|
| | | stream ="*";
|
| | | }
|
| | | String key = VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId() + "_" + deviceId + "_" + channelId + "_" + callId+ "_" + stream;
|
| | | List<Object> scanResult = redisUtil.scan(key);
|
| | | if (scanResult.size() == 0) return null;
|
| | | if (scanResult.size() == 0) {
|
| | | return null;
|
| | | }
|
| | | List<SsrcTransaction> result = new ArrayList<>();
|
| | | for (Object keyObj : scanResult) {
|
| | | result.add((SsrcTransaction)redisUtil.get((String) keyObj));
|
| | |
| | |
|
| | | public String getMediaServerId(String deviceId, String channelId, String stream){
|
| | | SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, null, stream);
|
| | | if (ssrcTransaction == null) return null;
|
| | | if (ssrcTransaction == null) {
|
| | | return null;
|
| | | }
|
| | | return ssrcTransaction.getMediaServerId();
|
| | | }
|
| | |
|
| | | public String getSSRC(String deviceId, String channelId, String stream){
|
| | | SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, null, stream);
|
| | | if (ssrcTransaction == null) return null;
|
| | | if (ssrcTransaction == null) {
|
| | | return null;
|
| | | }
|
| | | return ssrcTransaction.getSsrc();
|
| | | }
|
| | |
|
| | | public void remove(String deviceId, String channelId, String stream) {
|
| | | SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, null, stream);
|
| | | if (ssrcTransaction == null) return;
|
| | | if (ssrcTransaction == null) {
|
| | | return;
|
| | | }
|
| | | redisUtil.del(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId() + "_"
|
| | | + deviceId + "_" + channelId + "_" + ssrcTransaction.getCallId() + "_" + ssrcTransaction.getStream());
|
| | | }
|
| | |
| | | |
| | | import javax.sip.DialogState; |
| | | |
| | | /** |
| | | * @author lin |
| | | */ |
| | | public interface ISubscribeTask extends Runnable{ |
| | | void stop(); |
| | | |
| | |
| | | package com.genersoft.iot.vmp.gb28181.task.impl; |
| | | |
| | | import com.genersoft.iot.vmp.conf.DynamicTask; |
| | | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| | | import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.scheduling.annotation.Async; |
| | | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; |
| | | |
| | | import javax.sip.Dialog; |
| | | import javax.sip.DialogState; |
| | |
| | | |
| | | /** |
| | | * 目录订阅任务 |
| | | * @author lin |
| | | */ |
| | | public class CatalogSubscribeTask implements ISubscribeTask { |
| | | private final Logger logger = LoggerFactory.getLogger(CatalogSubscribeTask.class); |
| | |
| | | private final ISIPCommander sipCommander; |
| | | private Dialog dialog; |
| | | |
| | | private Timer timer ; |
| | | private DynamicTask dynamicTask; |
| | | |
| | | public CatalogSubscribeTask(Device device, ISIPCommander sipCommander) { |
| | | private String taskKey = "catalog-subscribe-timeout"; |
| | | |
| | | |
| | | public CatalogSubscribeTask(Device device, ISIPCommander sipCommander, DynamicTask dynamicTask) { |
| | | this.device = device; |
| | | this.sipCommander = sipCommander; |
| | | this.dynamicTask = dynamicTask; |
| | | } |
| | | |
| | | @Override |
| | | public void run() { |
| | | if (timer != null ) { |
| | | timer.cancel(); |
| | | timer = null; |
| | | if (dynamicTask.get(taskKey) != null) { |
| | | dynamicTask.stop(taskKey); |
| | | } |
| | | sipCommander.catalogSubscribe(device, dialog, eventResult -> { |
| | | if (eventResult.dialog != null || eventResult.dialog.getState().equals(DialogState.CONFIRMED)) { |
| | |
| | | dialog = null; |
| | | // 失败 |
| | | logger.warn("[目录订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg); |
| | | timer = new Timer(); |
| | | timer.schedule(new TimerTask() { |
| | | @Override |
| | | public void run() { |
| | | CatalogSubscribeTask.this.run(); |
| | | } |
| | | }, 2000); |
| | | dynamicTask.startDelay(taskKey, CatalogSubscribeTask.this, 2000); |
| | | }); |
| | | } |
| | | |
| | |
| | | * TERMINATED-> Terminated Dialog状态-终止 |
| | | */ |
| | | logger.info("取消目录订阅时dialog状态为{}", DialogState.CONFIRMED); |
| | | if (timer != null ) { |
| | | timer.cancel(); |
| | | timer = null; |
| | | if (dynamicTask.get(taskKey) != null) { |
| | | dynamicTask.stop(taskKey); |
| | | } |
| | | if (dialog != null && dialog.getState().equals(DialogState.CONFIRMED)) { |
| | | device.setSubscribeCycleForCatalog(0); |
| | |
| | | |
| | | @Override |
| | | public DialogState getDialogState() { |
| | | if (dialog == null) return null; |
| | | if (dialog == null) { |
| | | return null; |
| | | } |
| | | return dialog.getState(); |
| | | } |
| | | } |
| | |
| | | package com.genersoft.iot.vmp.gb28181.task.impl; |
| | | |
| | | import com.genersoft.iot.vmp.conf.DynamicTask; |
| | | import com.genersoft.iot.vmp.gb28181.bean.*; |
| | | import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; |
| | |
| | | |
| | | /** |
| | | * 向已经订阅(移动位置)的上级发送MobilePosition消息 |
| | | * @author lin |
| | | */ |
| | | public class MobilePositionSubscribeHandlerTask implements ISubscribeTask { |
| | | |
| | |
| | | private ISIPCommanderForPlatform sipCommanderForPlatform; |
| | | private SubscribeHolder subscribeHolder; |
| | | private ParentPlatform platform; |
| | | |
| | | private String sn; |
| | | private String key; |
| | | |
| | | public MobilePositionSubscribeHandlerTask(IRedisCatchStorage redisCatchStorage, ISIPCommanderForPlatform sipCommanderForPlatform, IVideoManagerStorage storager, String platformId, String sn, String key, SubscribeHolder subscribeInfo) { |
| | | public MobilePositionSubscribeHandlerTask(IRedisCatchStorage redisCatchStorage, |
| | | ISIPCommanderForPlatform sipCommanderForPlatform, |
| | | IVideoManagerStorage storager, |
| | | String platformId, |
| | | String sn, |
| | | String key, |
| | | SubscribeHolder subscribeInfo, |
| | | DynamicTask dynamicTask) { |
| | | this.redisCatchStorage = redisCatchStorage; |
| | | this.storager = storager; |
| | | this.platform = storager.queryParentPlatByServerGBId(platformId); |
| | |
| | | @Override |
| | | public void run() { |
| | | |
| | | if (platform == null) return; |
| | | if (platform == null) { |
| | | return; |
| | | } |
| | | SubscribeInfo subscribe = subscribeHolder.getMobilePositionSubscribe(platform.getServerGBId()); |
| | | if (subscribe != null) { |
| | | |
| | |
| | | package com.genersoft.iot.vmp.gb28181.task.impl; |
| | | |
| | | import com.genersoft.iot.vmp.conf.DynamicTask; |
| | | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| | | import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; |
| | |
| | | |
| | | /** |
| | | * 移动位置订阅的定时更新 |
| | | * @author lin |
| | | */ |
| | | public class MobilePositionSubscribeTask implements ISubscribeTask { |
| | | private final Logger logger = LoggerFactory.getLogger(MobilePositionSubscribeTask.class); |
| | | private Device device; |
| | | private ISIPCommander sipCommander; |
| | | private Dialog dialog; |
| | | private DynamicTask dynamicTask; |
| | | private String taskKey = "mobile-position-subscribe-timeout"; |
| | | |
| | | private Timer timer ; |
| | | |
| | | public MobilePositionSubscribeTask(Device device, ISIPCommander sipCommander) { |
| | | public MobilePositionSubscribeTask(Device device, ISIPCommander sipCommander, DynamicTask dynamicTask) { |
| | | this.device = device; |
| | | this.sipCommander = sipCommander; |
| | | this.dynamicTask = dynamicTask; |
| | | } |
| | | |
| | | @Override |
| | | public void run() { |
| | | if (timer != null ) { |
| | | timer.cancel(); |
| | | timer = null; |
| | | if (dynamicTask.get(taskKey) != null) { |
| | | dynamicTask.stop(taskKey); |
| | | } |
| | | sipCommander.mobilePositionSubscribe(device, dialog, eventResult -> { |
| | | // if (eventResult.dialog != null || eventResult.dialog.getState().equals(DialogState.CONFIRMED)) { |
| | |
| | | dialog = null; |
| | | // 失败 |
| | | logger.warn("[移动位置订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg); |
| | | timer = new Timer(); |
| | | timer.schedule(new TimerTask() { |
| | | @Override |
| | | public void run() { |
| | | MobilePositionSubscribeTask.this.run(); |
| | | } |
| | | }, 2000); |
| | | dynamicTask.startDelay(taskKey, MobilePositionSubscribeTask.this, 2000); |
| | | }); |
| | | |
| | | } |
| | |
| | | * COMPLETED-> Completed Dialog状态-已完成 |
| | | * TERMINATED-> Terminated Dialog状态-终止 |
| | | */ |
| | | if (timer != null ) { |
| | | timer.cancel(); |
| | | timer = null; |
| | | if (dynamicTask.get(taskKey) != null) { |
| | | dynamicTask.stop(taskKey); |
| | | } |
| | | if (dialog != null && dialog.getState().equals(DialogState.CONFIRMED)) { |
| | | logger.info("取消移动订阅时dialog状态为{}", dialog.getState()); |
| | |
| | | } |
| | | @Override |
| | | public DialogState getDialogState() { |
| | | if (dialog == null) return null; |
| | | if (dialog == null) { |
| | | return null; |
| | | } |
| | | return dialog.getState(); |
| | | } |
| | | } |
| | |
| | | * @param processor 处理程序 |
| | | */ |
| | | public void addTimeoutProcessor(ITimeoutProcessor processor) { |
| | | this.timeoutProcessor = processor; |
| | | timeoutProcessor = processor; |
| | | } |
| | | |
| | | /** |
| | |
| | | this.recordInfo = recordInfo; |
| | | } |
| | | |
| | | @Override |
| | | public void run() { |
| | | |
| | | String cacheKey = this.key; |
| | |
| | |
|
| | | public DeferredResult get(String key, String id) {
|
| | | Map<String, DeferredResult> deferredResultMap = map.get(key);
|
| | | if (deferredResultMap == null) return null;
|
| | | if (deferredResultMap == null) {
|
| | | return null;
|
| | | }
|
| | | return deferredResultMap.get(id);
|
| | | }
|
| | |
|
| | | public boolean exist(String key, String id){
|
| | | if (key == null) return false;
|
| | | if (key == null) {
|
| | | return false;
|
| | | }
|
| | | Map<String, DeferredResult> deferredResultMap = map.get(key);
|
| | | if (id == null) {
|
| | | return deferredResultMap != null;
|
| | |
| | | public Request createInfoRequest(Device device, StreamInfo streamInfo, String content)
|
| | | throws PeerUnavailableException, ParseException, InvalidArgumentException {
|
| | | Request request = null;
|
| | | if (streamInfo == null) return null;
|
| | | if (streamInfo == null) {
|
| | | return null;
|
| | | }
|
| | | Dialog dialog = streamSession.getDialogByStream(streamInfo.getDeviceID(), streamInfo.getChannelId(), streamInfo.getStream());
|
| | | if (dialog == null) return null;
|
| | | if (dialog == null) {
|
| | | return null;
|
| | | }
|
| | |
|
| | | SipURI requestLine = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(),
|
| | | device.getHostAddress());
|
| | |
| | | ZLMHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) {
|
| | | String streamId = ssrcInfo.getStream();
|
| | | try {
|
| | | if (device == null) return;
|
| | | if (device == null) {
|
| | | return;
|
| | | }
|
| | | String streamMode = device.getStreamMode().toUpperCase();
|
| | |
|
| | | logger.info("{} 分配的ZLM为: {} [{}:{}]", streamId, mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort());
|
| | |
| | | if (callId != null) {
|
| | | dialog = streamSession.getDialogByCallId(deviceId, channelId, callId);
|
| | | }else {
|
| | | if (stream == null) return;
|
| | | if (stream == null) {
|
| | | return;
|
| | | }
|
| | | dialog = streamSession.getDialogByStream(deviceId, channelId, stream);
|
| | | }
|
| | | if (ssrcTransaction != null) {
|
| | |
| | | * @param device 视频设备
|
| | | * @return true = 命令发送成功
|
| | | */
|
| | | @Override
|
| | | public boolean mobilePositionSubscribe(Device device, Dialog dialog, SipSubscribe.Event okEvent ,SipSubscribe.Event errorEvent) {
|
| | | try {
|
| | | StringBuffer subscribePostitionXml = new StringBuffer(200);
|
| | |
| | | * @param endTime 报警发生终止时间(可选)
|
| | | * @return true = 命令发送成功
|
| | | */
|
| | | @Override
|
| | | public boolean alarmSubscribe(Device device, int expires, String startPriority, String endPriority, String alarmMethod, String alarmType, String startTime, String endTime) {
|
| | | try {
|
| | | StringBuffer cmdXml = new StringBuffer(200);
|
| | |
| | | content.append("CSeq: " + cseq + "\r\n");
|
| | | content.append("Range: npt=now-\r\n");
|
| | | Request request = headerProvider.createInfoRequest(device, streamInfo, content.toString());
|
| | | if (request == null) return;
|
| | | if (request == null) {
|
| | | return;
|
| | | }
|
| | | logger.info(request.toString());
|
| | | ClientTransaction clientTransaction = null;
|
| | | if ("TCP".equals(device.getTransport())) {
|
| | |
| | | content.append("Range: npt=" + Math.abs(seekTime) + "-\r\n");
|
| | |
|
| | | Request request = headerProvider.createInfoRequest(device, streamInfo, content.toString());
|
| | | if (request == null) return;
|
| | | if (request == null) {
|
| | | return;
|
| | | }
|
| | | logger.info(request.toString());
|
| | | ClientTransaction clientTransaction = null;
|
| | | if ("TCP".equals(device.getTransport())) {
|
| | |
| | | content.append("CSeq: " + cseq + "\r\n");
|
| | | content.append("Scale: " + String.format("%.1f",speed) + "\r\n");
|
| | | Request request = headerProvider.createInfoRequest(device, streamInfo, content.toString());
|
| | | if (request == null) return;
|
| | | if (request == null) {
|
| | | return;
|
| | | }
|
| | | logger.info(request.toString());
|
| | | ClientTransaction clientTransaction = null;
|
| | | if ("TCP".equals(device.getTransport())) {
|
| | |
| | | // 设置编码, 防止中文乱码
|
| | | messageFactory.setDefaultContentEncodingCharset(characterSet);
|
| | | Dialog dialog = subscribeInfo.getDialog();
|
| | | if (dialog == null || !dialog.getState().equals(DialogState.CONFIRMED)) return;
|
| | | if (dialog == null || !dialog.getState().equals(DialogState.CONFIRMED)) {
|
| | | return;
|
| | | }
|
| | | SIPRequest notifyRequest = (SIPRequest)dialog.createRequest(Request.NOTIFY);
|
| | | ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
|
| | | notifyRequest.setContent(catalogXmlContent, contentTypeHeader);
|
| | |
| | | // 设置编码, 防止中文乱码 |
| | | messageFactory.setDefaultContentEncodingCharset(characterSet); |
| | | Dialog dialog = subscribeInfo.getDialog(); |
| | | if (dialog == null || !dialog.getState().equals(DialogState.CONFIRMED)) return; |
| | | if (dialog == null || !dialog.getState().equals(DialogState.CONFIRMED)) { |
| | | return; |
| | | } |
| | | SIPRequest notifyRequest = (SIPRequest)dialog.createRequest(Request.NOTIFY); |
| | | ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml"); |
| | | notifyRequest.setContent(catalogXmlContent, contentTypeHeader); |
| | |
| | | serverTransaction.sendResponse(response); |
| | | if (statusCode >= 200 && !"NOTIFY".equals(evt.getRequest().getMethod())) { |
| | | |
| | | if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete(); |
| | | if (serverTransaction.getDialog() != null) { |
| | | serverTransaction.getDialog().delete(); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | ServerTransaction serverTransaction = getServerTransaction(evt); |
| | | serverTransaction.sendResponse(response); |
| | | if (statusCode >= 200 && !"NOTIFY".equals(evt.getRequest().getMethod())) { |
| | | if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete(); |
| | | if (serverTransaction.getDialog() != null) { |
| | | serverTransaction.getDialog().delete(); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | return getRootElement(evt, "gb2312"); |
| | | } |
| | | public Element getRootElement(RequestEvent evt, String charset) throws DocumentException { |
| | | if (charset == null) charset = "gb2312"; |
| | | if (charset == null) { |
| | | charset = "gb2312"; |
| | | } |
| | | Request request = evt.getRequest(); |
| | | SAXReader reader = new SAXReader(); |
| | | reader.setEncoding(charset); |
| | |
| | | public void process(RequestEvent evt) { |
| | | Dialog dialog = evt.getDialog(); |
| | | CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME); |
| | | if (dialog == null) return; |
| | | if (dialog == null) { |
| | | return; |
| | | } |
| | | if (dialog.getState()== DialogState.CONFIRMED) { |
| | | String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser(); |
| | | logger.info("ACK请求: platformGbId->{}", platformGbId); |
| | |
| | | responseAck(evt, Response.OK); |
| | | Dialog dialog = evt.getDialog(); |
| | | CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME); |
| | | if (dialog == null) return; |
| | | if (dialog == null) { |
| | | return; |
| | | } |
| | | if (dialog.getState().equals(DialogState.TERMINATED)) { |
| | | String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser(); |
| | | String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser(); |
| | |
| | | response = getMessageFactory().createResponse(event.statusCode, evt.getRequest()); |
| | | ServerTransaction serverTransaction = getServerTransaction(evt); |
| | | serverTransaction.sendResponse(response); |
| | | if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete(); |
| | | if (serverTransaction.getDialog() != null) { |
| | | serverTransaction.getDialog().delete(); |
| | | } |
| | | } catch (ParseException | SipException | InvalidArgumentException e) { |
| | | e.printStackTrace(); |
| | | } |
| | |
| | | response = getMessageFactory().createResponse(Response.BAD_REQUEST, request); |
| | | ServerTransaction serverTransaction = getServerTransaction(evt); |
| | | serverTransaction.sendResponse(response); |
| | | if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete(); |
| | | if (serverTransaction.getDialog() != null) { |
| | | serverTransaction.getDialog().delete(); |
| | | } |
| | | return; |
| | | } |
| | | // 添加Contact头 |
| | |
| | | return; |
| | | } |
| | | serverTransaction.sendResponse(response); |
| | | if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete(); |
| | | if (serverTransaction.getDialog() != null) { |
| | | serverTransaction.getDialog().delete(); |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | /** |
| | | * SIP命令类型: SUBSCRIBE请求 |
| | | * @author lin |
| | | */ |
| | | @Component |
| | | public class SubscribeRequestProcessor extends SIPRequestProcessorParent implements InitializingBean, ISIPRequestProcessor { |
| | | |
| | | private Logger logger = LoggerFactory.getLogger(SubscribeRequestProcessor.class); |
| | | private String method = "SUBSCRIBE"; |
| | | private final Logger logger = LoggerFactory.getLogger(SubscribeRequestProcessor.class); |
| | | private final String method = "SUBSCRIBE"; |
| | | |
| | | @Autowired |
| | | private SIPProcessorObserver sipProcessorObserver; |
| | | |
| | | @Autowired |
| | | private IRedisCatchStorage redisCatchStorage; |
| | | |
| | | @Autowired |
| | | private ISIPCommanderForPlatform sipCommanderForPlatform; |
| | | |
| | | @Autowired |
| | | private IVideoManagerStorage storager; |
| | |
| | | /** |
| | | * 处理SUBSCRIBE请求 |
| | | * |
| | | * @param evt |
| | | * @param evt 事件 |
| | | */ |
| | | @Override |
| | | public void process(RequestEvent evt) { |
| | |
| | | } else { |
| | | logger.info("接收到消息:" + cmd); |
| | | |
| | | Response response = null; |
| | | response = getMessageFactory().createResponse(200, request); |
| | | Response response = getMessageFactory().createResponse(200, request); |
| | | if (response != null) { |
| | | ExpiresHeader expireHeader = getHeaderFactory().createExpiresHeader(30); |
| | | response.setExpires(expireHeader); |
| | | } |
| | | logger.info("response : " + response.toString()); |
| | | logger.info("response : " + response); |
| | | ServerTransaction transaction = getServerTransaction(evt); |
| | | if (transaction != null) { |
| | | transaction.sendResponse(response); |
| | |
| | | logger.info("processRequest serverTransactionId is null."); |
| | | } |
| | | } |
| | | } catch (ParseException e) { |
| | | e.printStackTrace(); |
| | | } catch (SipException e) { |
| | | e.printStackTrace(); |
| | | } catch (InvalidArgumentException e) { |
| | | e.printStackTrace(); |
| | | } catch (DocumentException e) { |
| | | } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | |
| | | */ |
| | | private void processNotifyMobilePosition(RequestEvent evt, Element rootElement) throws SipException { |
| | | String platformId = SipUtils.getUserIdFromFromHeader(evt.getRequest()); |
| | | String deviceID = XmlUtil.getText(rootElement, "DeviceID"); |
| | | String deviceId = XmlUtil.getText(rootElement, "DeviceID"); |
| | | ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId); |
| | | SubscribeInfo subscribeInfo = new SubscribeInfo(evt, platformId); |
| | | if (platform == null) { |
| | | return; |
| | | } |
| | | if (evt.getServerTransaction() == null) { |
| | | ServerTransaction serverTransaction = platform.getTransport().equals("TCP") ? tcpSipProvider.getNewServerTransaction(evt.getRequest()) |
| | | ServerTransaction serverTransaction = "TCP".equals(platform.getTransport()) ? tcpSipProvider.getNewServerTransaction(evt.getRequest()) |
| | | : udpSipProvider.getNewServerTransaction(evt.getRequest()); |
| | | subscribeInfo.setTransaction(serverTransaction); |
| | | Dialog dialog = serverTransaction.getDialog(); |
| | |
| | | resultXml.append("<?xml version=\"1.0\" ?>\r\n") |
| | | .append("<Response>\r\n") |
| | | .append("<CmdType>MobilePosition</CmdType>\r\n") |
| | | .append("<SN>" + sn + "</SN>\r\n") |
| | | .append("<DeviceID>" + deviceID + "</DeviceID>\r\n") |
| | | .append("<SN>").append(sn).append("</SN>\r\n") |
| | | .append("<DeviceID>").append(deviceId).append("</DeviceID>\r\n") |
| | | .append("<Result>OK</Result>\r\n") |
| | | .append("</Response>\r\n"); |
| | | |
| | | if (subscribeInfo.getExpires() > 0) { |
| | | String interval = XmlUtil.getText(rootElement, "Interval"); // GPS上报时间间隔 |
| | | // GPS上报时间间隔 |
| | | String interval = XmlUtil.getText(rootElement, "Interval"); |
| | | if (interval == null) { |
| | | subscribeInfo.setGpsInterval(5); |
| | | }else { |
| | |
| | | |
| | | subscribeInfo.setSn(sn); |
| | | subscribeHolder.putMobilePositionSubscribe(platformId, subscribeInfo); |
| | | // if (subscribeHolder.getMobilePositionSubscribe(platformId) == null ) { |
| | | // subscribeHolder.putMobilePositionSubscribe(platformId, subscribeInfo); |
| | | // }else { |
| | | // if (subscribeHolder.getMobilePositionSubscribe(platformId).getDialog() != null |
| | | // && subscribeHolder.getMobilePositionSubscribe(platformId).getDialog().getState() != null |
| | | // && !subscribeHolder.getMobilePositionSubscribe(platformId).getDialog().getState().equals(DialogState.CONFIRMED)) { |
| | | // subscribeHolder.putMobilePositionSubscribe(platformId, subscribeInfo); |
| | | // } |
| | | // } |
| | | |
| | | }else if (subscribeInfo.getExpires() == 0) { |
| | | subscribeHolder.removeMobilePositionSubscribe(platformId); |
| | | } |
| | |
| | | try { |
| | | ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformId); |
| | | responseXmlAck(evt, resultXml.toString(), parentPlatform); |
| | | } catch (SipException e) { |
| | | e.printStackTrace(); |
| | | } catch (InvalidArgumentException e) { |
| | | e.printStackTrace(); |
| | | } catch (ParseException e) { |
| | | } catch (SipException | InvalidArgumentException | ParseException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | |
| | | |
| | | private void processNotifyCatalogList(RequestEvent evt, Element rootElement) throws SipException { |
| | | String platformId = SipUtils.getUserIdFromFromHeader(evt.getRequest()); |
| | | String deviceID = XmlUtil.getText(rootElement, "DeviceID"); |
| | | String deviceId = XmlUtil.getText(rootElement, "DeviceID"); |
| | | ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId); |
| | | if (platform == null)return; |
| | | if (platform == null){ |
| | | return; |
| | | } |
| | | SubscribeInfo subscribeInfo = new SubscribeInfo(evt, platformId); |
| | | if (evt.getServerTransaction() == null) { |
| | | ServerTransaction serverTransaction = platform.getTransport().equals("TCP") ? tcpSipProvider.getNewServerTransaction(evt.getRequest()) |
| | | ServerTransaction serverTransaction = "TCP".equals(platform.getTransport()) ? tcpSipProvider.getNewServerTransaction(evt.getRequest()) |
| | | : udpSipProvider.getNewServerTransaction(evt.getRequest()); |
| | | subscribeInfo.setTransaction(serverTransaction); |
| | | Dialog dialog = serverTransaction.getDialog(); |
| | |
| | | subscribeInfo.setDialog(dialog); |
| | | } |
| | | String sn = XmlUtil.getText(rootElement, "SN"); |
| | | logger.info("[回复 目录订阅]: {}/{}", platformId, deviceID); |
| | | logger.info("[回复 目录订阅]: {}/{}", platformId, deviceId); |
| | | StringBuilder resultXml = new StringBuilder(200); |
| | | resultXml.append("<?xml version=\"1.0\" ?>\r\n") |
| | | .append("<Response>\r\n") |
| | | .append("<CmdType>Catalog</CmdType>\r\n") |
| | | .append("<SN>" + sn + "</SN>\r\n") |
| | | .append("<DeviceID>" + deviceID + "</DeviceID>\r\n") |
| | | .append("<SN>").append(sn).append("</SN>\r\n") |
| | | .append("<DeviceID>").append(deviceId).append("</DeviceID>\r\n") |
| | | .append("<Result>OK</Result>\r\n") |
| | | .append("</Response>\r\n"); |
| | | |
| | |
| | | try { |
| | | ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformId); |
| | | responseXmlAck(evt, resultXml.toString(), parentPlatform); |
| | | } catch (SipException e) { |
| | | e.printStackTrace(); |
| | | } catch (InvalidArgumentException e) { |
| | | e.printStackTrace(); |
| | | } catch (ParseException e) { |
| | | } catch (SipException | InvalidArgumentException | ParseException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | |
| | | * */ |
| | | public static String getChannelIdFromHeader(Request request) { |
| | | Header subject = request.getHeader("subject"); |
| | | if (subject == null) return null; |
| | | if (subject == null) { |
| | | return null; |
| | | } |
| | | return ((Subject) subject).getSubject().split(":")[0]; |
| | | } |
| | | |
| | |
| | | if (result == null) { |
| | | result = key.getString(s).equals(hookResponse.getString(s)); |
| | | }else { |
| | | if (key.getString(s) == null) continue; |
| | | if (key.getString(s) == null) { |
| | | continue; |
| | | } |
| | | result = result && key.getString(s).equals(hookResponse.getString(s)); |
| | | } |
| | | } |
| | |
| | | |
| | | // 使用异步的当时更新媒体流列表 |
| | | zlmresTfulUtils.getMediaList(mediaServerItem, (mediaList ->{ |
| | | if (mediaList == null) return; |
| | | if (mediaList == null) { |
| | | return; |
| | | } |
| | | String dataStr = mediaList.getString("data"); |
| | | |
| | | Integer code = mediaList.getInteger("code"); |
| | |
| | | //使用异步更新推流 |
| | | zlmresTfulUtils.getMediaList(mediaServerItem, app, streamId, "rtmp", json->{ |
| | | |
| | | if (json == null) return; |
| | | if (json == null) { |
| | | return; |
| | | } |
| | | String dataStr = json.getString("data"); |
| | | |
| | | Integer code = json.getInteger("code"); |
| | |
| | | private int[] portRangeArray = new int[2]; |
| | | |
| | | public int getFreePort(MediaServerItem mediaServerItem, int startPort, int endPort, List<Integer> usedFreelist) { |
| | | if (endPort <= startPort) return -1; |
| | | if (endPort <= startPort) { |
| | | return -1; |
| | | } |
| | | if (usedFreelist == null) { |
| | | usedFreelist = new ArrayList<>(); |
| | | } |
| | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.genersoft.iot.vmp.conf.DynamicTask; |
| | | import com.genersoft.iot.vmp.conf.MediaConfig; |
| | | import com.genersoft.iot.vmp.gb28181.event.EventPublisher; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| | |
| | | @Autowired |
| | | private MediaConfig mediaConfig; |
| | | |
| | | @Autowired |
| | | private DynamicTask dynamicTask; |
| | | |
| | | @Qualifier("taskExecutor") |
| | | @Autowired |
| | | private ThreadPoolTaskExecutor taskExecutor; |
| | |
| | | all.add(mediaConfig.getMediaSerItem()); |
| | | } |
| | | for (MediaServerItem mediaServerItem : all) { |
| | | if (startGetMedia == null) startGetMedia = new HashMap<>(); |
| | | if (startGetMedia == null) { |
| | | startGetMedia = new HashMap<>(); |
| | | } |
| | | startGetMedia.put(mediaServerItem.getId(), true); |
| | | taskExecutor.execute(()->{ |
| | | connectZlmServer(mediaServerItem); |
| | | }); |
| | | } |
| | | Timer timer = new Timer(); |
| | | // 10分钟后未连接到则不再去主动连接, TODO 并对重启前使用此在zlm的通道发送bye |
| | | timer.schedule(new TimerTask() { |
| | | @Override |
| | | public void run() { |
| | | String taskKey = "zlm-connect-timeout"; |
| | | dynamicTask.startDelay(taskKey, ()->{ |
| | | if (startGetMedia != null) { |
| | | Set<String> allZlmId = startGetMedia.keySet(); |
| | | for (String id : allZlmId) { |
| | | logger.error("[ {} ]]主动连接失败,不再主动连接", id); |
| | | logger.error("[ {} ]]主动连接失败,不再尝试连接", id); |
| | | } |
| | | startGetMedia = null; |
| | | } |
| | | // TODO 清理数据库中与redis不匹配的zlm |
| | | } |
| | | }, 60 * 1000 * 10); |
| | | // TODO 清理数据库中与redis不匹配的zlm |
| | | }, 6 * 1000 ); |
| | | } |
| | | |
| | | @Async |
| | |
| | | if ( startGetMedia.get(mediaServerItem.getId()) == null || !startGetMedia.get(mediaServerItem.getId())) { |
| | | return null; |
| | | } |
| | | JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); |
| | | ZLMServerConfig ZLMServerConfig = null; |
| | | if (responseJSON != null) { |
| | | JSONArray data = responseJSON.getJSONArray("data"); |
| | | JSONObject responseJson = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); |
| | | ZLMServerConfig zlmServerConfig = null; |
| | | if (responseJson != null) { |
| | | JSONArray data = responseJson.getJSONArray("data"); |
| | | if (data != null && data.size() > 0) { |
| | | ZLMServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class); |
| | | zlmServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class); |
| | | } |
| | | } else { |
| | | logger.error("[ {} ]-[ {}:{} ]第{}次主动连接失败, 2s后重试", |
| | |
| | | } catch (InterruptedException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | ZLMServerConfig = getMediaServerConfig(mediaServerItem, index += 1); |
| | | zlmServerConfig = getMediaServerConfig(mediaServerItem, index += 1); |
| | | } |
| | | return ZLMServerConfig; |
| | | return zlmServerConfig; |
| | | |
| | | } |
| | | |
| | |
| | | this.type = type; |
| | | } |
| | | |
| | | @Override |
| | | public String getApp() { |
| | | return app; |
| | | } |
| | | |
| | | @Override |
| | | public void setApp(String app) { |
| | | this.app = app; |
| | | } |
| | | |
| | | @Override |
| | | public String getStream() { |
| | | return stream; |
| | | } |
| | | |
| | | @Override |
| | | public void setStream(String stream) { |
| | | this.stream = stream; |
| | | } |
| | |
| | | this.id = id; |
| | | } |
| | | |
| | | @Override |
| | | public String getApp() { |
| | | return app; |
| | | } |
| | | |
| | | @Override |
| | | public void setApp(String app) { |
| | | this.app = app; |
| | | } |
| | | |
| | | @Override |
| | | public String getStream() { |
| | | return stream; |
| | | } |
| | | |
| | | @Override |
| | | public void setStream(String stream) { |
| | | this.stream = stream; |
| | | } |
| | |
| | | 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.scheduling.concurrent.ThreadPoolTaskExecutor; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.sip.DialogState; |
| | |
| | | } |
| | | logger.info("[添加目录订阅] 设备{}", device.getDeviceId()); |
| | | // 添加目录订阅 |
| | | CatalogSubscribeTask catalogSubscribeTask = new CatalogSubscribeTask(device, sipCommander); |
| | | CatalogSubscribeTask catalogSubscribeTask = new CatalogSubscribeTask(device, sipCommander, dynamicTask); |
| | | // 提前开始刷新订阅 |
| | | int subscribeCycleForCatalog = Math.max(device.getSubscribeCycleForCatalog(),30); |
| | | // 设置最小值为30 |
| | |
| | | } |
| | | logger.info("[添加移动位置订阅] 设备{}", device.getDeviceId()); |
| | | // 添加目录订阅 |
| | | MobilePositionSubscribeTask mobilePositionSubscribeTask = new MobilePositionSubscribeTask(device, sipCommander); |
| | | // 提前开始刷新订阅 |
| | | MobilePositionSubscribeTask mobilePositionSubscribeTask = new MobilePositionSubscribeTask(device, sipCommander, dynamicTask); |
| | | // 设置最小值为30 |
| | | int subscribeCycleForCatalog = Math.max(device.getSubscribeCycleForMobilePosition(),30); |
| | | // 提前开始刷新订阅 |
| | | dynamicTask.startCron(device.getDeviceId() + "mobile_position" , mobilePositionSubscribeTask, subscribeCycleForCatalog -1 ); |
| | | return true; |
| | | } |
| | |
| | | boolean result = false; |
| | | TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition); |
| | | ParentPlatform parentPlatform = platformMapper.getParentPlatByServerGBId(platformId); |
| | | if (catalogId == null) catalogId = parentPlatform.getCatalogId(); |
| | | if (catalogId == null) { |
| | | catalogId = parentPlatform.getCatalogId(); |
| | | } |
| | | try { |
| | | List<DeviceChannel> deviceChannelList = new ArrayList<>(); |
| | | for (GbStream gbStream : gbStreams) { |
| | |
| | | if (mediaList != null) { |
| | | if (mediaList.getInteger("code") == 0) { |
| | | JSONArray data = mediaList.getJSONArray("data"); |
| | | if (data == null) return null; |
| | | if (data == null) { |
| | | return null; |
| | | } |
| | | JSONObject mediaJSON = JSON.parseObject(JSON.toJSONString(data.get(0)), JSONObject.class); |
| | | JSONArray tracks = mediaJSON.getJSONArray("tracks"); |
| | | streamInfo = getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks); |
| | |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.genersoft.iot.vmp.common.StreamInfo; |
| | | import com.genersoft.iot.vmp.conf.DynamicTask; |
| | | import com.genersoft.iot.vmp.conf.UserSetting; |
| | | import com.genersoft.iot.vmp.gb28181.bean.*; |
| | | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; |
| | |
| | | @Autowired |
| | | private UserSetting userSetting; |
| | | |
| | | @Autowired |
| | | private DynamicTask dynamicTask; |
| | | |
| | | |
| | | |
| | | |
| | |
| | | String uuid = UUID.randomUUID().toString(); |
| | | msg.setId(uuid); |
| | | playResult.setUuid(uuid); |
| | | DeferredResult<ResponseEntity<String>> result = new DeferredResult<>(userSetting.getPlayTimeout()); |
| | | DeferredResult<ResponseEntity<String>> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue()); |
| | | playResult.setResult(result); |
| | | // 录像查询以channelId作为deviceId查询 |
| | | resultHolder.put(key, uuid, result); |
| | |
| | | } |
| | | |
| | | // 超时处理 |
| | | Timer timer = new Timer(); |
| | | String timeOutTaskKey = UUID.randomUUID().toString(); |
| | | SSRCInfo finalSsrcInfo = ssrcInfo; |
| | | timer.schedule(new TimerTask() { |
| | | @Override |
| | | public void run() { |
| | | logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", device.getDeviceId(), channelId)); |
| | | dynamicTask.startDelay( timeOutTaskKey,()->{ |
| | | logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", device.getDeviceId(), channelId)); |
| | | |
| | | SIPDialog dialog = streamSession.getDialogByStream(device.getDeviceId(), channelId, finalSsrcInfo.getStream()); |
| | | if (dialog != null) { |
| | | timeoutCallback.run(1, "收流超时"); |
| | | // 点播超时回复BYE 同时释放ssrc以及此次点播的资源 |
| | | cmder.streamByeCmd(device.getDeviceId(), channelId, finalSsrcInfo.getStream(), null); |
| | | }else { |
| | | timeoutCallback.run(0, "点播超时"); |
| | | mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc()); |
| | | mediaServerService.closeRTPServer(device.getDeviceId(), channelId, finalSsrcInfo.getStream()); |
| | | streamSession.remove(device.getDeviceId(), channelId, finalSsrcInfo.getStream()); |
| | | } |
| | | SIPDialog dialog = streamSession.getDialogByStream(device.getDeviceId(), channelId, finalSsrcInfo.getStream()); |
| | | if (dialog != null) { |
| | | timeoutCallback.run(1, "收流超时"); |
| | | // 点播超时回复BYE 同时释放ssrc以及此次点播的资源 |
| | | cmder.streamByeCmd(device.getDeviceId(), channelId, finalSsrcInfo.getStream(), null); |
| | | }else { |
| | | timeoutCallback.run(0, "点播超时"); |
| | | mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc()); |
| | | mediaServerService.closeRTPServer(device.getDeviceId(), channelId, finalSsrcInfo.getStream()); |
| | | streamSession.remove(device.getDeviceId(), channelId, finalSsrcInfo.getStream()); |
| | | } |
| | | }, userSetting.getPlayTimeout()); |
| | | }, userSetting.getPlayTimeout()*1000); |
| | | final String ssrc = ssrcInfo.getSsrc(); |
| | | cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> { |
| | | logger.info("收到订阅消息: " + response.toJSONString()); |
| | | timer.cancel(); |
| | | dynamicTask.stop(timeOutTaskKey); |
| | | // hook响应 |
| | | onPublishHandlerForPlay(mediaServerItemInuse, response, device.getDeviceId(), channelId, uuid); |
| | | hookEvent.response(mediaServerItemInuse, response); |
| | |
| | | } |
| | | } |
| | | }, (event) -> { |
| | | timer.cancel(); |
| | | dynamicTask.stop(timeOutTaskKey); |
| | | mediaServerService.closeRTPServer(device.getDeviceId(), channelId, finalSsrcInfo.getStream()); |
| | | // 释放ssrc |
| | | mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc()); |
| | |
| | | |
| | | @Override |
| | | public MediaServerItem getNewMediaServerItem(Device device) { |
| | | if (device == null) return null; |
| | | if (device == null) { |
| | | return null; |
| | | } |
| | | String mediaServerId = device.getMediaServerId(); |
| | | MediaServerItem mediaServerItem; |
| | | if (mediaServerId == null) { |
| | |
| | | String endTime,InviteStreamCallback inviteStreamCallback, |
| | | PlayBackCallback callback) { |
| | | Device device = storager.queryVideoDevice(deviceId); |
| | | if (device == null) return null; |
| | | if (device == null) { |
| | | return null; |
| | | } |
| | | MediaServerItem newMediaServerItem = getNewMediaServerItem(device); |
| | | SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, true); |
| | | |
| | |
| | | String deviceId, String channelId, String startTime, |
| | | String endTime, InviteStreamCallback infoCallBack, |
| | | PlayBackCallback playBackCallback) { |
| | | if (mediaServerItem == null || ssrcInfo == null) return null; |
| | | if (mediaServerItem == null || ssrcInfo == null) { |
| | | return null; |
| | | } |
| | | String uuid = UUID.randomUUID().toString(); |
| | | String key = DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId; |
| | | DeferredResult<ResponseEntity<String>> result = new DeferredResult<>(30000L); |
| | |
| | | msg.setId(uuid); |
| | | msg.setKey(key); |
| | | PlayBackResult<RequestMessage> playBackResult = new PlayBackResult<>(); |
| | | |
| | | Timer timer = new Timer(); |
| | | timer.schedule(new TimerTask() { |
| | | @Override |
| | | public void run() { |
| | | logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId)); |
| | | playBackResult.setCode(-1); |
| | | playBackResult.setData(msg); |
| | | playBackCallback.call(playBackResult); |
| | | SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, ssrcInfo.getStream()); |
| | | String playBackTimeOutTaskKey = UUID.randomUUID().toString(); |
| | | dynamicTask.startDelay(playBackTimeOutTaskKey, ()->{ |
| | | logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId)); |
| | | playBackResult.setCode(-1); |
| | | playBackResult.setData(msg); |
| | | playBackCallback.call(playBackResult); |
| | | SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, ssrcInfo.getStream()); |
| | | // 点播超时回复BYE 同时释放ssrc以及此次点播的资源 |
| | | if (dialog != null) { |
| | | // 点播超时回复BYE 同时释放ssrc以及此次点播的资源 |
| | | if (dialog != null) { |
| | | // 点播超时回复BYE 同时释放ssrc以及此次点播的资源 |
| | | cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream(), null); |
| | | }else { |
| | | mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); |
| | | mediaServerService.closeRTPServer(deviceId, channelId, ssrcInfo.getStream()); |
| | | streamSession.remove(deviceId, channelId, ssrcInfo.getStream()); |
| | | } |
| | | cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream(), null); |
| | | // 回复之前所有的点播请求 |
| | | playBackCallback.call(playBackResult); |
| | | }else { |
| | | mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); |
| | | mediaServerService.closeRTPServer(deviceId, channelId, ssrcInfo.getStream()); |
| | | streamSession.remove(deviceId, channelId, ssrcInfo.getStream()); |
| | | } |
| | | }, userSetting.getPlayTimeout()); |
| | | cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream(), null); |
| | | // 回复之前所有的点播请求 |
| | | playBackCallback.call(playBackResult); |
| | | }, userSetting.getPlayTimeout()*1000); |
| | | |
| | | cmder.playbackStreamCmd(mediaServerItem, ssrcInfo, device, channelId, startTime, endTime, infoCallBack, |
| | | (InviteStreamInfo inviteStreamInfo) -> { |
| | | logger.info("收到订阅消息: " + inviteStreamInfo.getResponse().toJSONString()); |
| | | timer.cancel(); |
| | | dynamicTask.stop(playBackTimeOutTaskKey); |
| | | StreamInfo streamInfo = onPublishHandler(inviteStreamInfo.getMediaServerItem(), inviteStreamInfo.getResponse(), deviceId, channelId); |
| | | if (streamInfo == null) { |
| | | logger.warn("设备回放API调用失败!"); |
| | |
| | | playBackResult.setResponse(inviteStreamInfo.getResponse()); |
| | | playBackCallback.call(playBackResult); |
| | | }, event -> { |
| | | timer.cancel(); |
| | | dynamicTask.stop(playBackTimeOutTaskKey); |
| | | msg.setData(String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg)); |
| | | playBackResult.setCode(-1); |
| | | playBackResult.setData(msg); |
| | |
| | | @Override |
| | | public DeferredResult<ResponseEntity<String>> download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack) { |
| | | Device device = storager.queryVideoDevice(deviceId); |
| | | if (device == null) return null; |
| | | if (device == null) { |
| | | return null; |
| | | } |
| | | MediaServerItem newMediaServerItem = getNewMediaServerItem(device); |
| | | SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, true); |
| | | |
| | |
| | | |
| | | @Override |
| | | public DeferredResult<ResponseEntity<String>> download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack) { |
| | | if (mediaServerItem == null || ssrcInfo == null) return null; |
| | | if (mediaServerItem == null || ssrcInfo == null) { |
| | | return null; |
| | | } |
| | | String uuid = UUID.randomUUID().toString(); |
| | | String key = DeferredResultHolder.CALLBACK_CMD_DOWNLOAD + deviceId + channelId; |
| | | DeferredResult<ResponseEntity<String>> result = new DeferredResult<>(30000L); |
| | |
| | | PlayBackResult<RequestMessage> downloadResult = new PlayBackResult<>(); |
| | | downloadResult.setData(msg); |
| | | |
| | | Timer timer = new Timer(); |
| | | timer.schedule(new TimerTask() { |
| | | @Override |
| | | public void run() { |
| | | logger.warn(String.format("录像下载请求超时,deviceId:%s ,channelId:%s", deviceId, channelId)); |
| | | wvpResult.setCode(-1); |
| | | wvpResult.setMsg("录像下载请求超时"); |
| | | downloadResult.setCode(-1); |
| | | hookCallBack.call(downloadResult); |
| | | SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, ssrcInfo.getStream()); |
| | | String downLoadTimeOutTaskKey = UUID.randomUUID().toString(); |
| | | dynamicTask.startDelay(downLoadTimeOutTaskKey, ()->{ |
| | | logger.warn(String.format("录像下载请求超时,deviceId:%s ,channelId:%s", deviceId, channelId)); |
| | | wvpResult.setCode(-1); |
| | | wvpResult.setMsg("录像下载请求超时"); |
| | | downloadResult.setCode(-1); |
| | | hookCallBack.call(downloadResult); |
| | | SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, ssrcInfo.getStream()); |
| | | // 点播超时回复BYE 同时释放ssrc以及此次点播的资源 |
| | | if (dialog != null) { |
| | | // 点播超时回复BYE 同时释放ssrc以及此次点播的资源 |
| | | if (dialog != null) { |
| | | // 点播超时回复BYE 同时释放ssrc以及此次点播的资源 |
| | | cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream(), null); |
| | | }else { |
| | | mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); |
| | | mediaServerService.closeRTPServer(deviceId, channelId, ssrcInfo.getStream()); |
| | | streamSession.remove(deviceId, channelId, ssrcInfo.getStream()); |
| | | } |
| | | cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream(), null); |
| | | // 回复之前所有的点播请求 |
| | | hookCallBack.call(downloadResult); |
| | | }else { |
| | | mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); |
| | | mediaServerService.closeRTPServer(deviceId, channelId, ssrcInfo.getStream()); |
| | | streamSession.remove(deviceId, channelId, ssrcInfo.getStream()); |
| | | } |
| | | }, userSetting.getPlayTimeout()); |
| | | cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream(), null); |
| | | // 回复之前所有的点播请求 |
| | | hookCallBack.call(downloadResult); |
| | | }, userSetting.getPlayTimeout()*1000); |
| | | cmder.downloadStreamCmd(mediaServerItem, ssrcInfo, device, channelId, startTime, endTime, downloadSpeed, infoCallBack, |
| | | inviteStreamInfo -> { |
| | | logger.info("收到订阅消息: " + inviteStreamInfo.getResponse().toJSONString()); |
| | | timer.cancel(); |
| | | dynamicTask.stop(downLoadTimeOutTaskKey); |
| | | StreamInfo streamInfo = onPublishHandler(inviteStreamInfo.getMediaServerItem(), inviteStreamInfo.getResponse(), deviceId, channelId); |
| | | streamInfo.setStartTime(startTime); |
| | | streamInfo.setEndTime(endTime); |
| | |
| | | downloadResult.setResponse(inviteStreamInfo.getResponse()); |
| | | hookCallBack.call(downloadResult); |
| | | }, event -> { |
| | | timer.cancel(); |
| | | dynamicTask.stop(downLoadTimeOutTaskKey); |
| | | downloadResult.setCode(-1); |
| | | wvpResult.setCode(-1); |
| | | wvpResult.setMsg(String.format("录像下载失败, 错误码: %s, %s", event.statusCode, event.msg)); |
| | |
| | | |
| | | @Override |
| | | public JSONObject removeStreamProxyFromZlm(StreamProxyItem param) { |
| | | if (param ==null) return null; |
| | | if (param ==null) { |
| | | return null; |
| | | } |
| | | MediaServerItem mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); |
| | | JSONObject result = zlmresTfulUtils.closeStreams(mediaServerItem, param.getApp(), param.getStream()); |
| | | return result; |
| | |
| | | StreamProxyItem streamProxy = videoManagerStorager.queryStreamProxy(app, stream); |
| | | if (!streamProxy.isEnable() && streamProxy != null) { |
| | | JSONObject jsonObject = addStreamProxyToZlm(streamProxy); |
| | | if (jsonObject == null) return false; |
| | | if (jsonObject == null) { |
| | | return false; |
| | | } |
| | | if (jsonObject.getInteger("code") == 0) { |
| | | result = true; |
| | | streamProxy.setEnable(true); |
| | |
| | | |
| | | @Override |
| | | public List<StreamPushItem> handleJSON(String jsonData, MediaServerItem mediaServerItem) { |
| | | if (jsonData == null) return null; |
| | | if (jsonData == null) { |
| | | return null; |
| | | } |
| | | |
| | | Map<String, StreamPushItem> result = new HashMap<>(); |
| | | |
| | |
| | | } |
| | | } |
| | | zlmresTfulUtils.getMediaList(mediaServerItem, (mediaList ->{ |
| | | if (mediaList == null) return; |
| | | if (mediaList == null) { |
| | | return; |
| | | } |
| | | String dataStr = mediaList.getString("data"); |
| | | |
| | | Integer code = mediaList.getInteger("code"); |
| | |
| | | @Override |
| | | public int addUser(User user) { |
| | | User userByUsername = userMapper.getUserByUsername(user.getUsername()); |
| | | if (userByUsername != null) return 0; |
| | | if (userByUsername != null) { |
| | | return 0; |
| | | } |
| | | return userMapper.add(user); |
| | | } |
| | | @Override |
| | |
| | | */ |
| | | @Override |
| | | public boolean stopPlay(StreamInfo streamInfo) { |
| | | if (streamInfo == null) return false; |
| | | if (streamInfo == null) { |
| | | return false; |
| | | } |
| | | return redis.del(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX, |
| | | userSetting.getServerId(), |
| | | streamInfo.getStream(), |
| | |
| | | @Override |
| | | public StreamInfo queryPlayByStreamId(String streamId) { |
| | | List<Object> playLeys = redis.scan(String.format("%S_%s_%s_*", VideoManagerConstants.PLAYER_PREFIX, userSetting.getServerId(), streamId)); |
| | | if (playLeys == null || playLeys.size() == 0) return null; |
| | | if (playLeys == null || playLeys.size() == 0) { |
| | | return null; |
| | | } |
| | | return (StreamInfo)redis.get(playLeys.get(0).toString()); |
| | | } |
| | | |
| | |
| | | userSetting.getServerId(), |
| | | deviceId, |
| | | channelId)); |
| | | if (playLeys == null || playLeys.size() == 0) return null; |
| | | if (playLeys == null || playLeys.size() == 0) { |
| | | return null; |
| | | } |
| | | return (StreamInfo)redis.get(playLeys.get(0).toString()); |
| | | } |
| | | |
| | |
| | | Map<String, StreamInfo> streamInfos = new HashMap<>(); |
| | | // List<Object> playLeys = redis.keys(String.format("%S_*_%S_*", VideoManagerConstants.PLAYER_PREFIX, deviceId)); |
| | | List<Object> players = redis.scan(String.format("%S_%s_*_%S_*", VideoManagerConstants.PLAYER_PREFIX, userSetting.getServerId(),deviceId)); |
| | | if (players.size() == 0) return streamInfos; |
| | | if (players.size() == 0) { |
| | | return streamInfos; |
| | | } |
| | | for (Object player : players) { |
| | | String key = (String) player; |
| | | StreamInfo streamInfo = (StreamInfo) redis.get(key); |
| | |
| | | deviceChannel.setDeviceId(deviceId); |
| | | deviceChannelMapper.update(deviceChannel); |
| | | } |
| | | if (deviceId == null) deviceId = "*"; |
| | | if (channelId == null) channelId = "*"; |
| | | if (stream == null) stream = "*"; |
| | | if (callId == null) callId = "*"; |
| | | if (deviceId == null) { |
| | | deviceId = "*"; |
| | | } |
| | | if (channelId == null) { |
| | | channelId = "*"; |
| | | } |
| | | if (stream == null) { |
| | | stream = "*"; |
| | | } |
| | | if (callId == null) { |
| | | callId = "*"; |
| | | } |
| | | String key = String.format("%S_%s_%s_%s_%s_%s", VideoManagerConstants.DOWNLOAD_PREFIX, |
| | | userSetting.getServerId(), |
| | | deviceId, |
| | |
| | | deviceChannel.setDeviceId(deviceId); |
| | | deviceChannelMapper.update(deviceChannel); |
| | | } |
| | | if (deviceId == null) deviceId = "*"; |
| | | if (channelId == null) channelId = "*"; |
| | | if (stream == null) stream = "*"; |
| | | if (callId == null) callId = "*"; |
| | | if (deviceId == null) { |
| | | deviceId = "*"; |
| | | } |
| | | if (channelId == null) { |
| | | channelId = "*"; |
| | | } |
| | | if (stream == null) { |
| | | stream = "*"; |
| | | } |
| | | if (callId == null) { |
| | | callId = "*"; |
| | | } |
| | | String key = String.format("%S_%s_%s_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, |
| | | userSetting.getServerId(), |
| | | deviceId, |
| | |
| | | if (stream == null && callId == null) { |
| | | return null; |
| | | } |
| | | if (deviceId == null) deviceId = "*"; |
| | | if (channelId == null) channelId = "*"; |
| | | if (stream == null) stream = "*"; |
| | | if (callId == null) callId = "*"; |
| | | if (deviceId == null) { |
| | | deviceId = "*"; |
| | | } |
| | | if (channelId == null) { |
| | | channelId = "*"; |
| | | } |
| | | if (stream == null) { |
| | | stream = "*"; |
| | | } |
| | | if (callId == null) { |
| | | callId = "*"; |
| | | } |
| | | String key = String.format("%S_%s_%s_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, |
| | | userSetting.getServerId(), |
| | | deviceId, |
| | |
| | | |
| | | @Override |
| | | public SendRtpItem querySendRTPServer(String platformGbId, String channelId, String streamId, String callId) { |
| | | if (platformGbId == null) platformGbId = "*"; |
| | | if (channelId == null) channelId = "*"; |
| | | if (streamId == null) streamId = "*"; |
| | | if (callId == null) callId = "*"; |
| | | if (platformGbId == null) { |
| | | platformGbId = "*"; |
| | | } |
| | | if (channelId == null) { |
| | | channelId = "*"; |
| | | } |
| | | if (streamId == null) { |
| | | streamId = "*"; |
| | | } |
| | | if (callId == null) { |
| | | callId = "*"; |
| | | } |
| | | String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + userSetting.getServerId() + "_" + platformGbId |
| | | + "_" + channelId + "_" + streamId + "_" + callId; |
| | | List<Object> scan = redis.scan(key); |
| | |
| | | |
| | | @Override |
| | | public List<SendRtpItem> querySendRTPServer(String platformGbId) { |
| | | if (platformGbId == null) platformGbId = "*"; |
| | | if (platformGbId == null) { |
| | | platformGbId = "*"; |
| | | } |
| | | String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + userSetting.getServerId() + "_" + platformGbId + "_*" + "_*" + "_*"; |
| | | List<Object> queryResult = redis.scan(key); |
| | | List<SendRtpItem> result= new ArrayList<>(); |
| | |
| | | */ |
| | | @Override |
| | | public void deleteSendRTPServer(String platformGbId, String channelId, String callId, String streamId) { |
| | | if (streamId == null) streamId = "*"; |
| | | if (callId == null) callId = "*"; |
| | | if (streamId == null) { |
| | | streamId = "*"; |
| | | } |
| | | if (callId == null) { |
| | | callId = "*"; |
| | | } |
| | | String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + userSetting.getServerId() + "_" + platformGbId |
| | | + "_" + channelId + "_" + streamId + "_" + callId; |
| | | List<Object> scan = redis.scan(key); |
| | |
| | | if (stream == null && callId == null) { |
| | | return null; |
| | | } |
| | | if (deviceId == null) deviceId = "*"; |
| | | if (channelId == null) channelId = "*"; |
| | | if (stream == null) stream = "*"; |
| | | if (callId == null) callId = "*"; |
| | | if (deviceId == null) { |
| | | deviceId = "*"; |
| | | } |
| | | if (channelId == null) { |
| | | channelId = "*"; |
| | | } |
| | | if (stream == null) { |
| | | stream = "*"; |
| | | } |
| | | if (callId == null) { |
| | | callId = "*"; |
| | | } |
| | | String key = String.format("%S_%s_%s_%s_%s_%s", VideoManagerConstants.DOWNLOAD_PREFIX, |
| | | userSetting.getServerId(), |
| | | deviceId, |
| | |
| | | public synchronized boolean outline(String deviceId) { |
| | | logger.info("更新设备离线: " + deviceId); |
| | | Device device = deviceMapper.getDeviceByDeviceId(deviceId); |
| | | if (device == null) return false; |
| | | if (device == null) { |
| | | return false; |
| | | } |
| | | device.setOnline(0); |
| | | redisCatchStorage.updateDevice(device); |
| | | return deviceMapper.update(device) > 0; |
| | |
| | | * 删除指定设备的所有移动位置 |
| | | * @param deviceId |
| | | */ |
| | | @Override |
| | | public int clearMobilePositionsByDeviceId(String deviceId) { |
| | | return deviceMobilePositionMapper.clearMobilePositionsByDeviceId(deviceId); |
| | | } |
| | |
| | | |
| | | @Override |
| | | public void updateMediaList(List<StreamPushItem> streamPushItems) { |
| | | if (streamPushItems == null || streamPushItems.size() == 0) return; |
| | | if (streamPushItems == null || streamPushItems.size() == 0) { |
| | | return; |
| | | } |
| | | logger.info("updateMediaList: " + streamPushItems.size()); |
| | | streamPushMapper.addAll(streamPushItems); |
| | | // TODO 待优化 |
| | |
| | | * 获取对象 这里重写了bean方法,起主要作用
|
| | | */
|
| | | public static Object getBean(String beanId) throws BeansException {
|
| | | if (applicationContext == null) return null;
|
| | | if (applicationContext == null) {
|
| | | return null;
|
| | | }
|
| | | return applicationContext.getBean(beanId);
|
| | | }
|
| | |
|
| | |
| | | @RequestParam(required = false) String startTime, |
| | | @RequestParam(required = false) String endTime |
| | | ) { |
| | | if (StringUtils.isEmpty(alarmPriority)) alarmPriority = null; |
| | | if (StringUtils.isEmpty(alarmMethod)) alarmMethod = null; |
| | | if (StringUtils.isEmpty(alarmType)) alarmType = null; |
| | | if (StringUtils.isEmpty(startTime)) startTime = null; |
| | | if (StringUtils.isEmpty(endTime)) endTime = null; |
| | | if (StringUtils.isEmpty(alarmPriority)) { |
| | | alarmPriority = null; |
| | | } |
| | | if (StringUtils.isEmpty(alarmMethod)) { |
| | | alarmMethod = null; |
| | | } |
| | | if (StringUtils.isEmpty(alarmType)) { |
| | | alarmType = null; |
| | | } |
| | | if (StringUtils.isEmpty(startTime)) { |
| | | startTime = null; |
| | | } |
| | | if (StringUtils.isEmpty(endTime)) { |
| | | endTime = null; |
| | | } |
| | | |
| | | |
| | | try { |
| | | if (startTime != null) format.parse(startTime); |
| | | if (endTime != null) format.parse(endTime); |
| | | if (startTime != null) { |
| | | format.parse(startTime); |
| | | } |
| | | if (endTime != null) { |
| | | format.parse(endTime); |
| | | } |
| | | } catch (ParseException e) { |
| | | return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST); |
| | | } |
| | |
| | | @RequestParam(required = false) String deviceIds, |
| | | @RequestParam(required = false) String time |
| | | ) { |
| | | if (StringUtils.isEmpty(id)) id = null; |
| | | if (StringUtils.isEmpty(deviceIds)) deviceIds = null; |
| | | if (StringUtils.isEmpty(time)) time = null; |
| | | if (StringUtils.isEmpty(id)) { |
| | | id = null; |
| | | } |
| | | if (StringUtils.isEmpty(deviceIds)) { |
| | | deviceIds = null; |
| | | } |
| | | if (StringUtils.isEmpty(time)) { |
| | | time = null; |
| | | } |
| | | try { |
| | | if (time != null) { |
| | | format.parse(time); |
| | |
| | | |
| | | if (device != null && device.getDeviceId() != null) { |
| | | Device deviceInStore = storager.queryVideoDevice(device.getDeviceId()); |
| | | if (!StringUtils.isEmpty(device.getName())) deviceInStore.setName(device.getName()); |
| | | if (!StringUtils.isEmpty(device.getCharset())) deviceInStore.setCharset(device.getCharset()); |
| | | if (!StringUtils.isEmpty(device.getMediaServerId())) deviceInStore.setMediaServerId(device.getMediaServerId()); |
| | | if (!StringUtils.isEmpty(device.getName())) { |
| | | deviceInStore.setName(device.getName()); |
| | | } |
| | | if (!StringUtils.isEmpty(device.getCharset())) { |
| | | deviceInStore.setCharset(device.getCharset()); |
| | | } |
| | | if (!StringUtils.isEmpty(device.getMediaServerId())) { |
| | | deviceInStore.setMediaServerId(device.getMediaServerId()); |
| | | } |
| | | |
| | | // 目录订阅相关的信息 |
| | | if (device.getSubscribeCycleForCatalog() > 0) { |
| | |
| | | return new ResponseEntity<>("missing parameters", HttpStatus.BAD_REQUEST); |
| | | } |
| | | ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(serverGBId); |
| | | if (parentPlatform == null) return new ResponseEntity<>("fail", HttpStatus.OK); |
| | | if (parentPlatform == null) { |
| | | return new ResponseEntity<>("fail", HttpStatus.OK); |
| | | } |
| | | // 发送离线消息,无论是否成功都删除缓存 |
| | | commanderForPlatform.unregister(parentPlatform, (event -> { |
| | | // 清空redis缓存 |
| | |
| | | @RequestParam(required = false) String startTime, |
| | | @RequestParam(required = false) String endTime |
| | | ) { |
| | | if (StringUtils.isEmpty(query)) query = null; |
| | | if (StringUtils.isEmpty(startTime)) startTime = null; |
| | | if (StringUtils.isEmpty(endTime)) endTime = null; |
| | | if (StringUtils.isEmpty(query)) { |
| | | query = null; |
| | | } |
| | | if (StringUtils.isEmpty(startTime)) { |
| | | startTime = null; |
| | | } |
| | | if (StringUtils.isEmpty(endTime)) { |
| | | endTime = null; |
| | | } |
| | | if (!userSetting.getLogInDatebase()) { |
| | | logger.warn("自动记录日志功能已关闭,查询结果可能不完整。"); |
| | | } |
| | | |
| | | try { |
| | | if (startTime != null) format.parse(startTime); |
| | | if (endTime != null) format.parse(endTime); |
| | | if (startTime != null) { |
| | | format.parse(startTime); |
| | | } |
| | | if (endTime != null) { |
| | | format.parse(endTime); |
| | | } |
| | | } catch (ParseException e) { |
| | | return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST); |
| | | } |
| | |
| | | @ResponseBody |
| | | public WVPResult save(@RequestBody StreamProxyItem param){ |
| | | logger.info("添加代理: " + JSONObject.toJSONString(param)); |
| | | if (StringUtils.isEmpty(param.getMediaServerId())) param.setMediaServerId("auto"); |
| | | if (StringUtils.isEmpty(param.getType())) param.setType("default"); |
| | | if (StringUtils.isEmpty(param.getGbId())) param.setGbId(null); |
| | | if (StringUtils.isEmpty(param.getMediaServerId())) { |
| | | param.setMediaServerId("auto"); |
| | | } |
| | | if (StringUtils.isEmpty(param.getType())) { |
| | | param.setType("default"); |
| | | } |
| | | if (StringUtils.isEmpty(param.getGbId())) { |
| | | param.setGbId(null); |
| | | } |
| | | WVPResult<StreamInfo> result = streamProxyService.save(param); |
| | | return result; |
| | | } |
| | |
| | | @RequestParam(required = false)String timeout |
| | | |
| | | ){ |
| | | DeferredResult<JSONObject> resultDeferredResult = new DeferredResult<>(userSetting.getPlayTimeout() + 10); |
| | | DeferredResult<JSONObject> resultDeferredResult = new DeferredResult<>(userSetting.getPlayTimeout().longValue() + 10); |
| | | Device device = storager.queryVideoDevice(serial); |
| | | if (device == null ) { |
| | | JSONObject result = new JSONObject(); |