Merge branch '648540858:wvp-28181-2.0' into wvp-28181-2.0
| | |
| | | import org.springframework.boot.autoconfigure.SpringBootApplication;
|
| | | import org.springframework.boot.web.servlet.ServletComponentScan;
|
| | | import org.springframework.context.ConfigurableApplicationContext;
|
| | | import org.springframework.scheduling.annotation.EnableAsync;
|
| | | import org.springframework.scheduling.annotation.EnableScheduling;
|
| | | import springfox.documentation.oas.annotations.EnableOpenApi;
|
| | |
|
| | |
| | | package com.genersoft.iot.vmp.common; |
| | | |
| | | /** |
| | | * 为API重命名, 方便向数据库记录数据的时候展示 |
| | | * @author lin |
| | | */ |
| | | public class ApiSaveConstant { |
| | | |
| | | public static String getVal(String key) { |
| | |
| | | return "[设备控制] 强制关键帧"; |
| | | case "home_position": |
| | | return "[设备控制] 看守位控制"; |
| | | default: |
| | | return ""; |
| | | } |
| | | 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 "[设备查询] 同步设备通道"; |
| | | case "delete": |
| | | return "[设备查询] 移除设备"; |
| | | default: |
| | | return ""; |
| | | } |
| | | break; |
| | | case "channel": |
| | | return "[设备查询] 更新通道信息"; |
| | | case "transport": |
| | | return "[设备查询] 修改数据流传输模式"; |
| | | default: |
| | | return ""; |
| | | } |
| | | break; |
| | | default: |
| | | return ""; |
| | | } |
| | | |
| | | break; |
| | | case "gbStream": |
| | | switch (keyItemArray[3]) { |
| | | case "del": |
| | | return "移除通道与国标的关联"; |
| | | case "add": |
| | | return "添加通道与国标的关联"; |
| | | default: |
| | | return ""; |
| | | } |
| | | break; |
| | | case "media": |
| | | break; |
| | | case "position": |
| | |
| | | return "向上级平台添加国标通道"; |
| | | case "del_channel_for_gb": |
| | | return "从上级平台移除国标通道"; |
| | | default: |
| | | return ""; |
| | | } |
| | | break; |
| | | case "platform_gb_stream": |
| | | break; |
| | | case "play": |
| | |
| | | return "结束转码"; |
| | | case "broadcast": |
| | | return "语音广播"; |
| | | default: |
| | | return ""; |
| | | } |
| | | break; |
| | | case "download": |
| | | switch (keyItemArray[3]) { |
| | | case "start": |
| | | return "开始历史媒体下载"; |
| | | case "stop": |
| | | return "停止历史媒体下载"; |
| | | default: |
| | | return ""; |
| | | } |
| | | break; |
| | | case "playback": |
| | | switch (keyItemArray[3]) { |
| | | case "start": |
| | | return "开始视频回放"; |
| | | case "stop": |
| | | return "停止视频回放"; |
| | | default: |
| | | return ""; |
| | | } |
| | | break; |
| | | case "ptz": |
| | | switch (keyItemArray[3]) { |
| | | case "control": |
| | | return "云台控制"; |
| | | case "front_end_command": |
| | | return "通用前端控制命令"; |
| | | default: |
| | | return ""; |
| | | } |
| | | break; |
| | | case "gb_record": |
| | | break; |
| | | case "onvif": |
| | |
| | | return "启用代理"; |
| | | case "stop": |
| | | return "停用代理"; |
| | | default: |
| | | return ""; |
| | | } |
| | | break; |
| | | case "push": |
| | | switch (keyItemArray[3]) { |
| | | case "save_to_gb": |
| | | return "将推流添加到国标"; |
| | | case "remove_form_gb": |
| | | return "将推流移出到国标"; |
| | | default: |
| | | return ""; |
| | | } |
| | | break; |
| | | case "user": |
| | | switch (keyItemArray[3]) { |
| | | case "login": |
| | |
| | | return "添加用户"; |
| | | case "delete": |
| | | return "删除用户"; |
| | | default: |
| | | return ""; |
| | | } |
| | | break; |
| | | default: |
| | | return ""; |
| | | } |
| | | } |
| | | return null; |
| | |
| | | |
| | | 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; |
| | | } |
| | | |
| | |
| | | |
| | | /** |
| | | * 处理匿名用户访问逻辑 |
| | | * @author lin |
| | | */ |
| | | @Component |
| | | public class AnonymousAuthenticationEntryPoint implements AuthenticationEntryPoint { |
| | |
| | | |
| | | @Override |
| | | public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) { |
| | | // logger.debug("用户需要登录,访问[{}]失败,AuthenticationException=[{}]", request.getRequestURI(), e.getMessage()); |
| | | // 允许跨域 |
| | | response.setHeader("Access-Control-Allow-Origin", "*"); |
| | | // 允许自定义请求头token(允许head跨域) |
| | |
| | | JSONObject jsonObject = new JSONObject(); |
| | | jsonObject.put("code", "-1"); |
| | | jsonObject.put("msg", "请登录后重新请求"); |
| | | if (request.getRequestURI().contains("api/user/login")){ |
| | | String logUri = "api/user/login"; |
| | | if (request.getRequestURI().contains(logUri)){ |
| | | jsonObject.put("msg", e.getMessage()); |
| | | } |
| | | response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); |
| | |
| | | import org.slf4j.LoggerFactory;
|
| | | import org.springframework.beans.factory.annotation.Autowired;
|
| | | import org.springframework.context.annotation.Bean;
|
| | | import org.springframework.context.annotation.Configuration;
|
| | | import org.springframework.context.annotation.DependsOn;
|
| | | import org.springframework.stereotype.Component;
|
| | |
|
| | |
| | | import java.util.concurrent.ThreadPoolExecutor;
|
| | | import java.util.concurrent.TimeUnit;
|
| | |
|
| | | @Component
|
| | | @Configuration
|
| | | public class SipLayer{
|
| | |
|
| | | private final static Logger logger = LoggerFactory.getLogger(SipLayer.class);
|
| | |
| | |
|
| | |
|
| | | @Bean("sipFactory")
|
| | | private SipFactory createSipFactory() {
|
| | | SipFactory createSipFactory() {
|
| | | sipFactory = SipFactory.getInstance();
|
| | | sipFactory.setPathName("gov.nist");
|
| | | return sipFactory;
|
| | |
| | |
|
| | | @Bean("sipStack")
|
| | | @DependsOn({"sipFactory"})
|
| | | private SipStack createSipStack() throws PeerUnavailableException {
|
| | | SipStack createSipStack() throws PeerUnavailableException {
|
| | | Properties properties = new Properties();
|
| | | properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");
|
| | | properties.setProperty("javax.sip.IP_ADDRESS", sipConfig.getMonitorIp());
|
| | |
| | |
|
| | | @Bean(name = "tcpSipProvider")
|
| | | @DependsOn("sipStack")
|
| | | private SipProviderImpl startTcpListener() {
|
| | | SipProviderImpl startTcpListener() {
|
| | | ListeningPoint tcpListeningPoint = null;
|
| | | SipProviderImpl tcpSipProvider = null;
|
| | | try {
|
| | |
| | |
|
| | | @Bean(name = "udpSipProvider")
|
| | | @DependsOn("sipStack")
|
| | | private SipProviderImpl startUdpListener() {
|
| | | SipProviderImpl startUdpListener() {
|
| | | ListeningPoint udpListeningPoint = null;
|
| | | SipProviderImpl udpSipProvider = null;
|
| | | try {
|
| | |
| | | */ |
| | | 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(); |
| | | |
New file |
| | |
| | | package com.genersoft.iot.vmp.gb28181.bean; |
| | | |
| | | /** |
| | | * 报警方式 |
| | | * @author lin |
| | | * 1为电话报警, 2为设备报警, 3为短信报警, 4为 GPS报警, 5为视频报警, 6为设备故障报警, |
| | | * 7其他报警;可以为直接组合如12为电话报警或 设备报警- |
| | | */ |
| | | public enum DeviceAlarmMethod { |
| | | // 1为电话报警 |
| | | Telephone(1), |
| | | |
| | | // 2为设备报警 |
| | | Device(2), |
| | | |
| | | // 3为短信报警 |
| | | SMS(3), |
| | | |
| | | // 4为 GPS报警 |
| | | GPS(4), |
| | | |
| | | // 5为视频报警 |
| | | Video(5), |
| | | |
| | | // 6为设备故障报警 |
| | | DeviceFailure(6), |
| | | |
| | | // 7其他报警 |
| | | Other(7); |
| | | |
| | | private final int val; |
| | | |
| | | DeviceAlarmMethod(int val) { |
| | | this.val=val; |
| | | } |
| | | |
| | | public int getVal() { |
| | | return val; |
| | | } |
| | | } |
| | |
| | | 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;
|
| | |
| | | toHeader, viaHeaders, maxForwards); |
| | | |
| | | List<String> agentParam = new ArrayList<>(); |
| | | agentParam.add("wvp-pro"); |
| | | UserAgentHeader userAgentHeader = sipFactory.createHeaderFactory().createUserAgentHeader(agentParam); |
| | | request.addHeader(userAgentHeader); |
| | | |
| | | ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml"); |
| | | request.setContent(content, contentTypeHeader); |
| | |
| | | ExpiresHeader expires = sipFactory.createHeaderFactory().createExpiresHeader(Integer.parseInt(platform.getExpires())); |
| | | request.addHeader(expires); |
| | | |
| | | List<String> agentParam = new ArrayList<>(); |
| | | agentParam.add("wvp-pro"); |
| | | UserAgentHeader userAgentHeader = sipFactory.createHeaderFactory().createUserAgentHeader(agentParam); |
| | | request.addHeader(userAgentHeader); |
| | | |
| | | return request; |
| | | } |
| | |
| | | messageFactory.setDefaultContentEncodingCharset(parentPlatform.getCharacterSet()); |
| | | request = messageFactory.createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader, |
| | | toHeader, viaHeaders, maxForwards); |
| | | List<String> agentParam = new ArrayList<>(); |
| | | agentParam.add("wvp-pro"); |
| | | UserAgentHeader userAgentHeader = sipFactory.createHeaderFactory().createUserAgentHeader(agentParam); |
| | | request.addHeader(userAgentHeader); |
| | | |
| | | ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml"); |
| | | request.setContent(content, contentTypeHeader); |
| | |
| | | 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());
|
| | |
| | | import org.slf4j.LoggerFactory;
|
| | | import org.springframework.beans.factory.annotation.Autowired;
|
| | | import org.springframework.beans.factory.annotation.Qualifier;
|
| | | import org.springframework.boot.SpringBootVersion;
|
| | | import org.springframework.context.annotation.DependsOn;
|
| | | import org.springframework.stereotype.Component;
|
| | | import org.springframework.util.StringUtils;
|
| | |
| | | import javax.sip.message.Request;
|
| | | import java.lang.reflect.Field;
|
| | | import java.text.ParseException;
|
| | | import java.util.ArrayList;
|
| | | import java.util.HashSet;
|
| | | import java.util.List;
|
| | |
|
| | | /**
|
| | | * @description:设备能力接口,用于定义设备的控制、查询能力
|
| | |
| | | public class SIPCommander implements ISIPCommander {
|
| | |
|
| | | private final Logger logger = LoggerFactory.getLogger(SIPCommander.class);
|
| | | |
| | |
|
| | | @Autowired
|
| | | private SipConfig sipConfig;
|
| | |
|
| | |
| | | * @param channelId 预览通道
|
| | | * @param event hook订阅
|
| | | * @param errorEvent sip错误订阅
|
| | | */
|
| | | */
|
| | | @Override
|
| | | public void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
|
| | | 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);
|
| | |
| | | } else if("UDP".equals(device.getTransport())) {
|
| | | clientTransaction = udpSipProvider.getNewClientTransaction(request);
|
| | | }
|
| | |
|
| | | if (request.getHeader(UserAgentHeader.NAME) == null) {
|
| | | List<String> agentParam = new ArrayList<>();
|
| | | agentParam.add("wvp-pro");
|
| | | // TODO 添加版本信息以及日期
|
| | | UserAgentHeader userAgentHeader = null;
|
| | | try {
|
| | | userAgentHeader = sipFactory.createHeaderFactory().createUserAgentHeader(agentParam);
|
| | | } catch (ParseException e) {
|
| | | throw new RuntimeException(e);
|
| | | }
|
| | | request.addHeader(userAgentHeader);
|
| | | }
|
| | | CallIdHeader callIdHeader = (CallIdHeader)request.getHeader(CallIdHeader.NAME);
|
| | | // 添加错误订阅
|
| | | if (errorEvent != null) {
|
| | |
| | | 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(); |
| | | } |
| | |
| | | import com.genersoft.iot.vmp.conf.SipConfig; |
| | | import com.genersoft.iot.vmp.conf.UserSetting; |
| | | import com.genersoft.iot.vmp.gb28181.bean.*; |
| | | import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector; |
| | | import com.genersoft.iot.vmp.gb28181.event.EventPublisher; |
| | | import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; |
| | |
| | | import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| | | import com.genersoft.iot.vmp.utils.GpsUtil; |
| | | import com.genersoft.iot.vmp.utils.redis.RedisUtil; |
| | | import org.dom4j.DocumentException; |
| | | import org.dom4j.Element; |
| | |
| | | |
| | | @Autowired |
| | | private EventPublisher publisher; |
| | | |
| | | @Autowired |
| | | private DeviceOffLineDetector offLineDetector; |
| | | |
| | | |
| | | private String method = "NOTIFY"; |
| | | |
| | |
| | | |
| | | // 回复200 OK |
| | | responseAck(evt, Response.OK); |
| | | if (offLineDetector.isOnline(deviceId)) { |
| | | if (redisCatchStorage.deviceIsOnline(deviceId)) { |
| | | publisher.deviceAlarmEventPublish(deviceAlarm); |
| | | } |
| | | } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) { |
| | |
| | | |
| | | } |
| | | |
| | | if (!offLineDetector.isOnline(deviceId)) { |
| | | if (!redisCatchStorage.deviceIsOnline(deviceId)) { |
| | | publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE); |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | public void setDeferredResultHolder(DeferredResultHolder deferredResultHolder) { |
| | | } |
| | | |
| | | public void setOffLineDetector(DeviceOffLineDetector offLineDetector) { |
| | | this.offLineDetector = offLineDetector; |
| | | } |
| | | |
| | | public IRedisCatchStorage getRedisCatchStorage() { |
| | |
| | | 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(); |
| | | } |
| | | } |
| | |
| | | package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.genersoft.iot.vmp.conf.SipConfig; |
| | | import com.genersoft.iot.vmp.conf.UserSetting; |
| | | import com.genersoft.iot.vmp.gb28181.bean.*; |
| | | import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector; |
| | | import com.genersoft.iot.vmp.gb28181.event.EventPublisher; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; |
| | |
| | | import com.genersoft.iot.vmp.service.IDeviceAlarmService; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| | | import com.genersoft.iot.vmp.utils.GpsUtil; |
| | | import org.dom4j.Element; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | |
| | | @Component |
| | | public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler { |
| | | |
| | | private Logger logger = LoggerFactory.getLogger(AlarmNotifyMessageHandler.class); |
| | | private final Logger logger = LoggerFactory.getLogger(AlarmNotifyMessageHandler.class); |
| | | private final String cmdType = "Alarm"; |
| | | |
| | | @Autowired |
| | |
| | | |
| | | @Autowired |
| | | private IDeviceAlarmService deviceAlarmService; |
| | | |
| | | @Autowired |
| | | private DeviceOffLineDetector offLineDetector; |
| | | |
| | | @Override |
| | | public void afterPropertiesSet() throws Exception { |
| | |
| | | deviceAlarm.setAlarmPriority(getText(rootElement, "AlarmPriority")); |
| | | deviceAlarm.setAlarmMethod(getText(rootElement, "AlarmMethod")); |
| | | deviceAlarm.setAlarmTime(getText(rootElement, "AlarmTime")); |
| | | if (getText(rootElement, "AlarmDescription") == null) { |
| | | String alarmDescription = getText(rootElement, "AlarmDescription"); |
| | | if (alarmDescription == null) { |
| | | deviceAlarm.setAlarmDescription(""); |
| | | } else { |
| | | deviceAlarm.setAlarmDescription(getText(rootElement, "AlarmDescription")); |
| | | deviceAlarm.setAlarmDescription(alarmDescription); |
| | | } |
| | | if (NumericUtil.isDouble(getText(rootElement, "Longitude"))) { |
| | | deviceAlarm.setLongitude(Double.parseDouble(getText(rootElement, "Longitude"))); |
| | | String longitude = getText(rootElement, "Longitude"); |
| | | if (longitude != null && NumericUtil.isDouble(longitude)) { |
| | | deviceAlarm.setLongitude(Double.parseDouble(longitude)); |
| | | } else { |
| | | deviceAlarm.setLongitude(0.00); |
| | | } |
| | | if (NumericUtil.isDouble(getText(rootElement, "Latitude"))) { |
| | | deviceAlarm.setLatitude(Double.parseDouble(getText(rootElement, "Latitude"))); |
| | | String latitude = getText(rootElement, "Latitude"); |
| | | if (latitude != null && NumericUtil.isDouble(latitude)) { |
| | | deviceAlarm.setLatitude(Double.parseDouble(latitude)); |
| | | } else { |
| | | deviceAlarm.setLatitude(0.00); |
| | | } |
| | | |
| | | if (!StringUtils.isEmpty(deviceAlarm.getAlarmMethod())) { |
| | | if ( deviceAlarm.getAlarmMethod().equals("4")) { |
| | | if ( deviceAlarm.getAlarmMethod().contains(DeviceAlarmMethod.GPS.getVal() + "")) { |
| | | MobilePosition mobilePosition = new MobilePosition(); |
| | | mobilePosition.setDeviceId(deviceAlarm.getDeviceId()); |
| | | mobilePosition.setTime(deviceAlarm.getAlarmTime()); |
| | |
| | | } |
| | | } |
| | | if (!StringUtils.isEmpty(deviceAlarm.getDeviceId())) { |
| | | if (deviceAlarm.getAlarmMethod().equals("5")) { |
| | | if (deviceAlarm.getAlarmMethod().contains(DeviceAlarmMethod.Video.getVal() + "")) { |
| | | deviceAlarm.setAlarmType(getText(rootElement.element("Info"), "AlarmType")); |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | |
| | | if (offLineDetector.isOnline(device.getDeviceId())) { |
| | | if (redisCatchStorage.deviceIsOnline(device.getDeviceId())) { |
| | | publisher.deviceAlarmEventPublish(deviceAlarm); |
| | | } |
| | | } |
| | |
| | | deviceAlarm.setAlarmPriority(getText(rootElement, "AlarmPriority")); |
| | | deviceAlarm.setAlarmMethod(getText(rootElement, "AlarmMethod")); |
| | | deviceAlarm.setAlarmTime(getText(rootElement, "AlarmTime")); |
| | | if (getText(rootElement, "AlarmDescription") == null) { |
| | | String alarmDescription = getText(rootElement, "AlarmDescription"); |
| | | if (alarmDescription == null) { |
| | | deviceAlarm.setAlarmDescription(""); |
| | | } else { |
| | | deviceAlarm.setAlarmDescription(getText(rootElement, "AlarmDescription")); |
| | | deviceAlarm.setAlarmDescription(alarmDescription); |
| | | } |
| | | if (NumericUtil.isDouble(getText(rootElement, "Longitude"))) { |
| | | deviceAlarm.setLongitude(Double.parseDouble(getText(rootElement, "Longitude"))); |
| | | String longitude = getText(rootElement, "Longitude"); |
| | | if (longitude != null && NumericUtil.isDouble(longitude)) { |
| | | deviceAlarm.setLongitude(Double.parseDouble(longitude)); |
| | | } else { |
| | | deviceAlarm.setLongitude(0.00); |
| | | } |
| | | if (NumericUtil.isDouble(getText(rootElement, "Latitude"))) { |
| | | deviceAlarm.setLatitude(Double.parseDouble(getText(rootElement, "Latitude"))); |
| | | String latitude = getText(rootElement, "Latitude"); |
| | | if (latitude != null && NumericUtil.isDouble(latitude)) { |
| | | deviceAlarm.setLatitude(Double.parseDouble(latitude)); |
| | | } else { |
| | | deviceAlarm.setLatitude(0.00); |
| | | } |
| | | |
| | | if (!StringUtils.isEmpty(deviceAlarm.getAlarmMethod())) { |
| | | |
| | | if (deviceAlarm.getAlarmMethod().equals("5")) { |
| | | if (deviceAlarm.getAlarmMethod().contains(DeviceAlarmMethod.Video.getVal() + "")) { |
| | | deviceAlarm.setAlarmType(getText(rootElement.element("Info"), "AlarmType")); |
| | | } |
| | | } |
| | |
| | | videoManagerStorager.updateDevice(device); |
| | | redisCatchStorage.updateDevice(device); |
| | | } |
| | | publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE); |
| | | if (!redisCatchStorage.deviceIsOnline(device.getDeviceId())) { |
| | | publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE); |
| | | } |
| | | } |
| | | } catch (SipException e) { |
| | | e.printStackTrace(); |
| | |
| | | package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd; |
| | | |
| | | import com.genersoft.iot.vmp.common.VideoManagerConstants; |
| | | import com.genersoft.iot.vmp.conf.SipConfig; |
| | | import com.genersoft.iot.vmp.conf.UserSetting; |
| | | import com.genersoft.iot.vmp.gb28181.bean.*; |
| | | import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector; |
| | | import com.genersoft.iot.vmp.gb28181.event.EventPublisher; |
| | | import com.genersoft.iot.vmp.gb28181.session.CatalogDataCatch; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler; |
| | |
| | | import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| | | import com.genersoft.iot.vmp.utils.GpsUtil; |
| | | import com.genersoft.iot.vmp.vmanager.bean.WVPResult; |
| | | import org.dom4j.DocumentException; |
| | | import org.dom4j.Element; |
| | | import org.slf4j.Logger; |
| | |
| | | |
| | | @Autowired |
| | | private CatalogDataCatch catalogDataCatch; |
| | | |
| | | @Autowired |
| | | private DeviceOffLineDetector offLineDetector; |
| | | |
| | | @Autowired |
| | | private SipConfig config; |
| | |
| | | import com.genersoft.iot.vmp.conf.SipConfig; |
| | | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| | | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| | | import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector; |
| | | import com.genersoft.iot.vmp.gb28181.event.EventPublisher; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| | | import org.dom4j.DocumentException; |
| | | import org.dom4j.Element; |
| | |
| | | private IVideoManagerStorage storager; |
| | | |
| | | @Autowired |
| | | private DeferredResultHolder deferredResultHolder; |
| | | private IRedisCatchStorage redisCatchStorage; |
| | | |
| | | @Autowired |
| | | private DeviceOffLineDetector offLineDetector; |
| | | private DeferredResultHolder deferredResultHolder; |
| | | |
| | | @Autowired |
| | | private SipConfig config; |
| | |
| | | deferredResultHolder.invokeAllResult(msg); |
| | | // 回复200 OK |
| | | responseAck(evt, Response.OK); |
| | | if (offLineDetector.isOnline(device.getDeviceId())) { |
| | | if (redisCatchStorage.deviceIsOnline(device.getDeviceId())) { |
| | | publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE); |
| | | } |
| | | } catch (DocumentException e) { |
| | |
| | | import com.genersoft.iot.vmp.common.VideoManagerConstants; |
| | | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| | | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| | | import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector; |
| | | import com.genersoft.iot.vmp.gb28181.event.EventPublisher; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; |
| | |
| | | import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler; |
| | | import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | | import org.dom4j.Element; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | |
| | | @Autowired |
| | | private ResponseMessageHandler responseMessageHandler; |
| | | |
| | | @Autowired |
| | | private DeviceOffLineDetector offLineDetector; |
| | | |
| | | @Autowired |
| | | private DeferredResultHolder deferredResultHolder; |
| | | |
| | | @Autowired |
| | | private EventPublisher publisher; |
| | | |
| | | @Autowired |
| | | private IRedisCatchStorage redisCatchStorage; |
| | | |
| | | @Override |
| | | public void afterPropertiesSet() throws Exception { |
| | |
| | | msg.setData(json); |
| | | deferredResultHolder.invokeAllResult(msg); |
| | | |
| | | if (offLineDetector.isOnline(device.getDeviceId())) { |
| | | if (redisCatchStorage.deviceIsOnline(device.getDeviceId())) { |
| | | publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE); |
| | | } else { |
| | | |
| | | } |
| | | } |
| | | |
| | |
| | | * */ |
| | | 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 |
| | |
| | | |
| | | void sendStreamPushRequestedMsg(MessageForPushChannel messageForPushChannel); |
| | | |
| | | /** |
| | | * 判断设备状态 |
| | | * @param deviceId 设备ID |
| | | * @return |
| | | */ |
| | | public boolean deviceIsOnline(String deviceId); |
| | | |
| | | } |
| | |
| | | */ |
| | | @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, |
| | |
| | | logger.info("[redis 报警通知] {}: {}", key, JSON.toJSON(msg)); |
| | | redis.convertAndSend(key, (JSONObject)JSON.toJSON(msg)); |
| | | } |
| | | |
| | | @Override |
| | | public boolean deviceIsOnline(String deviceId) { |
| | | String key = VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_" + deviceId; |
| | | return redis.hasKey(key); |
| | | } |
| | | } |
| | |
| | | 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); |
| | |
| | | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| | | import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder; |
| | | import com.genersoft.iot.vmp.gb28181.bean.SyncStatus; |
| | | import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector; |
| | | import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask; |
| | | import com.genersoft.iot.vmp.gb28181.task.impl.CatalogSubscribeTask; |
| | | import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeTask; |
| | |
| | | |
| | | @Autowired |
| | | private DeferredResultHolder resultHolder; |
| | | |
| | | @Autowired |
| | | private DeviceOffLineDetector offLineDetector; |
| | | |
| | | @Autowired |
| | | private IDeviceService deviceService; |
| | |
| | | |
| | | 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(); |
| | |
| | | <script type="text/javascript" src="./static/js/jessibuca/jessibuca.js"></script> |
| | | <script type="text/javascript" src="./static/js/EasyWasmPlayer.js"></script> |
| | | <script type="text/javascript" src="./static/js/ZLMRTCClient.js"></script> |
| | | <script type="text/javascript" src="./static/js/mapConfig.js"></script> |
| | | <div id="app"></div> |
| | | <!-- built files will be auto injected --> |
| | | <script> |
| | | // map组件全局参数, 注释此内容可以关闭地图功能 |
| | | window.mapParam = { |
| | | // 坐标系 GCJ-02 WGS-84, |
| | | coordinateSystem: "GCJ-02", |
| | | // 地图瓦片地址 |
| | | tilesUrl: "http://webrd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8", |
| | | // 瓦片大小 |
| | | tileSize: 256, |
| | | // 默认层级 |
| | | zoom:10, |
| | | // 默认地图中心点 |
| | | center:[116.41020, 39.915119], |
| | | // 地图最大层级 |
| | | maxZoom:18, |
| | | // 地图最小层级 |
| | | minZoom: 3 |
| | | } |
| | | </script> |
| | | </body> |
| | | </html> |
| | |
| | | <template> |
| | | <div ref="container" @dblclick="fullscreenSwich" style="width:100%;height:100%;background-color: #eee;margin:0 auto;"> |
| | | <div ref="container" @dblclick="fullscreenSwich" style="width:100%;height:100%;background-color: #000000;margin:0 auto;"> |
| | | <div class="buttons-box" id="buttonsBox"> |
| | | <div class="buttons-box-left"> |
| | | <i v-if="!playing" class="iconfont icon-play jessibuca-btn" @click="playBtnClick"></i> |
| | |
| | | }, |
| | | data() { |
| | | return { |
| | | onOff: typeof window.mapParam !== "undefined", |
| | | onOff: typeof window.mapParam !== "undefined" && window.mapParam.enable, |
| | | deviceService: new DeviceService(), |
| | | layer: null, |
| | | lineLayer: null, |
New file |
| | |
| | | // map组件全局参数, 注释此内容可以关闭地图功能 |
| | | window.mapParam = { |
| | | // 开启/关闭地图功能 |
| | | enable: true, |
| | | // 坐标系 GCJ-02 WGS-84, |
| | | coordinateSystem: "GCJ-02", |
| | | // 地图瓦片地址 |
| | | tilesUrl: "http://webrd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8", |
| | | // 瓦片大小 |
| | | tileSize: 256, |
| | | // 默认层级 |
| | | zoom:10, |
| | | // 默认地图中心点 |
| | | center:[116.41020, 39.915119], |
| | | // 地图最大层级 |
| | | maxZoom:18, |
| | | // 地图最小层级 |
| | | minZoom: 3 |
| | | } |