Merge remote-tracking branch 'origin/master' into wvp-28181-2.0
# Conflicts:
# README.md
# src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java
# src/main/java/com/genersoft/iot/vmp/gb28181/event/alarm/AlarmEvent.java
# src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
# src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
# src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
# src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
# src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
# src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
# src/main/java/com/genersoft/iot/vmp/vmanager/SseController/SseController.java
# src/main/java/com/genersoft/iot/vmp/vmanager/service/IPlayService.java
# src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java
# src/main/resources/wvp.sqlite
# web_src/.postcssrc.js
# web_src/src/components/UiHeader.vue
# web_src/src/main.js
# web_src/src/router/index.js
54个文件已修改
13个文件已添加
1 文件已重命名
| | |
| | | # gitee同步仓库 |
| | | https://gitee.com/18010473990/wvp-GB28181.git |
| | | |
| | | # 截图 |
| | |  |
| | |  |
| | |  |
| | |  |
| | |  |
| | | |
| | | # 1.0 支持特性 |
| | | 1. 视频预览; |
| | |
| | | 19. 支持播放h265, g.711格式的流(需要将closeWaitRTPInfo设为false) |
| | | 20. 报警信息处理,支持向前端推送报警信息 |
| | | |
| | | # 2.0 支持特性 |
| | | - [ ] 国标通道向上级联 |
| | | # 新支持特性 |
| | | 1. 集成web界面, 不需要单独部署前端服务, 直接利用wvp内置文件服务部署, 随wvp一起部署; |
| | | 2. 支持平台接入, 针对大平台大量设备的情况进行优化; |
| | | 3. 支持检索,通道筛选; |
| | | 4. 支持自动配置ZLM媒体服务, 减少因配置问题所出现的问题; |
| | | 5. 支持启用udp多端口模式, 提高udp模式下媒体传输性能; |
| | | 6. 支持通道是否含有音频的设置; |
| | | 7. 支持通道子目录查询; |
| | | 8. 支持udp/tcp国标流传输模式; |
| | | 9. 支持直接输出RTSP、RTMP、HTTP-FLV、Websocket-FLV、HLS多种协议流地址 |
| | | 10. 支持国标网络校时 |
| | | 11. 支持公网部署, 支持wvp与zlm分开部署 |
| | | 12. 支持播放h265, g.711格式的流 |
| | | 13. 支持固定流地址和自动点播,同时支持未点播时直接播放流地址,代码自动发起点播. ( [查看WIKI](https://github.com/648540858/wvp-GB28181-pro/wiki/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E5%9B%BA%E5%AE%9A%E6%92%AD%E6%94%BE%E5%9C%B0%E5%9D%80%E4%B8%8E%E8%87%AA%E5%8A%A8%E7%82%B9%E6%92%AD)) |
| | | 14. 报警信息处理,支持向前端推送报警信息 |
| | | 15. 支持订阅与通知方法 |
| | | - [X] 移动位置订阅 |
| | | - [X] 移动位置通知处理 |
| | | - [ ] 报警事件订阅 |
| | | - [X] 报警事件通知处理 |
| | | - [ ] 设备目录订阅 |
| | | - [X] 设备目录通知处理 |
| | | 16. 移动位置查询和显示,可通过配置文件设置移动位置历史是否存储 |
| | | |
| | | # 2.0 支持特性 |
| | | - [ ] 国标通道向上级联 |
| | | - [X] WEB添加上级平台 |
| | | - [X] 注册 |
| | | - [X] 心跳保活 |
| | |
| | | - [X] 通道推送 |
| | | - [ ] 点播 |
| | | - [ ] 云台控制 |
| | | - [ ] 添加RTSP视频 |
| | | - [ ] 添加ONVIF探测局域网内的设备 |
| | | - [ ] 添加RTMP视频 |
| | | - [ ] 添加系统配置 |
| | | - [ ] 添加用户管理 |
| | | |
| | | |
| | | - [ ] 添加RTSP视频 |
| | | - [ ] 添加ONVIF探测局域网内的设备 |
| | | - [ ] 添加RTMP视频 |
| | | - [ ] 添加系统配置 |
| | | - [ ] 添加用户管理 |
| | | |
| | | # 待实现: |
| | | 上级级联 |
| | | 推流列表 |
| | | 拉流列表 |
| | | web界面系统设置 |
| | | 使用mysql作为数据库 |
| | | |
| | | # 项目部署 |
| | | 参考:[WIKI](https://github.com/648540858/wvp-GB28181-pro/wiki) |
| | |
| | | import java.util.logging.LogManager;
|
| | |
|
| | | import org.springframework.boot.SpringApplication;
|
| | | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
| | | import org.springframework.boot.autoconfigure.SpringBootApplication;
|
| | |
|
| | | @SpringBootApplication
|
| | |
| | | package com.genersoft.iot.vmp.common;
|
| | |
|
| | | /**
|
| | | * @Description:TODO(这里用一句话描述这个类的作用) |
| | | * @Description: 定义常量 |
| | | * @author: swwheihei
|
| | | * @date: 2019年5月30日 下午3:04:04
|
| | | *
|
New file |
| | |
| | | package com.genersoft.iot.vmp.conf; |
| | | |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | @Configuration("userSetup") |
| | | public class UserSetup { |
| | | @Value("${userSettings.savePositionHistory}") |
| | | boolean savePositionHistory; |
| | | |
| | | public boolean getSavePositionHistory() { |
| | | return savePositionHistory; |
| | | } |
| | | |
| | | public void setSavePositionHistory(boolean savePositionHistory) { |
| | | this.savePositionHistory = savePositionHistory; |
| | | } |
| | | } |
| | |
| | | import org.springframework.context.annotation.Configuration;
|
| | |
|
| | | /**
|
| | | * @Description:TODO(这里用一句话描述这个类的作用) |
| | | * @Description: 获取数据库配置 |
| | | * @author: swwheihei
|
| | | * @date: 2020年5月6日 下午2:46:00
|
| | | */
|
| | |
| | | }
|
| | | }
|
| | | }
|
| | | // } else if (status == Response.TRYING) {
|
| | | // trying不会回复
|
| | | } else if ((status >= 100) && (status < 200)) {
|
| | | // 增加其它无需回复的响应,如101、180等
|
| | | } else {
|
| | |
| | | long time = date.getTime(); |
| | | Random rand = new Random(); |
| | | long pad = rand.nextLong(); |
| | | String nonceString = (new Long(time)).toString() |
| | | + (new Long(pad)).toString(); |
| | | // String nonceString = (new Long(time)).toString() |
| | | // + (new Long(pad)).toString(); |
| | | String nonceString = Long.valueOf(time).toString() |
| | | + Long.valueOf(pad).toString(); |
| | | byte mdbytes[] = messageDigest.digest(nonceString.getBytes()); |
| | | // Convert the mdbytes array into a hex string. |
| | | return toHexString(mdbytes); |
| | |
| | | |
| | | // 客户端随机数,这是一个不透明的字符串值,由客户端提供,并且客户端和服务器都会使用,以避免用明文文本。 |
| | | // 这使得双方都可以查验对方的身份,并对消息的完整性提供一些保护 |
| | | String cNonce = authHeader.getCNonce(); |
| | | //String cNonce = authHeader.getCNonce(); |
| | | |
| | | // nonce计数器,是一个16进制的数值,表示同一nonce下客户端发送出请求的数量 |
| | | int nc = authHeader.getNonceCount(); |
New file |
| | |
| | | package com.genersoft.iot.vmp.gb28181.bean; |
| | | |
| | | public class BaiduPoint { |
| | | |
| | | String bdLng; |
| | | |
| | | String bdLat; |
| | | |
| | | public String getBdLng() { |
| | | return bdLng; |
| | | } |
| | | |
| | | public void setBdLng(String bdLng) { |
| | | this.bdLng = bdLng; |
| | | } |
| | | |
| | | public String getBdLat() { |
| | | return bdLat; |
| | | } |
| | | |
| | | public void setBdLat(String bdLat) { |
| | | this.bdLat = bdLat; |
| | | } |
| | | } |
New file |
| | |
| | | package com.genersoft.iot.vmp.gb28181.bean; |
| | | |
| | | /** |
| | | * @Description: 移动位置bean |
| | | * @author: lawrencehj |
| | | * @date: 2021年1月23日 |
| | | */ |
| | | |
| | | public class MobilePosition { |
| | | /** |
| | | * 设备Id |
| | | */ |
| | | private String deviceId; |
| | | |
| | | /** |
| | | * 设备名称 |
| | | */ |
| | | private String deviceName; |
| | | |
| | | /** |
| | | * 通知时间 |
| | | */ |
| | | private String time; |
| | | |
| | | /** |
| | | * 经度 |
| | | */ |
| | | private double longitude; |
| | | |
| | | /** |
| | | * 纬度 |
| | | */ |
| | | private double latitude; |
| | | |
| | | /** |
| | | * 海拔高度 |
| | | */ |
| | | private double altitude; |
| | | |
| | | /** |
| | | * 速度 |
| | | */ |
| | | private double speed; |
| | | |
| | | /** |
| | | * 方向 |
| | | */ |
| | | private double direction; |
| | | |
| | | /** |
| | | * 位置信息上报来源(Mobile Position、GPS Alarm) |
| | | */ |
| | | private String reportSource; |
| | | |
| | | /** |
| | | * 国内地理坐标系(GCJ-02 / BD-09) |
| | | */ |
| | | private String GeodeticSystem; |
| | | |
| | | /** |
| | | * 国内坐标系:经度坐标 |
| | | */ |
| | | private String cnLng; |
| | | |
| | | /** |
| | | * 国内坐标系:纬度坐标 |
| | | */ |
| | | private String cnLat; |
| | | |
| | | |
| | | public String getDeviceId() { |
| | | return deviceId; |
| | | } |
| | | |
| | | public void setDeviceId(String deviceId) { |
| | | this.deviceId = deviceId; |
| | | } |
| | | |
| | | public String getDeviceName() { |
| | | return deviceName; |
| | | } |
| | | |
| | | public void setDeviceName(String deviceName) { |
| | | this.deviceName = deviceName; |
| | | } |
| | | |
| | | public String getTime() { |
| | | return time; |
| | | } |
| | | |
| | | public void setTime(String time) { |
| | | this.time = time; |
| | | } |
| | | |
| | | public double getLongitude() { |
| | | return longitude; |
| | | } |
| | | |
| | | public void setLongitude(double longitude) { |
| | | this.longitude = longitude; |
| | | } |
| | | |
| | | public double getLatitude() { |
| | | return latitude; |
| | | } |
| | | |
| | | public void setLatitude(double latitude) { |
| | | this.latitude = latitude; |
| | | } |
| | | |
| | | public double getAltitude() { |
| | | return altitude; |
| | | } |
| | | |
| | | public void setAltitude(double altitude) { |
| | | this.altitude = altitude; |
| | | } |
| | | |
| | | public double getSpeed() { |
| | | return speed; |
| | | } |
| | | |
| | | public void setSpeed(double speed) { |
| | | this.speed = speed; |
| | | } |
| | | |
| | | public double getDirection() { |
| | | return direction; |
| | | } |
| | | |
| | | public void setDirection(double direction) { |
| | | this.direction = direction; |
| | | } |
| | | |
| | | public String getReportSource() { |
| | | return reportSource; |
| | | } |
| | | |
| | | public void setReportSource(String reportSource) { |
| | | this.reportSource = reportSource; |
| | | } |
| | | |
| | | public String getGeodeticSystem() { |
| | | return GeodeticSystem; |
| | | } |
| | | |
| | | public void setGeodeticSystem(String geodeticSystem) { |
| | | GeodeticSystem = geodeticSystem; |
| | | } |
| | | |
| | | public String getCnLng() { |
| | | return cnLng; |
| | | } |
| | | |
| | | public void setCnLng(String cnLng) { |
| | | this.cnLng = cnLng; |
| | | } |
| | | |
| | | public String getCnLat() { |
| | | return cnLat; |
| | | } |
| | | |
| | | public void setCnLat(String cnLat) { |
| | | this.cnLat = cnLat; |
| | | } |
| | | } |
| | |
| | | package com.genersoft.iot.vmp.gb28181.bean;
|
| | |
|
| | |
|
| | | import gov.nist.javax.sip.header.SIPDate;
|
| | | //import gov.nist.javax.sip.header.SIPDate;
|
| | |
|
| | | import java.util.List;
|
| | |
|
| | |
| | | package com.genersoft.iot.vmp.gb28181.bean; |
| | | |
| | | import gov.nist.core.InternalErrorHandler; |
| | | import gov.nist.javax.sip.header.SIPDate; |
| | | |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * 重写jain sip的SIPDate解决与国标时间格式不一致的问题 |
| | | */ |
| | | public class WvpSipDate extends SIPDate { |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | private Calendar javaCal; |
| | | |
| | | public WvpSipDate(long timeMillis) { |
| | | super(timeMillis); |
| | | this.javaCal = new GregorianCalendar(TimeZone.getDefault(), Locale.getDefault()); |
| | | Date date = new Date(timeMillis); |
| | | this.javaCal.setTime(date); |
| | | this.wkday = this.javaCal.get(7); |
| | | switch(this.wkday) { |
| | | case 1: |
| | | this.sipWkDay = "Sun"; |
| | | break; |
| | | case 2: |
| | | this.sipWkDay = "Mon"; |
| | | break; |
| | | case 3: |
| | | this.sipWkDay = "Tue"; |
| | | break; |
| | | case 4: |
| | | this.sipWkDay = "Wed"; |
| | | break; |
| | | case 5: |
| | | this.sipWkDay = "Thu"; |
| | | break; |
| | | case 6: |
| | | this.sipWkDay = "Fri"; |
| | | break; |
| | | case 7: |
| | | this.sipWkDay = "Sat"; |
| | | break; |
| | | default: |
| | | InternalErrorHandler.handleException("No date map for wkday " + this.wkday); |
| | | } |
| | | |
| | | this.day = this.javaCal.get(5); |
| | | this.month = this.javaCal.get(2); |
| | | switch(this.month) { |
| | | case 0: |
| | | this.sipMonth = "Jan"; |
| | | break; |
| | | case 1: |
| | | this.sipMonth = "Feb"; |
| | | break; |
| | | case 2: |
| | | this.sipMonth = "Mar"; |
| | | break; |
| | | case 3: |
| | | this.sipMonth = "Apr"; |
| | | break; |
| | | case 4: |
| | | this.sipMonth = "May"; |
| | | break; |
| | | case 5: |
| | | this.sipMonth = "Jun"; |
| | | break; |
| | | case 6: |
| | | this.sipMonth = "Jul"; |
| | | break; |
| | | case 7: |
| | | this.sipMonth = "Aug"; |
| | | break; |
| | | case 8: |
| | | this.sipMonth = "Sep"; |
| | | break; |
| | | case 9: |
| | | this.sipMonth = "Oct"; |
| | | break; |
| | | case 10: |
| | | this.sipMonth = "Nov"; |
| | | break; |
| | | case 11: |
| | | this.sipMonth = "Dec"; |
| | | break; |
| | | default: |
| | | InternalErrorHandler.handleException("No date map for month " + this.month); |
| | | } |
| | | |
| | | this.year = this.javaCal.get(1); |
| | | this.hour = this.javaCal.get(11); |
| | | this.minute = this.javaCal.get(12); |
| | | this.second = this.javaCal.get(13); |
| | | } |
| | | |
| | | @Override |
| | |
| | | var6 = "" + this.second; |
| | | } |
| | | |
| | | int var8 = this.getJavaCal().get(14); |
| | | int var8 = this.javaCal.get(14); |
| | | String var7; |
| | | if (var8 < 10) { |
| | | var7 = "00" + var8; |
| | |
| | | alarmEvent.setAlarmInfo(deviceAlarm);
|
| | | applicationEventPublisher.publishEvent(alarmEvent);
|
| | | }
|
| | | |
| | | }
|
| | |
| | | package com.genersoft.iot.vmp.gb28181.event; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.sip.ResponseEvent; |
| | | import javax.sip.message.Request; |
| | | import java.util.EventObject; |
| | | import java.util.Map; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | |
| | | @Component |
| | | public class SipSubscribe { |
| | | |
| | | private final static Logger logger = LoggerFactory.getLogger(SipSubscribe.class); |
| | | |
| | | private Map<String, SipSubscribe.Event> errorSubscribes = new ConcurrentHashMap<>(); |
| | | |
| | |
| | | */ |
| | | |
| | | public class AlarmEvent extends ApplicationEvent { |
| | | /** |
| | | * |
| | | */ |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public AlarmEvent(Object source) { |
| | | super(source); |
| | | } |
| | |
| | | import org.springframework.context.ApplicationEvent;
|
| | |
|
| | | /**
|
| | | * @Description:TODO(这里用一句话描述这个类的作用) |
| | | * @Description: 离线事件类 |
| | | * @author: swwheihei
|
| | | * @date: 2020年5月6日 上午11:33:13
|
| | | */
|
| | | public class OfflineEvent extends ApplicationEvent {
|
| | |
|
| | | /** |
| | | * @Title: OutlineEvent |
| | | * @Description: TODO(这里用一句话描述这个方法的作用) |
| | | * @param: @param source |
| | | * @throws |
| | | */ |
| | | /**
|
| | | *
|
| | | */
|
| | | private static final long serialVersionUID = 1L;
|
| | |
|
| | | public OfflineEvent(Object source) {
|
| | | super(source);
|
| | | }
|
| | |
| | | import org.springframework.context.ApplicationEvent;
|
| | |
|
| | | /**
|
| | | * @Description:TODO(这里用一句话描述这个类的作用) |
| | | * @Description: 在线事件类 |
| | | * @author: swwheihei
|
| | | * @date: 2020年5月6日 上午11:32:56
|
| | | */
|
| | | public class OnlineEvent extends ApplicationEvent {
|
| | |
|
| | | /** |
| | | * @Title: OnlineEvent |
| | | * @Description: TODO(这里用一句话描述这个方法的作用) |
| | | * @param: @param source |
| | | * @throws |
| | | */ |
| | | /**
|
| | | *
|
| | | */
|
| | | private static final long serialVersionUID = 1L;
|
| | |
|
| | | public OnlineEvent(Object source) {
|
| | | super(source);
|
| | | }
|
| | |
| | | import com.genersoft.iot.vmp.vmanager.service.IPlayService;
|
| | | import org.slf4j.Logger;
|
| | | import org.slf4j.LoggerFactory;
|
| | | // 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.context.annotation.Lazy;
|
| | |
| | | import com.genersoft.iot.vmp.gb28181.transmit.request.impl.CancelRequestProcessor;
|
| | | import com.genersoft.iot.vmp.gb28181.transmit.request.impl.InviteRequestProcessor;
|
| | | import com.genersoft.iot.vmp.gb28181.transmit.request.impl.MessageRequestProcessor;
|
| | | import com.genersoft.iot.vmp.gb28181.transmit.request.impl.NotifyRequestProcessor;
|
| | | import com.genersoft.iot.vmp.gb28181.transmit.request.impl.OtherRequestProcessor;
|
| | | import com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor;
|
| | | import com.genersoft.iot.vmp.gb28181.transmit.request.impl.SubscribeRequestProcessor;
|
| | |
| | | import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
| | |
|
| | | /**
|
| | | * @Description:TODO(这里用一句话描述这个类的作用) |
| | | * @Description: SIP信令处理分配
|
| | | * @author: swwheihei
|
| | | * @date: 2020年5月3日 下午4:24:37
|
| | | */
|
| | |
| | |
|
| | | @Autowired
|
| | | private SIPCommanderFroPlatform cmderFroPlatform;
|
| | | |
| | |
|
| | | @Autowired
|
| | | private RedisUtil redis;
|
| | |
|
| | |
| | | Request request = evt.getRequest();
|
| | | String method = request.getMethod();
|
| | | // logger.info("接收到消息:"+request.getMethod());
|
| | | // sipSubscribe.getSubscribe(evt.getServerTransaction().getBranchId()).response(evt);
|
| | | if (Request.INVITE.equals(method)) {
|
| | | InviteRequestProcessor processor = new InviteRequestProcessor();
|
| | | processor.setRequestEvent(evt);
|
| | |
| | | processor.setRequestEvent(evt);
|
| | | return processor;
|
| | | } else if (Request.MESSAGE.equals(method)) {
|
| | |
|
| | | MessageRequestProcessor processor = new MessageRequestProcessor();
|
| | | processor.setRequestEvent(evt);
|
| | | processor.setTcpSipProvider(getTcpSipProvider());
|
| | |
| | | processor.setStorager(storager);
|
| | | processor.setRedisCatchStorage(redisCatchStorage);
|
| | | return processor;
|
| | | } else if (Request.NOTIFY.equalsIgnoreCase(method)) {
|
| | | NotifyRequestProcessor processor = new NotifyRequestProcessor();
|
| | | processor.setRequestEvent(evt);
|
| | | processor.setTcpSipProvider(getTcpSipProvider());
|
| | | processor.setUdpSipProvider(getUdpSipProvider());
|
| | | processor.setPublisher(publisher);
|
| | | processor.setRedis(redis);
|
| | | processor.setDeferredResultHolder(deferredResultHolder);
|
| | | processor.setOffLineDetector(offLineDetector);
|
| | | processor.setCmder(cmder);
|
| | | processor.setStorager(storager);
|
| | | processor.setRedisCatchStorage(redisCatchStorage);
|
| | | return processor;
|
| | | } else {
|
| | | return new OtherRequestProcessor();
|
| | | OtherRequestProcessor processor = new OtherRequestProcessor();
|
| | | processor.setRequestEvent(evt);
|
| | | return processor;
|
| | | }
|
| | | }
|
| | |
|
New file |
| | |
| | | package com.genersoft.iot.vmp.gb28181.transmit.callback; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Comparator; |
| | | import java.util.List; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | import com.genersoft.iot.vmp.gb28181.bean.RecordInfo; |
| | | import com.genersoft.iot.vmp.gb28181.bean.RecordItem; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.request.impl.MessageRequestProcessor; |
| | | import com.genersoft.iot.vmp.utils.redis.RedisUtil; |
| | | |
| | | import org.slf4j.Logger; |
| | | |
| | | @SuppressWarnings("unchecked") |
| | | public class CheckForAllRecordsThread extends Thread { |
| | | |
| | | private String key; |
| | | |
| | | private RecordInfo recordInfo; |
| | | |
| | | private RedisUtil redis; |
| | | |
| | | private Logger logger; |
| | | |
| | | private DeferredResultHolder deferredResultHolder; |
| | | |
| | | public CheckForAllRecordsThread(String key, RecordInfo recordInfo) { |
| | | this.key = key; |
| | | this.recordInfo = recordInfo; |
| | | } |
| | | |
| | | public void run() { |
| | | |
| | | String cacheKey = this.key; |
| | | |
| | | for (long stop = System.nanoTime() + TimeUnit.SECONDS.toNanos(10); stop > System.nanoTime();) { |
| | | List<Object> cacheKeys = redis.scan(cacheKey + "_*"); |
| | | List<RecordItem> totalRecordList = new ArrayList<RecordItem>(); |
| | | for (int i = 0; i < cacheKeys.size(); i++) { |
| | | totalRecordList.addAll((List<RecordItem>) redis.get(cacheKeys.get(i).toString())); |
| | | } |
| | | if (totalRecordList.size() < this.recordInfo.getSumNum()) { |
| | | logger.info("已获取" + totalRecordList.size() + "项录像数据,共" + this.recordInfo.getSumNum() + "项"); |
| | | } else { |
| | | logger.info("录像数据已全部获取,共" + this.recordInfo.getSumNum() + "项"); |
| | | this.recordInfo.setRecordList(totalRecordList); |
| | | for (int i = 0; i < cacheKeys.size(); i++) { |
| | | redis.del(cacheKeys.get(i).toString()); |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | // 自然顺序排序, 元素进行升序排列 |
| | | this.recordInfo.getRecordList().sort(Comparator.naturalOrder()); |
| | | RequestMessage msg = new RequestMessage(); |
| | | String deviceId = recordInfo.getDeviceId(); |
| | | msg.setDeviceId(deviceId); |
| | | msg.setType(DeferredResultHolder.CALLBACK_CMD_RECORDINFO); |
| | | msg.setData(recordInfo); |
| | | deferredResultHolder.invokeResult(msg); |
| | | logger.info("处理完成,返回结果"); |
| | | MessageRequestProcessor.threadNameList.remove(cacheKey); |
| | | } |
| | | |
| | | public void setRedis(RedisUtil redis) { |
| | | this.redis = redis; |
| | | } |
| | | |
| | | public void setDeferredResultHolder(DeferredResultHolder deferredResultHolder) { |
| | | this.deferredResultHolder = deferredResultHolder; |
| | | } |
| | | |
| | | public void setLogger(Logger logger) { |
| | | this.logger = logger; |
| | | } |
| | | |
| | | } |
| | |
| | | package com.genersoft.iot.vmp.gb28181.transmit.callback;
|
| | |
|
| | | import java.util.HashMap;
|
| | | import java.util.Map;
|
| | | import java.util.concurrent.ConcurrentHashMap;
|
| | |
|
| | |
| | | import org.springframework.web.context.request.async.DeferredResult;
|
| | |
|
| | | /**
|
| | | * @Description:TODO(这里用一句话描述这个类的作用) |
| | | * @Description: 异步请求处理
|
| | | * @author: swwheihei
|
| | | * @date: 2020年5月8日 下午7:59:05
|
| | | */
|
| | | @SuppressWarnings(value = {"rawtypes", "unchecked"})
|
| | | @Component
|
| | | public class DeferredResultHolder {
|
| | |
|
| | | public static final String CALLBACK_CMD_DEVICESTATUS = "CALLBACK_DEVICESTATUS";
|
| | | |
| | | public static final String CALLBACK_CMD_DEVICEINFO = "CALLBACK_DEVICEINFO";
|
| | | |
| | | public static final String CALLBACK_CMD_DEVICECONTROL = "CALLBACK_DEVICECONTROL";
|
| | | |
| | | public static final String CALLBACK_CMD_DEVICECONFIG = "CALLBACK_DEVICECONFIG";
|
| | |
|
| | | public static final String CALLBACK_CMD_CONFIGDOWNLOAD = "CALLBACK_CONFIGDOWNLOAD";
|
| | |
|
| | | public static final String CALLBACK_CMD_CATALOG = "CALLBACK_CATALOG";
|
| | |
|
| | |
| | |
|
| | | public static final String CALLBACK_CMD_STOP = "CALLBACK_STOP";
|
| | |
|
| | | public static final String CALLBACK_CMD_MOBILEPOSITION = "CALLBACK_MOBILEPOSITION";
|
| | |
|
| | | public static final String CALLBACK_CMD_PRESETQUERY = "CALLBACK_PRESETQUERY";
|
| | |
|
| | | public static final String CALLBACK_CMD_ALARM = "CALLBACK_ALARM";
|
| | |
|
| | | private Map<String, DeferredResult> map = new ConcurrentHashMap<String, DeferredResult>();
|
| | |
|
| | | public void put(String key, DeferredResult result) {
|
| | |
| | | package com.genersoft.iot.vmp.gb28181.transmit.callback;
|
| | |
|
| | | /**
|
| | | * @Description:TODO(这里用一句话描述这个类的作用) |
| | | * @Description: 请求信息定义 |
| | | * @author: swwheihei
|
| | | * @date: 2020年5月8日 下午1:09:18
|
| | | */
|
| | |
| | | package com.genersoft.iot.vmp.gb28181.transmit.cmd;
|
| | |
|
| | | import com.genersoft.iot.vmp.common.StreamInfo;
|
| | | import com.genersoft.iot.vmp.gb28181.bean.Device;
|
| | | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
| | | import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
|
| | |
| | | /**
|
| | | * 音视频录像控制
|
| | | *
|
| | | * @param device 视频设备
|
| | | * @param channelId 预览通道
|
| | | * @param device 视频设备
|
| | | * @param channelId 预览通道
|
| | | * @param recordCmdStr 录像命令:Record / StopRecord
|
| | | */
|
| | | boolean recordCmd(Device device,String channelId);
|
| | | boolean recordCmd(Device device, String channelId, String recordCmdStr, SipSubscribe.Event errorEvent);
|
| | |
|
| | | /**
|
| | | * 远程启动控制命令
|
| | | * |
| | | * @param device 视频设备
|
| | | */
|
| | | boolean teleBootCmd(Device device);
|
| | |
|
| | | /**
|
| | | * 报警布防/撤防命令
|
| | | *
|
| | | * @param device 视频设备
|
| | | * @param device 视频设备
|
| | | * @param setGuard true: SetGuard, false: ResetGuard
|
| | | */
|
| | | boolean guardCmd(Device device);
|
| | | boolean guardCmd(Device device, String guardCmdStr, SipSubscribe.Event errorEvent);
|
| | |
|
| | | /**
|
| | | * 报警复位命令
|
| | | *
|
| | | * @param device 视频设备
|
| | | * @param device 视频设备
|
| | | * @param alarmMethod 报警方式(可选)
|
| | | * @param alarmType 报警类型(可选)
|
| | | */
|
| | | boolean alarmCmd(Device device);
|
| | | boolean alarmCmd(Device device, String alarmMethod, String alarmType, SipSubscribe.Event errorEvent);
|
| | |
|
| | | /**
|
| | | * 强制关键帧命令,设备收到此命令应立刻发送一个IDR帧
|
| | |
| | | * @param device 视频设备
|
| | | * @param channelId 预览通道
|
| | | */
|
| | | boolean iFameCmd(Device device,String channelId);
|
| | | boolean iFrameCmd(Device device, String channelId);
|
| | |
|
| | | /**
|
| | | * 看守位控制命令
|
| | | *
|
| | | * @param device 视频设备
|
| | | * @param device 视频设备
|
| | | * @param enabled 看守位使能:1 = 开启,0 = 关闭
|
| | | * @param resetTime 自动归位时间间隔,开启看守位时使用,单位:秒(s)
|
| | | * @param presetIndex 调用预置位编号,开启看守位时使用,取值范围0~255
|
| | | */
|
| | | boolean homePositionCmd(Device device);
|
| | | boolean homePositionCmd(Device device, String channelId, String enabled, String resetTime, String presetIndex, SipSubscribe.Event errorEvent);
|
| | |
|
| | | /**
|
| | | * 设备配置命令
|
| | |
| | | */
|
| | | boolean deviceConfigCmd(Device device);
|
| | |
|
| | | /**
|
| | | * 设备配置命令:basicParam
|
| | | * |
| | | * @param device 视频设备
|
| | | * @param channelId 通道编码(可选)
|
| | | * @param name 设备/通道名称(可选)
|
| | | * @param expiration 注册过期时间(可选)
|
| | | * @param heartBeatInterval 心跳间隔时间(可选)
|
| | | * @param heartBeatCount 心跳超时次数(可选)
|
| | | */ |
| | | boolean deviceBasicConfigCmd(Device device, String channelId, String name, String expiration, String heartBeatInterval, String heartBeatCount, SipSubscribe.Event errorEvent);
|
| | |
|
| | | /**
|
| | | * 查询设备状态
|
| | | *
|
| | | * @param device 视频设备
|
| | | */
|
| | | boolean deviceStatusQuery(Device device);
|
| | | boolean deviceStatusQuery(Device device, SipSubscribe.Event errorEvent);
|
| | |
|
| | | /**
|
| | | * 查询设备信息
|
| | |
| | | /**
|
| | | * 查询报警信息
|
| | | *
|
| | | * @param device 视频设备
|
| | | * @param device 视频设备
|
| | | * @param startPriority 报警起始级别(可选)
|
| | | * @param endPriority 报警终止级别(可选)
|
| | | * @param alarmMethod 报警方式条件(可选)
|
| | | * @param alarmType 报警类型
|
| | | * @param startTime 报警发生起始时间(可选)
|
| | | * @param endTime 报警发生终止时间(可选)
|
| | | * @return true = 命令发送成功
|
| | | */
|
| | | boolean alarmInfoQuery(Device device);
|
| | | boolean alarmInfoQuery(Device device, String startPriority, String endPriority, String alarmMethod,
|
| | | String alarmType, String startTime, String endTime, SipSubscribe.Event errorEvent); |
| | |
|
| | | /**
|
| | | * 查询设备配置
|
| | | *
|
| | | * @param device 视频设备
|
| | | * @param device 视频设备
|
| | | * @param channelId 通道编码(可选)
|
| | | * @param configType 配置类型:
|
| | | */
|
| | | boolean configQuery(Device device);
|
| | | boolean deviceConfigQuery(Device device, String channelId, String configType, SipSubscribe.Event errorEvent);
|
| | |
|
| | | /**
|
| | | * 查询设备预置位置
|
| | | *
|
| | | * @param device 视频设备
|
| | | */
|
| | | boolean presetQuery(Device device);
|
| | | boolean presetQuery(Device device, String channelId, SipSubscribe.Event errorEvent);
|
| | |
|
| | | /**
|
| | | * 查询移动设备位置数据
|
| | | *
|
| | | * @param device 视频设备
|
| | | */
|
| | | boolean mobilePostitionQuery(Device device);
|
| | | boolean mobilePostitionQuery(Device device, SipSubscribe.Event errorEvent);
|
| | |
|
| | | /**
|
| | | * 订阅、取消订阅移动位置
|
| | | * |
| | | * @param device 视频设备
|
| | | * @param expires 订阅超时时间(值=0时为取消订阅)
|
| | | * @param interval 上报时间间隔
|
| | | * @return true = 命令发送成功
|
| | | */
|
| | | boolean mobilePositionSubscribe(Device device, int expires, int interval);
|
| | |
|
| | | /**
|
| | | * 订阅、取消订阅报警信息
|
| | | * @param device 视频设备
|
| | | * @param expires 订阅过期时间(0 = 取消订阅)
|
| | | * @param startPriority 报警起始级别(可选)
|
| | | * @param endPriority 报警终止级别(可选)
|
| | | * @param alarmMethods 报警方式条件(可选)
|
| | | * @param alarmType 报警类型
|
| | | * @param startTime 报警发生起始时间(可选)
|
| | | * @param endTime 报警发生终止时间(可选)
|
| | | * @return true = 命令发送成功
|
| | | */
|
| | | boolean alarmSubscribe(Device device, int expires, String startPriority, String endPriority, String alarmMethod, String alarmType, String startTime, String endTime);
|
| | |
|
| | |
|
| | | /**
|
| | | * 释放rtpserver
|
| | |
| | | request.setContent(content, contentTypeHeader);
|
| | | return request;
|
| | | }
|
| | |
|
| | | public Request createSubscribeRequest(Device device, String content, String viaTag, String fromTag, String toTag, Integer expires, String event) throws ParseException, InvalidArgumentException, PeerUnavailableException {
|
| | | Request request = null;
|
| | | // sipuri
|
| | | SipURI requestURI = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress());
|
| | | // via
|
| | | ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
|
| | | ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(),
|
| | | device.getTransport(), viaTag);
|
| | | viaHeader.setRPort();
|
| | | viaHeaders.add(viaHeader);
|
| | | // from
|
| | | SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(sipConfig.getSipId(),
|
| | | sipConfig.getSipIp() + ":" + sipConfig.getSipPort());
|
| | | Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
|
| | | FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, fromTag);
|
| | | // to
|
| | | SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(), sipConfig.getSipDomain());
|
| | | Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
|
| | | ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, toTag);
|
| | | // callid
|
| | | CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
|
| | | : udpSipProvider.getNewCallId();
|
| | | // Forwards
|
| | | MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
|
| | | // ceq
|
| | | CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(1L, Request.SUBSCRIBE);
|
| | |
|
| | | request = sipFactory.createMessageFactory().createRequest(requestURI, Request.SUBSCRIBE, callIdHeader, cSeqHeader, fromHeader,
|
| | | toHeader, viaHeaders, maxForwards);
|
| | |
|
| | |
|
| | | Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory().createSipURI(sipConfig.getSipId(), sipConfig.getSipIp()+":"+sipConfig.getSipPort()));
|
| | | request.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
|
| | |
|
| | | // Expires
|
| | | ExpiresHeader expireHeader = sipFactory.createHeaderFactory().createExpiresHeader(expires);
|
| | | request.addHeader(expireHeader);
|
| | |
|
| | | // Event
|
| | | EventHeader eventHeader = sipFactory.createHeaderFactory().createEventHeader(event);
|
| | | request.addHeader(eventHeader);
|
| | |
|
| | | ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "MANSCDP+xml");
|
| | | request.setContent(content, contentTypeHeader);
|
| | | return request;
|
| | | }
|
| | | }
|
| | |
| | | package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl;
|
| | |
|
| | | import java.text.ParseException;
|
| | | import java.util.UUID;
|
| | | import java.util.regex.Matcher;
|
| | | import java.util.regex.Pattern;
|
| | |
|
| | | import javax.sip.*;
|
| | | import javax.sip.address.SipURI;
|
| | | import javax.sip.header.CallIdHeader;
|
| | | import javax.sip.header.Header;
|
| | | import javax.sip.header.ViaHeader;
|
| | | import javax.sip.message.Request;
|
| | |
|
| | | import com.alibaba.fastjson.JSONObject;
|
| | | import com.genersoft.iot.vmp.common.StreamInfo;
|
| | | import com.genersoft.iot.vmp.conf.MediaServerConfig;
|
| | | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
| | | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
| | | import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
|
| | | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
|
| | |
| | | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
|
| | | import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider;
|
| | | import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
|
| | | import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
|
| | | import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
|
| | |
|
| | | /**
|
| | | * @Description:设备能力接口,用于定义设备的控制、查询能力
|
| | |
| | | ptzXml.append("</Info>\r\n");
|
| | | ptzXml.append("</Control>\r\n");
|
| | |
|
| | | Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "ViaPtzBranch", "FromPtzTag", null);
|
| | | String tm = Long.toString(System.currentTimeMillis());
|
| | | Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "ViaPtzBranch", "FromPtz" + tm, null);
|
| | |
|
| | | transmitRequest(device, request);
|
| | | return true;
|
| | |
| | | ptzXml.append("</Info>\r\n");
|
| | | ptzXml.append("</Control>\r\n");
|
| | |
|
| | | Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "ViaPtzBranch", "FromPtzTag", null);
|
| | | String tm = Long.toString(System.currentTimeMillis());
|
| | | Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "ViaPtzBranch", "FromPtz" + tm, null);
|
| | | transmitRequest(device, request);
|
| | | return true;
|
| | | } catch (SipException | ParseException | InvalidArgumentException e) {
|
| | |
| | |
|
| | | content.append("y="+ssrc+"\r\n");//ssrc
|
| | |
|
| | | Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, "live", null, ssrc);
|
| | | String tm = Long.toString(System.currentTimeMillis());
|
| | | Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, "FromInvt" + tm, null, ssrc);
|
| | |
|
| | | ClientTransaction transaction = transmitRequest(device, request, errorEvent);
|
| | | streamSession.put(streamId, transaction);
|
| | |
| | |
|
| | | content.append("y="+ssrc+"\r\n");//ssrc
|
| | |
|
| | | Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "playback", null);
|
| | | String tm = Long.toString(System.currentTimeMillis());
|
| | | Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null);
|
| | |
|
| | | ClientTransaction transaction = transmitRequest(device, request, errorEvent);
|
| | | streamSession.put(streamId, transaction);
|
| | |
| | | /**
|
| | | * 音视频录像控制
|
| | | *
|
| | | * @param device 视频设备
|
| | | * @param channelId 预览通道
|
| | | * @param device 视频设备
|
| | | * @param channelId 预览通道
|
| | | * @param recordCmdStr 录像命令:Record / StopRecord
|
| | | */
|
| | | @Override
|
| | | public boolean recordCmd(Device device, String channelId) {
|
| | | // TODO Auto-generated method stub
|
| | | return false;
|
| | | public boolean recordCmd(Device device, String channelId, String recordCmdStr, SipSubscribe.Event errorEvent) {
|
| | | try {
|
| | | StringBuffer cmdXml = new StringBuffer(200);
|
| | | cmdXml.append("<?xml version=\"1.0\" ?>\r\n");
|
| | | cmdXml.append("<Control>\r\n");
|
| | | cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n");
|
| | | cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
| | | if (XmlUtil.isEmpty(channelId)) {
|
| | | cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
| | | } else {
|
| | | cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
|
| | | }
|
| | | cmdXml.append("<RecordCmd>" + recordCmdStr + "</RecordCmd>\r\n");
|
| | | cmdXml.append("</Control>\r\n");
|
| | | |
| | | String tm = Long.toString(System.currentTimeMillis());
|
| | | Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromRecord" + tm, null);
|
| | | transmitRequest(device, request, errorEvent);
|
| | | return true;
|
| | | } catch (SipException | ParseException | InvalidArgumentException e) {
|
| | | e.printStackTrace();
|
| | | return false;
|
| | | } |
| | | }
|
| | |
|
| | | /**
|
| | | * 远程启动控制命令
|
| | | * |
| | | * @param device 视频设备
|
| | | */
|
| | | @Override
|
| | | public boolean teleBootCmd(Device device) {
|
| | | try {
|
| | | StringBuffer cmdXml = new StringBuffer(200);
|
| | | cmdXml.append("<?xml version=\"1.0\" ?>\r\n");
|
| | | cmdXml.append("<Control>\r\n");
|
| | | cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n");
|
| | | cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
| | | cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
| | | cmdXml.append("<TeleBoot>Boot</TeleBoot>\r\n");
|
| | | cmdXml.append("</Control>\r\n");
|
| | | |
| | | String tm = Long.toString(System.currentTimeMillis());
|
| | | Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromBoot" + tm, null);
|
| | | transmitRequest(device, request);
|
| | | return true;
|
| | | } catch (SipException | ParseException | InvalidArgumentException e) {
|
| | | e.printStackTrace();
|
| | | return false;
|
| | | } |
| | | }
|
| | | |
| | | /**
|
| | | * 报警布防/撤防命令
|
| | | *
|
| | | * @param device 视频设备
|
| | | */ |
| | | * @param device 视频设备
|
| | | * @param guardCmdStr "SetGuard"/"ResetGuard"
|
| | | */
|
| | | @Override
|
| | | public boolean guardCmd(Device device) {
|
| | | // TODO Auto-generated method stub
|
| | | return false;
|
| | | public boolean guardCmd(Device device, String guardCmdStr, SipSubscribe.Event errorEvent) {
|
| | | try {
|
| | | StringBuffer cmdXml = new StringBuffer(200);
|
| | | cmdXml.append("<?xml version=\"1.0\" ?>\r\n");
|
| | | cmdXml.append("<Control>\r\n");
|
| | | cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n");
|
| | | cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
| | | cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
| | | cmdXml.append("<GuardCmd>" + guardCmdStr + "</GuardCmd>\r\n");
|
| | | cmdXml.append("</Control>\r\n");
|
| | | |
| | | String tm = Long.toString(System.currentTimeMillis());
|
| | | Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromGuard" + tm, null);
|
| | | transmitRequest(device, request, errorEvent);
|
| | | return true;
|
| | | } catch (SipException | ParseException | InvalidArgumentException e) {
|
| | | e.printStackTrace();
|
| | | return false;
|
| | | } |
| | | }
|
| | |
|
| | | /**
|
| | |
| | | * @param device 视频设备
|
| | | */
|
| | | @Override
|
| | | public boolean alarmCmd(Device device) {
|
| | | // TODO Auto-generated method stub
|
| | | return false;
|
| | | public boolean alarmCmd(Device device, String alarmMethod, String alarmType, SipSubscribe.Event errorEvent) {
|
| | | try {
|
| | | StringBuffer cmdXml = new StringBuffer(200);
|
| | | cmdXml.append("<?xml version=\"1.0\" ?>\r\n");
|
| | | cmdXml.append("<Control>\r\n");
|
| | | cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n");
|
| | | cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
| | | cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
| | | cmdXml.append("<AlarmCmd>ResetAlarm</AlarmCmd>\r\n");
|
| | | if (!XmlUtil.isEmpty(alarmMethod) || !XmlUtil.isEmpty(alarmType)) {
|
| | | cmdXml.append("<Info>\r\n");
|
| | | }
|
| | | if (!XmlUtil.isEmpty(alarmMethod)) {
|
| | | cmdXml.append("<AlarmMethod>" + alarmMethod + "</AlarmMethod>\r\n");
|
| | | }
|
| | | if (!XmlUtil.isEmpty(alarmType)) {
|
| | | cmdXml.append("<AlarmType>" + alarmType + "</AlarmType>\r\n");
|
| | | }
|
| | | if (!XmlUtil.isEmpty(alarmMethod) || !XmlUtil.isEmpty(alarmType)) {
|
| | | cmdXml.append("</Info>\r\n");
|
| | | }
|
| | | cmdXml.append("</Control>\r\n");
|
| | | |
| | | String tm = Long.toString(System.currentTimeMillis());
|
| | | Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromAlarm" + tm, null);
|
| | | transmitRequest(device, request, errorEvent);
|
| | | return true;
|
| | | } catch (SipException | ParseException | InvalidArgumentException e) {
|
| | | e.printStackTrace();
|
| | | return false;
|
| | | } |
| | | }
|
| | |
|
| | | /**
|
| | |
| | | * @param channelId 预览通道
|
| | | */
|
| | | @Override
|
| | | public boolean iFameCmd(Device device, String channelId) {
|
| | | // TODO Auto-generated method stub
|
| | | return false;
|
| | | public boolean iFrameCmd(Device device, String channelId) {
|
| | | try {
|
| | | StringBuffer cmdXml = new StringBuffer(200);
|
| | | cmdXml.append("<?xml version=\"1.0\" ?>\r\n");
|
| | | cmdXml.append("<Control>\r\n");
|
| | | cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n");
|
| | | cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
| | | if (XmlUtil.isEmpty(channelId)) {
|
| | | cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
| | | } else {
|
| | | cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
|
| | | }
|
| | | cmdXml.append("<IFameCmd>Send</IFameCmd>\r\n");
|
| | | cmdXml.append("</Control>\r\n");
|
| | | |
| | | String tm = Long.toString(System.currentTimeMillis());
|
| | | Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromBoot" + tm, null);
|
| | | transmitRequest(device, request);
|
| | | return true;
|
| | | } catch (SipException | ParseException | InvalidArgumentException e) {
|
| | | e.printStackTrace();
|
| | | return false;
|
| | | } |
| | | }
|
| | |
|
| | | /**
|
| | | * 看守位控制命令
|
| | | *
|
| | | * @param device 视频设备
|
| | | * @param device 视频设备
|
| | | * @param enabled 看守位使能:1 = 开启,0 = 关闭
|
| | | * @param resetTime 自动归位时间间隔,开启看守位时使用,单位:秒(s)
|
| | | * @param presetIndex 调用预置位编号,开启看守位时使用,取值范围0~255
|
| | | */
|
| | | @Override
|
| | | public boolean homePositionCmd(Device device) {
|
| | | // TODO Auto-generated method stub
|
| | | return false;
|
| | | public boolean homePositionCmd(Device device, String channelId, String enabled, String resetTime, String presetIndex, SipSubscribe.Event errorEvent) {
|
| | | try {
|
| | | StringBuffer cmdXml = new StringBuffer(200);
|
| | | cmdXml.append("<?xml version=\"1.0\" ?>\r\n");
|
| | | cmdXml.append("<Control>\r\n");
|
| | | cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n");
|
| | | cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
| | | if (XmlUtil.isEmpty(channelId)) {
|
| | | cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
| | | } else {
|
| | | cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
|
| | | }
|
| | | cmdXml.append("<HomePosition>\r\n");
|
| | | if (NumericUtil.isInteger(enabled) && (!enabled.equals("0"))) {
|
| | | cmdXml.append("<Enabled>1</Enabled>\r\n");
|
| | | if (NumericUtil.isInteger(resetTime)) {
|
| | | cmdXml.append("<ResetTime>" + resetTime + "</ResetTime>\r\n");
|
| | | } else {
|
| | | cmdXml.append("<ResetTime>0</ResetTime>\r\n");
|
| | | }
|
| | | if (NumericUtil.isInteger(presetIndex)) {
|
| | | cmdXml.append("<PresetIndex>" + presetIndex + "</PresetIndex>\r\n");
|
| | | } else {
|
| | | cmdXml.append("<PresetIndex>0</PresetIndex>\r\n");
|
| | | }
|
| | | } else {
|
| | | cmdXml.append("<Enabled>0</Enabled>\r\n");
|
| | | }
|
| | | cmdXml.append("</HomePosition>\r\n");
|
| | | cmdXml.append("</Control>\r\n");
|
| | | |
| | | String tm = Long.toString(System.currentTimeMillis());
|
| | | Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromGuard" + tm, null);
|
| | | transmitRequest(device, request, errorEvent);
|
| | | return true;
|
| | | } catch (SipException | ParseException | InvalidArgumentException e) {
|
| | | e.printStackTrace();
|
| | | return false;
|
| | | } |
| | | }
|
| | |
|
| | | /**
|
| | |
| | | }
|
| | |
|
| | | /**
|
| | | * 设备配置命令:basicParam
|
| | | * |
| | | * @param device 视频设备
|
| | | * @param channelId 通道编码(可选)
|
| | | * @param name 设备/通道名称(可选)
|
| | | * @param expiration 注册过期时间(可选)
|
| | | * @param heartBeatInterval 心跳间隔时间(可选)
|
| | | * @param heartBeatCount 心跳超时次数(可选)
|
| | | */ |
| | | @Override
|
| | | public boolean deviceBasicConfigCmd(Device device, String channelId, String name, String expiration, |
| | | String heartBeatInterval, String heartBeatCount, SipSubscribe.Event errorEvent) {
|
| | | try {
|
| | | StringBuffer cmdXml = new StringBuffer(200);
|
| | | cmdXml.append("<?xml version=\"1.0\" ?>\r\n");
|
| | | cmdXml.append("<Control>\r\n");
|
| | | cmdXml.append("<CmdType>DeviceConfig</CmdType>\r\n");
|
| | | cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
| | | if (XmlUtil.isEmpty(channelId)) {
|
| | | cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
| | | } else {
|
| | | cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
|
| | | }
|
| | | cmdXml.append("<BasicParam>\r\n");
|
| | | if (!XmlUtil.isEmpty(name)) {
|
| | | cmdXml.append("<Name>" + name + "</Name>\r\n");
|
| | | }
|
| | | if (NumericUtil.isInteger(expiration)) {
|
| | | if (Integer.valueOf(expiration) > 0) {
|
| | | cmdXml.append("<Expiration>" + expiration + "</Expiration>\r\n");
|
| | | }
|
| | | }
|
| | | if (NumericUtil.isInteger(heartBeatInterval)) {
|
| | | if (Integer.valueOf(heartBeatInterval) > 0) {
|
| | | cmdXml.append("<HeartBeatInterval>" + heartBeatInterval + "</HeartBeatInterval>\r\n");
|
| | | }
|
| | | }
|
| | | if (NumericUtil.isInteger(heartBeatCount)) {
|
| | | if (Integer.valueOf(heartBeatCount) > 0) {
|
| | | cmdXml.append("<HeartBeatCount>" + heartBeatCount + "</HeartBeatCount>\r\n");
|
| | | }
|
| | | }
|
| | | cmdXml.append("</BasicParam>\r\n");
|
| | | cmdXml.append("</Control>\r\n");
|
| | | |
| | | String tm = Long.toString(System.currentTimeMillis());
|
| | | Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromConfig" + tm, null);
|
| | | transmitRequest(device, request, errorEvent);
|
| | | return true;
|
| | | } catch (SipException | ParseException | InvalidArgumentException e) {
|
| | | e.printStackTrace();
|
| | | return false;
|
| | | } |
| | | }
|
| | |
|
| | | /**
|
| | | * 查询设备状态
|
| | | *
|
| | | * @param device 视频设备
|
| | | */
|
| | | @Override
|
| | | public boolean deviceStatusQuery(Device device) {
|
| | | // TODO Auto-generated method stub
|
| | | return false;
|
| | | public boolean deviceStatusQuery(Device device, SipSubscribe.Event errorEvent) {
|
| | | try {
|
| | | StringBuffer catalogXml = new StringBuffer(200);
|
| | | catalogXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n");
|
| | | catalogXml.append("<Query>\r\n");
|
| | | catalogXml.append("<CmdType>DeviceStatus</CmdType>\r\n");
|
| | | catalogXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
| | | catalogXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
| | | catalogXml.append("</Query>\r\n");
|
| | | |
| | | String tm = Long.toString(System.currentTimeMillis());
|
| | | Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), null, "FromStatus" + tm, null);
|
| | |
|
| | | transmitRequest(device, request, errorEvent);
|
| | | return true;
|
| | | |
| | | } catch (SipException | ParseException | InvalidArgumentException e) {
|
| | | e.printStackTrace();
|
| | | return false;
|
| | | }
|
| | | }
|
| | |
|
| | | /**
|
| | |
| | | catalogXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
| | | catalogXml.append("</Query>\r\n");
|
| | |
|
| | | Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "ViaDeviceInfoBranch", "FromDeviceInfoTag", null);
|
| | | String tm = Long.toString(System.currentTimeMillis());
|
| | | Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "ViaDeviceInfoBranch", "FromDev" + tm, null);
|
| | |
|
| | | transmitRequest(device, request);
|
| | |
|
| | |
| | | catalogXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
| | | catalogXml.append("</Query>\r\n");
|
| | |
|
| | | Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "ViaCatalogBranch", "FromCatalogTag", null);
|
| | | String tm = Long.toString(System.currentTimeMillis());
|
| | | Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "ViaCatalogBranch", "FromCat" + tm, null);
|
| | |
|
| | | transmitRequest(device, request, errorEvent);
|
| | | } catch (SipException | ParseException | InvalidArgumentException e) {
|
| | |
| | | recordInfoXml.append("<Type>all</Type>\r\n");
|
| | | recordInfoXml.append("</Query>\r\n");
|
| | |
|
| | | Request request = headerProvider.createMessageRequest(device, recordInfoXml.toString(), "ViaRecordInfoBranch", "FromRecordInfoTag", null);
|
| | | String tm = Long.toString(System.currentTimeMillis());
|
| | | Request request = headerProvider.createMessageRequest(device, recordInfoXml.toString(), "ViaRecordInfoBranch", "fromRec" + tm, null);
|
| | |
|
| | | transmitRequest(device, request);
|
| | | } catch (SipException | ParseException | InvalidArgumentException e) {
|
| | |
| | | /**
|
| | | * 查询报警信息
|
| | | *
|
| | | * @param device 视频设备
|
| | | */ |
| | | * @param device 视频设备
|
| | | * @param startPriority 报警起始级别(可选)
|
| | | * @param endPriority 报警终止级别(可选)
|
| | | * @param alarmMethods 报警方式条件(可选)
|
| | | * @param alarmType 报警类型
|
| | | * @param startTime 报警发生起始时间(可选)
|
| | | * @param endTime 报警发生终止时间(可选)
|
| | | * @return true = 命令发送成功
|
| | | */
|
| | | @Override
|
| | | public boolean alarmInfoQuery(Device device) {
|
| | | // TODO Auto-generated method stub
|
| | | return false;
|
| | | public boolean alarmInfoQuery(Device device, String startPriority, String endPriority, String alarmMethod, String alarmType,
|
| | | String startTime, String endTime, SipSubscribe.Event errorEvent) {
|
| | | try {
|
| | | StringBuffer cmdXml = new StringBuffer(200);
|
| | | cmdXml.append("<?xml version=\"1.0\" ?>\r\n");
|
| | | cmdXml.append("<Query>\r\n");
|
| | | cmdXml.append("<CmdType>Alarm</CmdType>\r\n");
|
| | | cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
| | | cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
| | | if (!XmlUtil.isEmpty(startPriority)) {
|
| | | cmdXml.append("<StartAlarmPriority>" + startPriority + "</StartAlarmPriority>\r\n");
|
| | | }
|
| | | if (!XmlUtil.isEmpty(endPriority)) {
|
| | | cmdXml.append("<EndAlarmPriority>" + endPriority + "</EndAlarmPriority>\r\n");
|
| | | }
|
| | | if (!XmlUtil.isEmpty(alarmMethod)) {
|
| | | cmdXml.append("<AlarmMethod>" + alarmMethod + "</AlarmMethod>\r\n");
|
| | | }
|
| | | if (!XmlUtil.isEmpty(alarmType)) {
|
| | | cmdXml.append("<AlarmType>" + alarmType + "</AlarmType>\r\n");
|
| | | }
|
| | | if (!XmlUtil.isEmpty(startTime)) {
|
| | | cmdXml.append("<StartAlarmTime>" + startTime + "</StartAlarmTime>\r\n");
|
| | | }
|
| | | if (!XmlUtil.isEmpty(endTime)) {
|
| | | cmdXml.append("<EndAlarmTime>" + endTime + "</EndAlarmTime>\r\n");
|
| | | }
|
| | | cmdXml.append("</Query>\r\n");
|
| | | |
| | | String tm = Long.toString(System.currentTimeMillis());
|
| | | Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromAlarm" + tm, null);
|
| | | transmitRequest(device, request, errorEvent);
|
| | | return true;
|
| | | } catch (SipException | ParseException | InvalidArgumentException e) {
|
| | | e.printStackTrace();
|
| | | return false;
|
| | | } |
| | | }
|
| | |
|
| | | /**
|
| | | * 查询设备配置
|
| | | *
|
| | | * @param device 视频设备
|
| | | */ |
| | | * @param device 视频设备
|
| | | * @param channelId 通道编码(可选)
|
| | | * @param configType 配置类型:
|
| | | */
|
| | | @Override
|
| | | public boolean configQuery(Device device) {
|
| | | // TODO Auto-generated method stub
|
| | | return false;
|
| | | public boolean deviceConfigQuery(Device device, String channelId, String configType, SipSubscribe.Event errorEvent) {
|
| | | try {
|
| | | StringBuffer cmdXml = new StringBuffer(200);
|
| | | cmdXml.append("<?xml version=\"1.0\" ?>\r\n");
|
| | | cmdXml.append("<Query>\r\n");
|
| | | cmdXml.append("<CmdType>ConfigDownload</CmdType>\r\n");
|
| | | cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
| | | if (XmlUtil.isEmpty(channelId)) {
|
| | | cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
| | | } else {
|
| | | cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
|
| | | }
|
| | | cmdXml.append("<ConfigType>" + configType + "</ConfigType>\r\n");
|
| | | cmdXml.append("</Query>\r\n");
|
| | | |
| | | String tm = Long.toString(System.currentTimeMillis());
|
| | | Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromConfig" + tm, null);
|
| | | transmitRequest(device, request, errorEvent);
|
| | | return true;
|
| | | } catch (SipException | ParseException | InvalidArgumentException e) {
|
| | | e.printStackTrace();
|
| | | return false;
|
| | | } |
| | | }
|
| | |
|
| | | /**
|
| | |
| | | * @param device 视频设备
|
| | | */
|
| | | @Override
|
| | | public boolean presetQuery(Device device) {
|
| | | // TODO Auto-generated method stub
|
| | | return false;
|
| | | public boolean presetQuery(Device device, String channelId, SipSubscribe.Event errorEvent) {
|
| | | try {
|
| | | StringBuffer cmdXml = new StringBuffer(200);
|
| | | cmdXml.append("<?xml version=\"1.0\" ?>\r\n");
|
| | | cmdXml.append("<Query>\r\n");
|
| | | cmdXml.append("<CmdType>PresetQuery</CmdType>\r\n");
|
| | | cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
| | | if (XmlUtil.isEmpty(channelId)) {
|
| | | cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
| | | } else {
|
| | | cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
|
| | | }
|
| | | cmdXml.append("</Query>\r\n");
|
| | | |
| | | String tm = Long.toString(System.currentTimeMillis());
|
| | | Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromConfig" + tm, null);
|
| | | transmitRequest(device, request, errorEvent);
|
| | | return true;
|
| | | } catch (SipException | ParseException | InvalidArgumentException e) {
|
| | | e.printStackTrace();
|
| | | return false;
|
| | | } |
| | | }
|
| | |
|
| | | /**
|
| | |
| | | * @param device 视频设备
|
| | | */
|
| | | @Override
|
| | | public boolean mobilePostitionQuery(Device device) {
|
| | | // TODO Auto-generated method stub
|
| | | return false;
|
| | | public boolean mobilePostitionQuery(Device device, SipSubscribe.Event errorEvent) {
|
| | | try {
|
| | | StringBuffer mobilePostitionXml = new StringBuffer(200);
|
| | | mobilePostitionXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n");
|
| | | mobilePostitionXml.append("<Query>\r\n");
|
| | | mobilePostitionXml.append("<CmdType>MobilePosition</CmdType>\r\n");
|
| | | mobilePostitionXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
| | | mobilePostitionXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
| | | mobilePostitionXml.append("<Interval>60</Interval>\r\n");
|
| | | mobilePostitionXml.append("</Query>\r\n");
|
| | | |
| | | String tm = Long.toString(System.currentTimeMillis());
|
| | | Request request = headerProvider.createMessageRequest(device, mobilePostitionXml.toString(), "viaTagPos" + tm, "fromTagPos" + tm, null);
|
| | |
|
| | | transmitRequest(device, request, errorEvent);
|
| | | |
| | | } catch (SipException | ParseException | InvalidArgumentException e) {
|
| | | e.printStackTrace();
|
| | | return false;
|
| | | }
|
| | | return true;
|
| | | }
|
| | |
|
| | | /**
|
| | | * 订阅、取消订阅移动位置
|
| | | * |
| | | * @param device 视频设备
|
| | | * @param expires 订阅超时时间
|
| | | * @param interval 上报时间间隔
|
| | | * @return true = 命令发送成功
|
| | | */
|
| | | public boolean mobilePositionSubscribe(Device device, int expires, int interval) {
|
| | | try {
|
| | | StringBuffer subscribePostitionXml = new StringBuffer(200);
|
| | | subscribePostitionXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n");
|
| | | subscribePostitionXml.append("<Query>\r\n");
|
| | | subscribePostitionXml.append("<CmdType>MobilePosition</CmdType>\r\n");
|
| | | subscribePostitionXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
| | | subscribePostitionXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
| | | if (expires > 0) {
|
| | | subscribePostitionXml.append("<Interval>" + String.valueOf(interval) + "</Interval>\r\n");
|
| | | }
|
| | | subscribePostitionXml.append("</Query>\r\n");
|
| | |
|
| | | String tm = Long.toString(System.currentTimeMillis());
|
| | | Request request = headerProvider.createSubscribeRequest(device, subscribePostitionXml.toString(), "viaTagPos" + tm, "fromTagPos" + tm, null, expires, "presence" ); //Position;id=" + tm.substring(tm.length() - 4));
|
| | | transmitRequest(device, request);
|
| | |
|
| | | return true;
|
| | |
|
| | | } catch ( NumberFormatException | ParseException | InvalidArgumentException | SipException e) {
|
| | | e.printStackTrace();
|
| | | return false;
|
| | | }
|
| | | }
|
| | |
|
| | | /**
|
| | | * 订阅、取消订阅报警信息
|
| | | * |
| | | * @param device 视频设备
|
| | | * @param expires 订阅过期时间(0 = 取消订阅)
|
| | | * @param startPriority 报警起始级别(可选)
|
| | | * @param endPriority 报警终止级别(可选)
|
| | | * @param alarmMethod 报警方式条件(可选)
|
| | | * @param alarmType 报警类型
|
| | | * @param startTime 报警发生起始时间(可选)
|
| | | * @param endTime 报警发生终止时间(可选)
|
| | | * @return true = 命令发送成功
|
| | | */
|
| | | 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);
|
| | | cmdXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n");
|
| | | cmdXml.append("<Query>\r\n");
|
| | | cmdXml.append("<CmdType>Alarm</CmdType>\r\n");
|
| | | cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
| | | cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
| | | if (!XmlUtil.isEmpty(startPriority)) {
|
| | | cmdXml.append("<StartAlarmPriority>" + startPriority + "</StartAlarmPriority>\r\n");
|
| | | }
|
| | | if (!XmlUtil.isEmpty(endPriority)) {
|
| | | cmdXml.append("<EndAlarmPriority>" + endPriority + "</EndAlarmPriority>\r\n");
|
| | | }
|
| | | if (!XmlUtil.isEmpty(alarmMethod)) {
|
| | | cmdXml.append("<AlarmMethod>" + alarmMethod + "</AlarmMethod>\r\n");
|
| | | }
|
| | | if (!XmlUtil.isEmpty(alarmType)) {
|
| | | cmdXml.append("<AlarmType>" + alarmType + "</AlarmType>\r\n");
|
| | | }
|
| | | if (!XmlUtil.isEmpty(startTime)) {
|
| | | cmdXml.append("<StartAlarmTime>" + startTime + "</StartAlarmTime>\r\n");
|
| | | }
|
| | | if (!XmlUtil.isEmpty(endTime)) {
|
| | | cmdXml.append("<EndAlarmTime>" + endTime + "</EndAlarmTime>\r\n");
|
| | | }
|
| | | cmdXml.append("</Query>\r\n");
|
| | |
|
| | | String tm = Long.toString(System.currentTimeMillis());
|
| | | Request request = headerProvider.createSubscribeRequest(device, cmdXml.toString(), "viaTagPos" + tm, "fromTagPos" + tm, null, expires, "presence" ); |
| | | transmitRequest(device, request);
|
| | |
|
| | | return true;
|
| | |
|
| | | } catch ( NumberFormatException | ParseException | InvalidArgumentException | SipException e) {
|
| | | e.printStackTrace();
|
| | | return false;
|
| | | }
|
| | | }
|
| | |
|
| | |
|
| | | private ClientTransaction transmitRequest(Device device, Request request) throws SipException {
|
| | | return transmitRequest(device, request, null, null);
|
| | | }
|
| | |
| | | import org.springframework.beans.factory.annotation.Autowired;
|
| | |
|
| | | import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
| | | import com.genersoft.iot.vmp.gb28181.bean.Device;
|
| | | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
| | | import com.genersoft.iot.vmp.gb28181.bean.RecordInfo;
|
| | | import com.genersoft.iot.vmp.gb28181.bean.RecordItem;
|
| | | 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;
|
| | |
| | | private static final String MESSAGE_RECORD_INFO = "RecordInfo";
|
| | | private static final String MESSAGE_MEDIA_STATUS = "MediaStatus";
|
| | | // private static final String MESSAGE_BROADCAST = "Broadcast";
|
| | | // private static final String MESSAGE_DEVICE_STATUS = "DeviceStatus";
|
| | | // private static final String MESSAGE_MOBILE_POSITION = "MobilePosition";
|
| | | private static final String MESSAGE_DEVICE_STATUS = "DeviceStatus";
|
| | | private static final String MESSAGE_DEVICE_CONTROL = "DeviceControl";
|
| | | private static final String MESSAGE_DEVICE_CONFIG = "DeviceConfig";
|
| | | private static final String MESSAGE_MOBILE_POSITION = "MobilePosition";
|
| | | // private static final String MESSAGE_MOBILE_POSITION_INTERVAL = "Interval";
|
| | | private static final String MESSAGE_PRESET_QUERY = "PresetQuery";
|
| | |
|
| | | /**
|
| | | * 处理MESSAGE请求
|
| | |
| | | processMessageKeepAlive(evt);
|
| | | } else if (MESSAGE_CONFIG_DOWNLOAD.equals(cmd)) {
|
| | | logger.info("接收到ConfigDownload消息");
|
| | | processMessageConfigDownload(evt);
|
| | | } else if (MESSAGE_CATALOG.equals(cmd)) {
|
| | | logger.info("接收到Catalog消息");
|
| | | processMessageCatalogList(evt);
|
| | | } else if (MESSAGE_DEVICE_INFO.equals(cmd)) {
|
| | | logger.info("接收到DeviceInfo消息");
|
| | | processMessageDeviceInfo(evt);
|
| | | } else if (MESSAGE_DEVICE_STATUS.equals(cmd)) {
|
| | | logger.info("接收到DeviceStatus消息");
|
| | | processMessageDeviceStatus(evt);
|
| | | } else if (MESSAGE_DEVICE_CONTROL.equals(cmd)) {
|
| | | logger.info("接收到DeviceControl消息");
|
| | | processMessageDeviceControl(evt);
|
| | | } else if (MESSAGE_DEVICE_CONFIG.equals(cmd)) {
|
| | | logger.info("接收到DeviceConfig消息");
|
| | | processMessageDeviceConfig(evt);
|
| | | } else if (MESSAGE_ALARM.equals(cmd)) {
|
| | | logger.info("接收到Alarm消息");
|
| | | processMessageAlarm(evt);
|
| | |
| | | }else if (MESSAGE_MEDIA_STATUS.equals(cmd)) {
|
| | | logger.info("接收到MediaStatus消息");
|
| | | processMessageMediaStatus(evt);
|
| | | } else if (MESSAGE_MOBILE_POSITION.equals(cmd)) {
|
| | | logger.info("接收到MobilePosition消息");
|
| | | processMessageMobilePosition(evt);
|
| | | } else if (MESSAGE_PRESET_QUERY.equals(cmd)) {
|
| | | logger.info("接收到PresetQuery消息");
|
| | | processMessagePresetQuery(evt);
|
| | | } else {
|
| | | logger.info("接收到消息:" + cmd);
|
| | | responseAck(evt);
|
| | | }
|
| | | } catch (DocumentException e) {
|
| | | } catch (DocumentException | SipException |InvalidArgumentException | ParseException e) {
|
| | | e.printStackTrace();
|
| | | }
|
| | | }
|
| | |
|
| | | /**
|
| | | * 收到deviceInfo设备信息请求 处理
|
| | | * 处理MobilePosition移动位置消息
|
| | | * |
| | | * @param evt
|
| | | */
|
| | | private void processMessageMobilePosition(RequestEvent evt) {
|
| | | try {
|
| | | Element rootElement = getRootElement(evt);
|
| | | MobilePosition mobilePosition = new MobilePosition();
|
| | | Element deviceIdElement = rootElement.element("DeviceID");
|
| | | String deviceId = deviceIdElement.getTextTrim().toString();
|
| | | Device device = storager.queryVideoDevice(deviceId);
|
| | | if (device != null) {
|
| | | if (!StringUtils.isEmpty(device.getName())) {
|
| | | mobilePosition.setDeviceName(device.getName());
|
| | | }
|
| | | }
|
| | | mobilePosition.setDeviceId(XmlUtil.getText(rootElement, "DeviceID"));
|
| | | mobilePosition.setTime(XmlUtil.getText(rootElement, "Time"));
|
| | | mobilePosition.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude")));
|
| | | mobilePosition.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude")));
|
| | | if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Speed"))) {
|
| | | mobilePosition.setSpeed(Double.parseDouble(XmlUtil.getText(rootElement, "Speed")));
|
| | | } else {
|
| | | mobilePosition.setSpeed(0.0);
|
| | | }
|
| | | if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Direction"))) {
|
| | | mobilePosition.setDirection(Double.parseDouble(XmlUtil.getText(rootElement, "Direction")));
|
| | | } else {
|
| | | mobilePosition.setDirection(0.0);
|
| | | }
|
| | | if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Altitude"))) {
|
| | | mobilePosition.setAltitude(Double.parseDouble(XmlUtil.getText(rootElement, "Altitude")));
|
| | | } else {
|
| | | mobilePosition.setAltitude(0.0);
|
| | | }
|
| | | mobilePosition.setReportSource("Mobile Position");
|
| | | BaiduPoint bp = new BaiduPoint();
|
| | | bp = GpsUtil.Wgs84ToBd09(String.valueOf(mobilePosition.getLongitude()), String.valueOf(mobilePosition.getLatitude()));
|
| | | logger.info("百度坐标:" + bp.getBdLng() + ", " + bp.getBdLat());
|
| | | mobilePosition.setGeodeticSystem("BD-09");
|
| | | mobilePosition.setCnLng(bp.getBdLng());
|
| | | mobilePosition.setCnLat(bp.getBdLat());
|
| | | if (!userSetup.getSavePositionHistory()) {
|
| | | storager.clearMobilePositionsByDeviceId(deviceId);
|
| | | }
|
| | | storager.insertMobilePosition(mobilePosition);
|
| | | //回复 200 OK
|
| | | responseAck(evt);
|
| | | } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
|
| | | e.printStackTrace();
|
| | | }
|
| | | }
|
| | |
|
| | | /**
|
| | | * 处理DeviceStatus设备状态Message
|
| | | * |
| | | * @param evt
|
| | | */
|
| | | private void processMessageDeviceStatus(RequestEvent evt) {
|
| | | try {
|
| | | Element rootElement = getRootElement(evt);
|
| | | String deviceId = XmlUtil.getText(rootElement, "DeviceID");
|
| | | // 检查设备是否存在, 不存在则不回复
|
| | | if (storager.exists(deviceId)) {
|
| | | // 回复200 OK
|
| | | responseAck(evt);
|
| | | JSONObject json = new JSONObject();
|
| | | XmlUtil.node2Json(rootElement, json);
|
| | | if (logger.isDebugEnabled()) {
|
| | | logger.debug(json.toJSONString());
|
| | | }
|
| | | RequestMessage msg = new RequestMessage();
|
| | | msg.setDeviceId(deviceId);
|
| | | msg.setType(DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS);
|
| | | msg.setData(json);
|
| | | deferredResultHolder.invokeResult(msg);
|
| | |
|
| | | if (offLineDetector.isOnline(deviceId)) {
|
| | | publisher.onlineEventPublish(deviceId, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE);
|
| | | } else {
|
| | | }
|
| | | }
|
| | | } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
|
| | | e.printStackTrace();
|
| | | }
|
| | | }
|
| | |
|
| | | /**
|
| | | * 处理DeviceControl设备状态Message
|
| | | * |
| | | * @param evt
|
| | | */
|
| | | private void processMessageDeviceControl(RequestEvent evt) {
|
| | | try {
|
| | | Element rootElement = getRootElement(evt);
|
| | | String deviceId = XmlUtil.getText(rootElement, "DeviceID");
|
| | | //String result = XmlUtil.getText(rootElement, "Result");
|
| | | // 回复200 OK
|
| | | responseAck(evt);
|
| | | if (rootElement.getName().equals("Response")) {//} !XmlUtil.isEmpty(result)) {
|
| | | // 此处是对本平台发出DeviceControl指令的应答
|
| | | JSONObject json = new JSONObject();
|
| | | XmlUtil.node2Json(rootElement, json);
|
| | | if (logger.isDebugEnabled()) {
|
| | | logger.debug(json.toJSONString());
|
| | | }
|
| | | RequestMessage msg = new RequestMessage();
|
| | | msg.setDeviceId(deviceId);
|
| | | msg.setType(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL);
|
| | | msg.setData(json);
|
| | | deferredResultHolder.invokeResult(msg);
|
| | | } else {
|
| | | // 此处是上级发出的DeviceControl指令
|
| | | }
|
| | | } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
|
| | | e.printStackTrace();
|
| | | }
|
| | | }
|
| | |
|
| | | /**
|
| | | * 处理DeviceConfig设备状态Message
|
| | | * |
| | | * @param evt
|
| | | */
|
| | | private void processMessageDeviceConfig(RequestEvent evt) {
|
| | | try {
|
| | | Element rootElement = getRootElement(evt);
|
| | | String deviceId = XmlUtil.getText(rootElement, "DeviceID");
|
| | | // 回复200 OK
|
| | | responseAck(evt);
|
| | | if (rootElement.getName().equals("Response")) {
|
| | | // 此处是对本平台发出DeviceControl指令的应答
|
| | | JSONObject json = new JSONObject();
|
| | | XmlUtil.node2Json(rootElement, json);
|
| | | if (logger.isDebugEnabled()) {
|
| | | logger.debug(json.toJSONString());
|
| | | }
|
| | | RequestMessage msg = new RequestMessage();
|
| | | msg.setDeviceId(deviceId);
|
| | | msg.setType(DeferredResultHolder.CALLBACK_CMD_DEVICECONFIG);
|
| | | msg.setData(json);
|
| | | deferredResultHolder.invokeResult(msg);
|
| | | } else {
|
| | | // 此处是上级发出的DeviceConfig指令
|
| | | }
|
| | | } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
|
| | | e.printStackTrace();
|
| | | }
|
| | | }
|
| | |
|
| | | /**
|
| | | * 处理ConfigDownload设备状态Message
|
| | | * |
| | | * @param evt
|
| | | */
|
| | | private void processMessageConfigDownload(RequestEvent evt) {
|
| | | try {
|
| | | Element rootElement = getRootElement(evt);
|
| | | String deviceId = XmlUtil.getText(rootElement, "DeviceID");
|
| | | // 回复200 OK
|
| | | responseAck(evt);
|
| | | if (rootElement.getName().equals("Response")) {
|
| | | // 此处是对本平台发出DeviceControl指令的应答
|
| | | JSONObject json = new JSONObject();
|
| | | XmlUtil.node2Json(rootElement, json);
|
| | | if (logger.isDebugEnabled()) {
|
| | | logger.debug(json.toJSONString());
|
| | | }
|
| | | RequestMessage msg = new RequestMessage();
|
| | | msg.setDeviceId(deviceId);
|
| | | msg.setType(DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD);
|
| | | msg.setData(json);
|
| | | deferredResultHolder.invokeResult(msg);
|
| | | } else {
|
| | | // 此处是上级发出的DeviceConfig指令
|
| | | }
|
| | | } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
|
| | | e.printStackTrace();
|
| | | }
|
| | | }
|
| | |
|
| | | /**
|
| | | * 处理PresetQuery预置位列表Message
|
| | | * |
| | | * @param evt
|
| | | */
|
| | | private void processMessagePresetQuery(RequestEvent evt) {
|
| | | try {
|
| | | Element rootElement = getRootElement(evt);
|
| | | String deviceId = XmlUtil.getText(rootElement, "DeviceID");
|
| | | // 回复200 OK
|
| | | responseAck(evt);
|
| | | if (rootElement.getName().equals("Response")) {// !XmlUtil.isEmpty(result)) {
|
| | | // 此处是对本平台发出DeviceControl指令的应答
|
| | | JSONObject json = new JSONObject();
|
| | | XmlUtil.node2Json(rootElement, json);
|
| | | if (logger.isDebugEnabled()) {
|
| | | logger.debug(json.toJSONString());
|
| | | }
|
| | | RequestMessage msg = new RequestMessage();
|
| | | msg.setDeviceId(deviceId);
|
| | | msg.setType(DeferredResultHolder.CALLBACK_CMD_PRESETQUERY);
|
| | | msg.setData(json);
|
| | | deferredResultHolder.invokeResult(msg);
|
| | | } else {
|
| | | // 此处是上级发出的DeviceControl指令
|
| | | }
|
| | | } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
|
| | | e.printStackTrace();
|
| | | }
|
| | | }
|
| | |
|
| | | /**
|
| | | * 处理DeviceInfo设备信息Message
|
| | | *
|
| | | * @param evt
|
| | | */
|
| | |
| | | try {
|
| | | Element rootElement = getRootElement(evt);
|
| | | Element deviceIdElement = rootElement.element("DeviceID");
|
| | | String deviceId = deviceIdElement.getText().toString();
|
| | | String deviceId = deviceIdElement.getTextTrim().toString();
|
| | |
|
| | | Device device = storager.queryVideoDevice(deviceId);
|
| | | if (device == null) {
|
| | |
| | | deviceChannel.setStatus(0);
|
| | | }
|
| | |
|
| | | deviceChannel.setManufacture(XmlUtil.getText(itemDevice, "Manufacturer"));
|
| | | deviceChannel.setModel(XmlUtil.getText(itemDevice, "Model"));
|
| | | deviceChannel.setOwner(XmlUtil.getText(itemDevice, "Owner"));
|
| | | deviceChannel.setCivilCode(XmlUtil.getText(itemDevice, "CivilCode"));
|
| | | deviceChannel.setBlock(XmlUtil.getText(itemDevice, "Block"));
|
| | | deviceChannel.setAddress(XmlUtil.getText(itemDevice, "Address"));
|
| | | if (XmlUtil.getText(itemDevice, "Parental") == null || XmlUtil.getText(itemDevice, "Parental") == "") {
|
| | | deviceChannel.setParental(0);
|
| | | } else {
|
| | | deviceChannel.setParental(Integer.parseInt(XmlUtil.getText(itemDevice, "Parental")));
|
| | | }
|
| | | deviceChannel.setParentId(XmlUtil.getText(itemDevice, "ParentID"));
|
| | | if (XmlUtil.getText(itemDevice, "SafetyWay") == null || XmlUtil.getText(itemDevice, "SafetyWay")== "") {
|
| | | deviceChannel.setSafetyWay(0);
|
| | | } else {
|
| | | deviceChannel.setSafetyWay(Integer.parseInt(XmlUtil.getText(itemDevice, "SafetyWay")));
|
| | | }
|
| | | if (XmlUtil.getText(itemDevice, "RegisterWay") == null || XmlUtil.getText(itemDevice, "RegisterWay") =="") {
|
| | | deviceChannel.setRegisterWay(1);
|
| | | } else {
|
| | | deviceChannel.setRegisterWay(Integer.parseInt(XmlUtil.getText(itemDevice, "RegisterWay")));
|
| | | }
|
| | | deviceChannel.setCertNum(XmlUtil.getText(itemDevice, "CertNum"));
|
| | | if (XmlUtil.getText(itemDevice, "Certifiable") == null || XmlUtil.getText(itemDevice, "Certifiable") == "") {
|
| | | deviceChannel.setCertifiable(0);
|
| | | } else {
|
| | | deviceChannel.setCertifiable(Integer.parseInt(XmlUtil.getText(itemDevice, "Certifiable")));
|
| | | }
|
| | | if (XmlUtil.getText(itemDevice, "ErrCode") == null || XmlUtil.getText(itemDevice, "ErrCode") == "") {
|
| | | deviceChannel.setErrCode(0);
|
| | | } else {
|
| | | deviceChannel.setErrCode(Integer.parseInt(XmlUtil.getText(itemDevice, "ErrCode")));
|
| | | }
|
| | | deviceChannel.setEndTime(XmlUtil.getText(itemDevice, "EndTime"));
|
| | | deviceChannel.setSecrecy(XmlUtil.getText(itemDevice, "Secrecy"));
|
| | | deviceChannel.setIpAddress(XmlUtil.getText(itemDevice, "IPAddress"));
|
| | | if (XmlUtil.getText(itemDevice, "Port") == null || XmlUtil.getText(itemDevice, "Port") =="") {
|
| | | deviceChannel.setPort(0);
|
| | | } else {
|
| | | deviceChannel.setPort(Integer.parseInt(XmlUtil.getText(itemDevice, "Port")));
|
| | | }
|
| | | deviceChannel.setPassword(XmlUtil.getText(itemDevice, "Password"));
|
| | | if (XmlUtil.getText(itemDevice, "Longitude") == null || XmlUtil.getText(itemDevice, "Longitude") == "") {
|
| | | deviceChannel.setLongitude(0.00);
|
| | | } else {
|
| | | deviceChannel.setLongitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Longitude")));
|
| | | }
|
| | | if (XmlUtil.getText(itemDevice, "Latitude") == null || XmlUtil.getText(itemDevice, "Latitude") =="") {
|
| | | deviceChannel.setLatitude(0.00);
|
| | | } else {
|
| | | deviceChannel.setLatitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Latitude")));
|
| | | }
|
| | | if (XmlUtil.getText(itemDevice, "PTZType") == null || XmlUtil.getText(itemDevice, "PTZType") == "") {
|
| | | deviceChannel.setPTZType(0);
|
| | | } else {
|
| | | deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(itemDevice, "PTZType")));
|
| | | }
|
| | | deviceChannel.setHasAudio(true); // 默认含有音频,播放时再检查是否有音频及是否AAC
|
| | | storager.updateChannel(device.getDeviceId(), deviceChannel);
|
| | | deviceChannel.setManufacture(XmlUtil.getText(itemDevice, "Manufacturer"));
|
| | | deviceChannel.setModel(XmlUtil.getText(itemDevice, "Model"));
|
| | | deviceChannel.setOwner(XmlUtil.getText(itemDevice, "Owner"));
|
| | | deviceChannel.setCivilCode(XmlUtil.getText(itemDevice, "CivilCode"));
|
| | | deviceChannel.setBlock(XmlUtil.getText(itemDevice, "Block"));
|
| | | deviceChannel.setAddress(XmlUtil.getText(itemDevice, "Address"));
|
| | | if (XmlUtil.getText(itemDevice, "Parental") == null || XmlUtil.getText(itemDevice, "Parental") == "") {
|
| | | deviceChannel.setParental(0);
|
| | | } else {
|
| | | deviceChannel.setParental(Integer.parseInt(XmlUtil.getText(itemDevice, "Parental")));
|
| | | } |
| | | deviceChannel.setParentId(XmlUtil.getText(itemDevice, "ParentID"));
|
| | | if (XmlUtil.getText(itemDevice, "SafetyWay") == null || XmlUtil.getText(itemDevice, "SafetyWay")== "") {
|
| | | deviceChannel.setSafetyWay(0);
|
| | | } else {
|
| | | deviceChannel.setSafetyWay(Integer.parseInt(XmlUtil.getText(itemDevice, "SafetyWay")));
|
| | | }
|
| | | if (XmlUtil.getText(itemDevice, "RegisterWay") == null || XmlUtil.getText(itemDevice, "RegisterWay") =="") {
|
| | | deviceChannel.setRegisterWay(1);
|
| | | } else {
|
| | | deviceChannel.setRegisterWay(Integer.parseInt(XmlUtil.getText(itemDevice, "RegisterWay")));
|
| | | }
|
| | | deviceChannel.setCertNum(XmlUtil.getText(itemDevice, "CertNum"));
|
| | | if (XmlUtil.getText(itemDevice, "Certifiable") == null || XmlUtil.getText(itemDevice, "Certifiable") == "") {
|
| | | deviceChannel.setCertifiable(0);
|
| | | } else {
|
| | | deviceChannel.setCertifiable(Integer.parseInt(XmlUtil.getText(itemDevice, "Certifiable")));
|
| | | }
|
| | | if (XmlUtil.getText(itemDevice, "ErrCode") == null || XmlUtil.getText(itemDevice, "ErrCode") == "") {
|
| | | deviceChannel.setErrCode(0);
|
| | | } else {
|
| | | deviceChannel.setErrCode(Integer.parseInt(XmlUtil.getText(itemDevice, "ErrCode")));
|
| | | }
|
| | | deviceChannel.setEndTime(XmlUtil.getText(itemDevice, "EndTime"));
|
| | | deviceChannel.setSecrecy(XmlUtil.getText(itemDevice, "Secrecy"));
|
| | | deviceChannel.setIpAddress(XmlUtil.getText(itemDevice, "IPAddress"));
|
| | | if (XmlUtil.getText(itemDevice, "Port") == null || XmlUtil.getText(itemDevice, "Port") =="") {
|
| | | deviceChannel.setPort(0);
|
| | | } else {
|
| | | deviceChannel.setPort(Integer.parseInt(XmlUtil.getText(itemDevice, "Port")));
|
| | | }
|
| | | deviceChannel.setPassword(XmlUtil.getText(itemDevice, "Password"));
|
| | | if (XmlUtil.getText(itemDevice, "Longitude") == null || XmlUtil.getText(itemDevice, "Longitude") == "") {
|
| | | deviceChannel.setLongitude(0.00);
|
| | | } else {
|
| | | deviceChannel.setLongitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Longitude")));
|
| | | }
|
| | | if (XmlUtil.getText(itemDevice, "Latitude") == null || XmlUtil.getText(itemDevice, "Latitude") =="") {
|
| | | deviceChannel.setLatitude(0.00);
|
| | | } else {
|
| | | deviceChannel.setLatitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Latitude")));
|
| | | }
|
| | | if (XmlUtil.getText(itemDevice, "PTZType") == null || XmlUtil.getText(itemDevice, "PTZType") == "") {
|
| | | deviceChannel.setPTZType(0);
|
| | | } else {
|
| | | deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(itemDevice, "PTZType")));
|
| | | }
|
| | | deviceChannel.setHasAudio(true); // 默认含有音频,播放时再检查是否有音频及是否AAC
|
| | | storager.updateChannel(device.getDeviceId(), deviceChannel);
|
| | | }
|
| | |
|
| | | RequestMessage msg = new RequestMessage();
|
| | | msg.setDeviceId(deviceId);
|
| | | msg.setType(DeferredResultHolder.CALLBACK_CMD_CATALOG);
|
| | | msg.setData(device);
|
| | | deferredResultHolder.invokeResult(msg);
|
| | | // 回复200 OK
|
| | | responseAck(evt);
|
| | | if (offLineDetector.isOnline(deviceId)) {
|
| | | publisher.onlineEventPublish(deviceId, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE);
|
| | | }
|
| | | RequestMessage msg = new RequestMessage();
|
| | | msg.setDeviceId(deviceId);
|
| | | msg.setType(DeferredResultHolder.CALLBACK_CMD_CATALOG);
|
| | | msg.setData(device);
|
| | | deferredResultHolder.invokeResult(msg);
|
| | | // 回复200 OK
|
| | | responseAck(evt);
|
| | | if (offLineDetector.isOnline(deviceId)) {
|
| | | publisher.onlineEventPublish(deviceId, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE);
|
| | | }
|
| | | }
|
| | |
|
| | | } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
|
| | | e.printStackTrace();
|
| | | }
|
| | |
| | | // storager.queryChannel(deviceId)
|
| | | return;
|
| | | }
|
| | |
|
| | | DeviceAlarm deviceAlarm = new DeviceAlarm();
|
| | | deviceAlarm.setDeviceId(deviceId);
|
| | | deviceAlarm.setAlarmPriority(XmlUtil.getText(rootElement, "AlarmPriority"));
|
| | | deviceAlarm.setAlarmMethod(XmlUtil.getText(rootElement, "AlarmMethod"));
|
| | | deviceAlarm.setAlarmTime(XmlUtil.getText(rootElement, "AlarmTime"));
|
| | | if (XmlUtil.getText(rootElement, "AlarmDescription") == null) {
|
| | | deviceAlarm.setAlarmDescription("");
|
| | | } else {
|
| | | deviceAlarm.setAlarmDescription(XmlUtil.getText(rootElement, "AlarmDescription"));
|
| | | device.setName(XmlUtil.getText(rootElement, "DeviceName"));
|
| | | device.setManufacturer(XmlUtil.getText(rootElement, "Manufacturer"));
|
| | | device.setModel(XmlUtil.getText(rootElement, "Model"));
|
| | | device.setFirmware(XmlUtil.getText(rootElement, "Firmware"));
|
| | | if (StringUtils.isEmpty(device.getStreamMode())) {
|
| | | device.setStreamMode("UDP");
|
| | | }
|
| | | if (XmlUtil.getText(rootElement, "Longitude") == null || XmlUtil.getText(rootElement, "Longitude") == "") {
|
| | | deviceAlarm.setLongitude(0.00);
|
| | | } else {
|
| | | deviceAlarm.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude")));
|
| | | }
|
| | | if (XmlUtil.getText(rootElement, "Latitude") == null || XmlUtil.getText(rootElement, "Latitude") =="") {
|
| | | deviceAlarm.setLatitude(0.00);
|
| | | } else {
|
| | | deviceAlarm.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude")));
|
| | | }
|
| | |
|
| | | // device.setName(XmlUtil.getText(rootElement, "DeviceName"));
|
| | | // device.setManufacturer(XmlUtil.getText(rootElement, "Manufacturer"));
|
| | | // device.setModel(XmlUtil.getText(rootElement, "Model"));
|
| | | // device.setFirmware(XmlUtil.getText(rootElement, "Firmware"));
|
| | | // if (StringUtils.isEmpty(device.getStreamMode())) {
|
| | | // device.setStreamMode("UDP");
|
| | | // }
|
| | | // storager.updateDevice(device);
|
| | | storager.updateDevice(device);
|
| | | //cmder.catalogQuery(device, null);
|
| | | // 回复200 OK
|
| | | responseAck(evt);
|
| | | if (offLineDetector.isOnline(deviceId)) {
|
| | | publisher.deviceAlarmEventPublish(deviceAlarm);
|
| | | publisher.onlineEventPublish(deviceId, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE);
|
| | | }
|
| | | } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
|
| | | // } catch (DocumentException e) {
|
| | |
| | | } else {
|
| | | }
|
| | | }
|
| | |
|
| | | } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
|
| | | e.printStackTrace();
|
| | | }
|
| | | }
|
| | |
|
| | | /***
|
| | | * 收到catalog设备目录列表请求 处理 TODO 过期时间暂时写死180秒,后续与DeferredResult超时时间保持一致
|
| | | * 处理RecordInfo设备录像列表Message请求 TODO 过期时间暂时写死180秒,后续与DeferredResult超时时间保持一致
|
| | | *
|
| | | * @param evt
|
| | | */
|
| | |
| | | Element recordListElement = rootElement.element("RecordList");
|
| | | if (recordListElement == null || recordInfo.getSumNum() == 0) {
|
| | | logger.info("无录像数据");
|
| | | // responseAck(evt);
|
| | | // return;
|
| | | RequestMessage msg = new RequestMessage();
|
| | | msg.setDeviceId(deviceId);
|
| | | msg.setType(DeferredResultHolder.CALLBACK_CMD_RECORDINFO);
|
| | | msg.setData(recordInfo);
|
| | | deferredResultHolder.invokeResult(msg);
|
| | | } else {
|
| | | Iterator<Element> recordListIterator = recordListElement.elementIterator();
|
| | | List<RecordItem> recordList = new ArrayList<RecordItem>();
|
| | |
| | | record.setRecorderId(XmlUtil.getText(itemRecord, "RecorderID"));
|
| | | recordList.add(record);
|
| | | }
|
| | | // recordList.sort(Comparator.naturalOrder());
|
| | | recordInfo.setRecordList(recordList);
|
| | | }
|
| | |
|
| | | // 存在录像且如果当前录像明细个数小于总条数,说明拆包返回,需要组装,暂不返回
|
| | | if (recordInfo.getSumNum() > 0 && recordList.size() > 0 && recordList.size() < recordInfo.getSumNum()) {
|
| | | // 为防止连续请求该设备的录像数据,返回数据错乱,特增加sn进行区分
|
| | | String cacheKey = CACHE_RECORDINFO_KEY + deviceId + sn;
|
| | |
|
| | | redis.set(cacheKey + "_" + uuid, recordList, 90);
|
| | | List<Object> cacheKeys = redis.scan(cacheKey + "_*");
|
| | | List<RecordItem> totalRecordList = new ArrayList<RecordItem>();
|
| | | for (int i = 0; i < cacheKeys.size(); i++) {
|
| | | totalRecordList.addAll((List<RecordItem>) redis.get(cacheKeys.get(i).toString()));
|
| | | // 改用单独线程统计已获取录像文件数量,避免多包并行分别统计不完整的问题
|
| | | String cacheKey = CACHE_RECORDINFO_KEY + deviceId + sn;
|
| | | redis.set(cacheKey + "_" + uuid, recordList, 90);
|
| | | if (!threadNameList.contains(cacheKey)) {
|
| | | threadNameList.add(cacheKey);
|
| | | CheckForAllRecordsThread chk = new CheckForAllRecordsThread(cacheKey, recordInfo);
|
| | | chk.setName(cacheKey);
|
| | | chk.setDeferredResultHolder(deferredResultHolder);
|
| | | chk.setRedis(redis);
|
| | | chk.setLogger(logger);
|
| | | chk.start();
|
| | | if (logger.isDebugEnabled()) {
|
| | | logger.debug("Start Thread " + cacheKey + ".");
|
| | | }
|
| | | if (totalRecordList.size() < recordInfo.getSumNum()) {
|
| | | logger.info("已获取" + totalRecordList.size() + "项录像数据,共" + recordInfo.getSumNum() + "项");
|
| | | return;
|
| | | }
|
| | | logger.info("录像数据已全部获取,共" + recordInfo.getSumNum() + "项");
|
| | | recordInfo.setRecordList(totalRecordList);
|
| | | for (int i = 0; i < cacheKeys.size(); i++) {
|
| | | redis.del(cacheKeys.get(i).toString());
|
| | | } else {
|
| | | if (logger.isDebugEnabled()) {
|
| | | logger.debug("Thread " + cacheKey + " already started.");
|
| | | }
|
| | | }
|
| | | // 自然顺序排序, 元素进行升序排列
|
| | | recordInfo.getRecordList().sort(Comparator.naturalOrder());
|
| | |
|
| | | // 存在录像且如果当前录像明细个数小于总条数,说明拆包返回,需要组装,暂不返回
|
| | | // if (recordInfo.getSumNum() > 0 && recordList.size() > 0 && recordList.size() < recordInfo.getSumNum()) {
|
| | | // // 为防止连续请求该设备的录像数据,返回数据错乱,特增加sn进行区分
|
| | | // String cacheKey = CACHE_RECORDINFO_KEY + deviceId + sn;
|
| | |
|
| | | // redis.set(cacheKey + "_" + uuid, recordList, 90);
|
| | | // List<Object> cacheKeys = redis.scan(cacheKey + "_*");
|
| | | // List<RecordItem> totalRecordList = new ArrayList<RecordItem>();
|
| | | // for (int i = 0; i < cacheKeys.size(); i++) {
|
| | | // totalRecordList.addAll((List<RecordItem>) redis.get(cacheKeys.get(i).toString()));
|
| | | // }
|
| | | // if (totalRecordList.size() < recordInfo.getSumNum()) {
|
| | | // logger.info("已获取" + totalRecordList.size() + "项录像数据,共" + recordInfo.getSumNum() + "项");
|
| | | // return;
|
| | | // }
|
| | | // logger.info("录像数据已全部获取,共" + recordInfo.getSumNum() + "项");
|
| | | // recordInfo.setRecordList(totalRecordList);
|
| | | // for (int i = 0; i < cacheKeys.size(); i++) {
|
| | | // redis.del(cacheKeys.get(i).toString());
|
| | | // }
|
| | | // }
|
| | | // // 自然顺序排序, 元素进行升序排列
|
| | | // recordInfo.getRecordList().sort(Comparator.naturalOrder());
|
| | | }
|
| | | // 走到这里,有以下可能:1、没有录像信息,第一次收到recordinfo的消息即返回响应数据,无redis操作
|
| | | // 2、有录像数据,且第一次即收到完整数据,返回响应数据,无redis操作
|
| | | // 3、有录像数据,在超时时间内收到多次包组装后数量足够,返回数据
|
| | |
|
| | | // 对记录进行排序
|
| | | RequestMessage msg = new RequestMessage();
|
| | | msg.setDeviceId(deviceId);
|
| | | msg.setType(DeferredResultHolder.CALLBACK_CMD_RECORDINFO);
|
| | | // // 自然顺序排序, 元素进行升序排列
|
| | | // recordInfo.getRecordList().sort(Comparator.naturalOrder());
|
| | | msg.setData(recordInfo);
|
| | | deferredResultHolder.invokeResult(msg);
|
| | | logger.info("处理完成,返回结果");
|
| | | // RequestMessage msg = new RequestMessage();
|
| | | // msg.setDeviceId(deviceId);
|
| | | // msg.setType(DeferredResultHolder.CALLBACK_CMD_RECORDINFO);
|
| | | // msg.setData(recordInfo);
|
| | | // deferredResultHolder.invokeResult(msg);
|
| | | // logger.info("处理完成,返回结果");
|
| | | } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
|
| | | e.printStackTrace();
|
| | | }
|
| | | }
|
| | |
|
| | |
|
| | | /**
|
| | | * 收到MediaStatus消息处理
|
| | | *
|
| | | * @param evt
|
| | | */
|
| | | private void processMessageMediaStatus(RequestEvent evt){
|
| | | try {
|
| | | // 回复200 OK
|
New file |
| | |
| | | package com.genersoft.iot.vmp.gb28181.transmit.request.impl; |
| | | |
| | | import java.io.ByteArrayInputStream; |
| | | import java.text.ParseException; |
| | | import java.util.Iterator; |
| | | |
| | | import javax.sip.InvalidArgumentException; |
| | | import javax.sip.RequestEvent; |
| | | import javax.sip.SipException; |
| | | import javax.sip.message.Request; |
| | | import javax.sip.message.Response; |
| | | |
| | | import com.genersoft.iot.vmp.common.VideoManagerConstants; |
| | | import com.genersoft.iot.vmp.conf.UserSetup; |
| | | import com.genersoft.iot.vmp.gb28181.bean.BaiduPoint; |
| | | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| | | import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm; |
| | | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| | | import com.genersoft.iot.vmp.gb28181.bean.MobilePosition; |
| | | 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.cmd.impl.SIPCommander; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; |
| | | import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; |
| | | import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| | | import com.genersoft.iot.vmp.utils.GpsUtil; |
| | | import com.genersoft.iot.vmp.utils.SpringBeanFactory; |
| | | import com.genersoft.iot.vmp.utils.redis.RedisUtil; |
| | | |
| | | import org.dom4j.Document; |
| | | import org.dom4j.DocumentException; |
| | | import org.dom4j.Element; |
| | | import org.dom4j.io.SAXReader; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.util.StringUtils; |
| | | |
| | | /** |
| | | * @Description: Notify请求处理器 |
| | | * @author: lawrencehj |
| | | * @date: 2021年1月27日 |
| | | */ |
| | | |
| | | public class NotifyRequestProcessor extends SIPRequestAbstractProcessor { |
| | | |
| | | private UserSetup userSetup = (UserSetup) SpringBeanFactory.getBean("userSetup"); |
| | | |
| | | private final static Logger logger = LoggerFactory.getLogger(MessageRequestProcessor.class); |
| | | |
| | | private IVideoManagerStorager storager; |
| | | |
| | | private IRedisCatchStorage redisCatchStorage; |
| | | |
| | | private EventPublisher publisher; |
| | | |
| | | private DeviceOffLineDetector offLineDetector; |
| | | |
| | | private static final String NOTIFY_CATALOG = "Catalog"; |
| | | private static final String NOTIFY_ALARM = "Alarm"; |
| | | private static final String NOTIFY_MOBILE_POSITION = "MobilePosition"; |
| | | |
| | | @Override |
| | | public void process(RequestEvent evt) { |
| | | try { |
| | | Element rootElement = getRootElement(evt); |
| | | String cmd = XmlUtil.getText(rootElement, "CmdType"); |
| | | |
| | | if (NOTIFY_CATALOG.equals(cmd)) { |
| | | logger.info("接收到Catalog通知"); |
| | | processNotifyCatalogList(evt); |
| | | } else if (NOTIFY_ALARM.equals(cmd)) { |
| | | logger.info("接收到Alarm通知"); |
| | | processNotifyAlarm(evt); |
| | | } else if (NOTIFY_MOBILE_POSITION.equals(cmd)) { |
| | | logger.info("接收到MobilePosition通知"); |
| | | processNotifyMobilePosition(evt); |
| | | } else { |
| | | logger.info("接收到消息:" + cmd); |
| | | response200Ok(evt); |
| | | } |
| | | } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 处理MobilePosition移动位置Notify |
| | | * |
| | | * @param evt |
| | | */ |
| | | private void processNotifyMobilePosition(RequestEvent evt) { |
| | | try { |
| | | // 回复 200 OK |
| | | Element rootElement = getRootElement(evt); |
| | | MobilePosition mobilePosition = new MobilePosition(); |
| | | Element deviceIdElement = rootElement.element("DeviceID"); |
| | | String deviceId = deviceIdElement.getTextTrim().toString(); |
| | | Device device = storager.queryVideoDevice(deviceId); |
| | | if (device != null) { |
| | | if (!StringUtils.isEmpty(device.getName())) { |
| | | mobilePosition.setDeviceName(device.getName()); |
| | | } |
| | | } |
| | | mobilePosition.setDeviceId(XmlUtil.getText(rootElement, "DeviceID")); |
| | | mobilePosition.setTime(XmlUtil.getText(rootElement, "Time")); |
| | | mobilePosition.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude"))); |
| | | mobilePosition.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude"))); |
| | | if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Speed"))) { |
| | | mobilePosition.setSpeed(Double.parseDouble(XmlUtil.getText(rootElement, "Speed"))); |
| | | } else { |
| | | mobilePosition.setSpeed(0.0); |
| | | } |
| | | if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Direction"))) { |
| | | mobilePosition.setDirection(Double.parseDouble(XmlUtil.getText(rootElement, "Direction"))); |
| | | } else { |
| | | mobilePosition.setDirection(0.0); |
| | | } |
| | | if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Altitude"))) { |
| | | mobilePosition.setAltitude(Double.parseDouble(XmlUtil.getText(rootElement, "Altitude"))); |
| | | } else { |
| | | mobilePosition.setAltitude(0.0); |
| | | } |
| | | mobilePosition.setReportSource("Mobile Position"); |
| | | BaiduPoint bp = new BaiduPoint(); |
| | | bp = GpsUtil.Wgs84ToBd09(String.valueOf(mobilePosition.getLongitude()), String.valueOf(mobilePosition.getLatitude())); |
| | | logger.info("百度坐标:" + bp.getBdLng() + ", " + bp.getBdLat()); |
| | | mobilePosition.setGeodeticSystem("BD-09"); |
| | | mobilePosition.setCnLng(bp.getBdLng()); |
| | | mobilePosition.setCnLat(bp.getBdLat()); |
| | | if (!userSetup.getSavePositionHistory()) { |
| | | storager.clearMobilePositionsByDeviceId(deviceId); |
| | | } |
| | | storager.insertMobilePosition(mobilePosition); |
| | | response200Ok(evt); |
| | | } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | /*** |
| | | * 处理alarm设备报警Notify |
| | | * |
| | | * @param evt |
| | | */ |
| | | private void processNotifyAlarm(RequestEvent evt) { |
| | | try { |
| | | Element rootElement = getRootElement(evt); |
| | | Element deviceIdElement = rootElement.element("DeviceID"); |
| | | String deviceId = deviceIdElement.getText().toString(); |
| | | |
| | | Device device = storager.queryVideoDevice(deviceId); |
| | | if (device == null) { |
| | | return; |
| | | } |
| | | DeviceAlarm deviceAlarm = new DeviceAlarm(); |
| | | deviceAlarm.setDeviceId(deviceId); |
| | | deviceAlarm.setAlarmPriority(XmlUtil.getText(rootElement, "AlarmPriority")); |
| | | deviceAlarm.setAlarmMethod(XmlUtil.getText(rootElement, "AlarmMethod")); |
| | | deviceAlarm.setAlarmTime(XmlUtil.getText(rootElement, "AlarmTime")); |
| | | if (XmlUtil.getText(rootElement, "AlarmDescription") == null) { |
| | | deviceAlarm.setAlarmDescription(""); |
| | | } else { |
| | | deviceAlarm.setAlarmDescription(XmlUtil.getText(rootElement, "AlarmDescription")); |
| | | } |
| | | if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Longitude"))) { |
| | | deviceAlarm.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude"))); |
| | | } else { |
| | | deviceAlarm.setLongitude(0.00); |
| | | } |
| | | if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Latitude"))) { |
| | | deviceAlarm.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude"))); |
| | | } else { |
| | | deviceAlarm.setLatitude(0.00); |
| | | } |
| | | |
| | | if (deviceAlarm.getAlarmMethod().equals("4")) { |
| | | MobilePosition mobilePosition = new MobilePosition(); |
| | | mobilePosition.setDeviceId(deviceAlarm.getDeviceId()); |
| | | mobilePosition.setTime(deviceAlarm.getAlarmTime()); |
| | | mobilePosition.setLongitude(deviceAlarm.getLongitude()); |
| | | mobilePosition.setLatitude(deviceAlarm.getLatitude()); |
| | | mobilePosition.setReportSource("GPS Alarm"); |
| | | BaiduPoint bp = new BaiduPoint(); |
| | | bp = GpsUtil.Wgs84ToBd09(String.valueOf(mobilePosition.getLongitude()), String.valueOf(mobilePosition.getLatitude())); |
| | | logger.info("百度坐标:" + bp.getBdLng() + ", " + bp.getBdLat()); |
| | | mobilePosition.setGeodeticSystem("BD-09"); |
| | | mobilePosition.setCnLng(bp.getBdLng()); |
| | | mobilePosition.setCnLat(bp.getBdLat()); |
| | | if (!userSetup.getSavePositionHistory()) { |
| | | storager.clearMobilePositionsByDeviceId(deviceId); |
| | | } |
| | | storager.insertMobilePosition(mobilePosition); |
| | | } |
| | | // TODO: 需要实现存储报警信息、报警分类 |
| | | |
| | | // 回复200 OK |
| | | response200Ok(evt); |
| | | if (offLineDetector.isOnline(deviceId)) { |
| | | publisher.deviceAlarmEventPublish(deviceAlarm); |
| | | } |
| | | } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | /*** |
| | | * 处理catalog设备目录列表Notify |
| | | * |
| | | * @param evt |
| | | */ |
| | | private void processNotifyCatalogList(RequestEvent evt) { |
| | | try { |
| | | Element rootElement = getRootElement(evt); |
| | | Element deviceIdElement = rootElement.element("DeviceID"); |
| | | String deviceId = deviceIdElement.getText(); |
| | | Element deviceListElement = rootElement.element("DeviceList"); |
| | | if (deviceListElement == null) { |
| | | return; |
| | | } |
| | | Iterator<Element> deviceListIterator = deviceListElement.elementIterator(); |
| | | if (deviceListIterator != null) { |
| | | Device device = storager.queryVideoDevice(deviceId); |
| | | if (device == null) { |
| | | return; |
| | | } |
| | | // 遍历DeviceList |
| | | while (deviceListIterator.hasNext()) { |
| | | Element itemDevice = deviceListIterator.next(); |
| | | Element channelDeviceElement = itemDevice.element("DeviceID"); |
| | | if (channelDeviceElement == null) { |
| | | continue; |
| | | } |
| | | String channelDeviceId = channelDeviceElement.getTextTrim(); |
| | | Element channdelNameElement = itemDevice.element("Name"); |
| | | String channelName = channdelNameElement != null ? channdelNameElement.getTextTrim().toString() : ""; |
| | | Element statusElement = itemDevice.element("Status"); |
| | | String status = statusElement != null ? statusElement.getTextTrim().toString() : "ON"; |
| | | DeviceChannel deviceChannel = new DeviceChannel(); |
| | | deviceChannel.setName(channelName); |
| | | deviceChannel.setChannelId(channelDeviceId); |
| | | // ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理 |
| | | if (status.equals("ON") || status.equals("On") || status.equals("ONLINE")) { |
| | | deviceChannel.setStatus(1); |
| | | } |
| | | if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) { |
| | | deviceChannel.setStatus(0); |
| | | } |
| | | |
| | | deviceChannel.setManufacture(XmlUtil.getText(itemDevice, "Manufacturer")); |
| | | deviceChannel.setModel(XmlUtil.getText(itemDevice, "Model")); |
| | | deviceChannel.setOwner(XmlUtil.getText(itemDevice, "Owner")); |
| | | deviceChannel.setCivilCode(XmlUtil.getText(itemDevice, "CivilCode")); |
| | | deviceChannel.setBlock(XmlUtil.getText(itemDevice, "Block")); |
| | | deviceChannel.setAddress(XmlUtil.getText(itemDevice, "Address")); |
| | | if (XmlUtil.getText(itemDevice, "Parental") == null |
| | | || XmlUtil.getText(itemDevice, "Parental") == "") { |
| | | deviceChannel.setParental(0); |
| | | } else { |
| | | deviceChannel.setParental(Integer.parseInt(XmlUtil.getText(itemDevice, "Parental"))); |
| | | } |
| | | deviceChannel.setParentId(XmlUtil.getText(itemDevice, "ParentID")); |
| | | if (XmlUtil.getText(itemDevice, "SafetyWay") == null |
| | | || XmlUtil.getText(itemDevice, "SafetyWay") == "") { |
| | | deviceChannel.setSafetyWay(0); |
| | | } else { |
| | | deviceChannel.setSafetyWay(Integer.parseInt(XmlUtil.getText(itemDevice, "SafetyWay"))); |
| | | } |
| | | if (XmlUtil.getText(itemDevice, "RegisterWay") == null |
| | | || XmlUtil.getText(itemDevice, "RegisterWay") == "") { |
| | | deviceChannel.setRegisterWay(1); |
| | | } else { |
| | | deviceChannel.setRegisterWay(Integer.parseInt(XmlUtil.getText(itemDevice, "RegisterWay"))); |
| | | } |
| | | deviceChannel.setCertNum(XmlUtil.getText(itemDevice, "CertNum")); |
| | | if (XmlUtil.getText(itemDevice, "Certifiable") == null |
| | | || XmlUtil.getText(itemDevice, "Certifiable") == "") { |
| | | deviceChannel.setCertifiable(0); |
| | | } else { |
| | | deviceChannel.setCertifiable(Integer.parseInt(XmlUtil.getText(itemDevice, "Certifiable"))); |
| | | } |
| | | if (XmlUtil.getText(itemDevice, "ErrCode") == null |
| | | || XmlUtil.getText(itemDevice, "ErrCode") == "") { |
| | | deviceChannel.setErrCode(0); |
| | | } else { |
| | | deviceChannel.setErrCode(Integer.parseInt(XmlUtil.getText(itemDevice, "ErrCode"))); |
| | | } |
| | | deviceChannel.setEndTime(XmlUtil.getText(itemDevice, "EndTime")); |
| | | deviceChannel.setSecrecy(XmlUtil.getText(itemDevice, "Secrecy")); |
| | | deviceChannel.setIpAddress(XmlUtil.getText(itemDevice, "IPAddress")); |
| | | if (XmlUtil.getText(itemDevice, "Port") == null || XmlUtil.getText(itemDevice, "Port") == "") { |
| | | deviceChannel.setPort(0); |
| | | } else { |
| | | deviceChannel.setPort(Integer.parseInt(XmlUtil.getText(itemDevice, "Port"))); |
| | | } |
| | | deviceChannel.setPassword(XmlUtil.getText(itemDevice, "Password")); |
| | | if (NumericUtil.isDouble(XmlUtil.getText(itemDevice, "Longitude"))) { |
| | | deviceChannel.setLongitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Longitude"))); |
| | | } else { |
| | | deviceChannel.setLongitude(0.00); |
| | | } |
| | | if (NumericUtil.isDouble(XmlUtil.getText(itemDevice, "Latitude"))) { |
| | | deviceChannel.setLatitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Latitude"))); |
| | | } else { |
| | | deviceChannel.setLatitude(0.00); |
| | | } |
| | | if (XmlUtil.getText(itemDevice, "PTZType") == null |
| | | || XmlUtil.getText(itemDevice, "PTZType") == "") { |
| | | deviceChannel.setPTZType(0); |
| | | } else { |
| | | deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(itemDevice, "PTZType"))); |
| | | } |
| | | deviceChannel.setHasAudio(true); // 默认含有音频,播放时再检查是否有音频及是否AAC |
| | | storager.updateChannel(device.getDeviceId(), deviceChannel); |
| | | } |
| | | |
| | | // RequestMessage msg = new RequestMessage(); |
| | | // msg.setDeviceId(deviceId); |
| | | // msg.setType(DeferredResultHolder.CALLBACK_CMD_CATALOG); |
| | | // msg.setData(device); |
| | | // deferredResultHolder.invokeResult(msg); |
| | | // 回复200 OK |
| | | response200Ok(evt); |
| | | if (offLineDetector.isOnline(deviceId)) { |
| | | publisher.onlineEventPublish(deviceId, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE); |
| | | } |
| | | } |
| | | } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | /*** |
| | | * 回复200 OK |
| | | * |
| | | * @param evt |
| | | * @throws SipException |
| | | * @throws InvalidArgumentException |
| | | * @throws ParseException |
| | | */ |
| | | private void response200Ok(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException { |
| | | Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest()); |
| | | getServerTransaction(evt).sendResponse(response); |
| | | } |
| | | |
| | | private Element getRootElement(RequestEvent evt) throws DocumentException { |
| | | Request request = evt.getRequest(); |
| | | SAXReader reader = new SAXReader(); |
| | | reader.setEncoding("gbk"); |
| | | Document xml = reader.read(new ByteArrayInputStream(request.getRawContent())); |
| | | return xml.getRootElement(); |
| | | } |
| | | |
| | | public void setCmder(SIPCommander cmder) { |
| | | } |
| | | |
| | | public void setStorager(IVideoManagerStorager storager) { |
| | | this.storager = storager; |
| | | } |
| | | |
| | | public void setPublisher(EventPublisher publisher) { |
| | | this.publisher = publisher; |
| | | } |
| | | |
| | | public void setRedis(RedisUtil redis) { |
| | | } |
| | | |
| | | public void setDeferredResultHolder(DeferredResultHolder deferredResultHolder) { |
| | | } |
| | | |
| | | public void setOffLineDetector(DeviceOffLineDetector offLineDetector) { |
| | | this.offLineDetector = offLineDetector; |
| | | } |
| | | |
| | | public IRedisCatchStorage getRedisCatchStorage() { |
| | | return redisCatchStorage; |
| | | } |
| | | |
| | | public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) { |
| | | this.redisCatchStorage = redisCatchStorage; |
| | | } |
| | | } |
| | |
| | | */
|
| | | @Override
|
| | | public void process(RequestEvent evt) {
|
| | | System.out.println("no support the method! Method:" + evt.getRequest().getMethod());
|
| | | System.out.println("Unsupported the method: " + evt.getRequest().getMethod());
|
| | | }
|
| | |
|
| | | }
|
| | |
| | | // 下发catelog查询目录
|
| | | if (registerFlag == 1 && device != null) {
|
| | | logger.info("注册成功! deviceId:" + device.getDeviceId());
|
| | | boolean exists = storager.exists(device.getDeviceId());
|
| | | // boolean exists = storager.exists(device.getDeviceId());
|
| | | device.setRegisterTimeMillis(System.currentTimeMillis());
|
| | | storager.updateDevice(device);
|
| | | publisher.onlineEventPublish(device.getDeviceId(), VideoManagerConstants.EVENT_ONLINE_REGISTER);
|
| | |
| | | import javax.sip.message.Request;
|
| | | import javax.sip.message.Response;
|
| | |
|
| | | import gov.nist.javax.sip.header.CSeq;
|
| | | import org.slf4j.Logger;
|
| | | import org.slf4j.LoggerFactory;
|
| | | // import org.slf4j.Logger;
|
| | | // import org.slf4j.LoggerFactory;
|
| | | import org.springframework.stereotype.Component;
|
| | |
|
| | | import com.genersoft.iot.vmp.conf.SipConfig;
|
| | | import com.genersoft.iot.vmp.gb28181.SipLayer;
|
| | | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorFactory;
|
| | | import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
|
| | |
|
| | |
|
| | |
| | | @Component
|
| | | public class InviteResponseProcessor implements ISIPResponseProcessor {
|
| | |
|
| | | private final static Logger logger = LoggerFactory.getLogger(InviteResponseProcessor.class);
|
| | | // private final static Logger logger = LoggerFactory.getLogger(InviteResponseProcessor.class);
|
| | |
|
| | | /**
|
| | | * 处理invite响应
|
New file |
| | |
| | | package com.genersoft.iot.vmp.gb28181.utils; |
| | | |
| | | /** |
| | | * 数值格式判断和处理 |
| | | * @author lawrencehj |
| | | * @date 2021年1月27日 |
| | | */ |
| | | public class NumericUtil { |
| | | |
| | | /** |
| | | * 判断是否Double格式 |
| | | * @param str |
| | | * @return true/false |
| | | */ |
| | | public static boolean isDouble(String str) { |
| | | try { |
| | | Double num2 = Double.valueOf(str); |
| | | System.out.println(num2 + " is a valid numeric string!"); |
| | | return true; |
| | | } catch (Exception e) { |
| | | System.out.println(str + " is an invalid numeric string!"); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 判断是否Double格式 |
| | | * @param str |
| | | * @return true/false |
| | | */ |
| | | public static boolean isInteger(String str) { |
| | | try { |
| | | int num2 = Integer.valueOf(str); |
| | | System.out.println(num2 + " is an integer!"); |
| | | return true; |
| | | } catch (Exception e) { |
| | | System.out.println(str + " is not an integer!"); |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | |
| | | import java.util.List;
|
| | | import java.util.Map;
|
| | |
|
| | | import com.alibaba.fastjson.JSONArray;
|
| | | import com.alibaba.fastjson.JSONObject;
|
| | |
|
| | | import org.dom4j.Attribute;
|
| | | import org.dom4j.Document;
|
| | | import org.dom4j.DocumentException;
|
| | |
| | | *
|
| | | *
|
| | | */
|
| | | public class XmlUtil
|
| | | {
|
| | | public class XmlUtil {
|
| | | /**
|
| | | * 日志服务
|
| | | */
|
| | |
| | | /**
|
| | | * 解析XML为Document对象
|
| | | *
|
| | | * @param xml
|
| | | * 被解析的XMl
|
| | | * @param xml 被解析的XMl
|
| | | * |
| | | * @return Document
|
| | | */
|
| | | public static Element parseXml(String xml)
|
| | | {
|
| | | public static Element parseXml(String xml) {
|
| | | Document document = null;
|
| | | //
|
| | | StringReader sr = new StringReader(xml);
|
| | | SAXReader saxReader = new SAXReader();
|
| | | try
|
| | | {
|
| | | try {
|
| | | document = saxReader.read(sr);
|
| | | }
|
| | | catch (DocumentException e)
|
| | | {
|
| | | } catch (DocumentException e) {
|
| | | LOG.error("解析失败", e);
|
| | | }
|
| | | return null == document ? null : document.getRootElement();
|
| | |
| | | /**
|
| | | * 获取element对象的text的值
|
| | | *
|
| | | * @param em
|
| | | * 节点的对象
|
| | | * @param tag
|
| | | * 节点的tag
|
| | | * @param em 节点的对象
|
| | | * @param tag 节点的tag
|
| | | * @return 节点
|
| | | */
|
| | | public static String getText(Element em, String tag)
|
| | | {
|
| | | if (null == em)
|
| | | {
|
| | | public static String getText(Element em, String tag) {
|
| | | if (null == em) {
|
| | | return null;
|
| | | }
|
| | | Element e = em.element(tag);
|
| | |
| | | /**
|
| | | * 递归解析xml节点,适用于 多节点数据
|
| | | *
|
| | | * @param node
|
| | | * node
|
| | | * @param nodeName
|
| | | * nodeName
|
| | | * @param node node
|
| | | * @param nodeName nodeName
|
| | | * @return List<Map<String, Object>>
|
| | | */
|
| | | public static List<Map<String, Object>> listNodes(Element node, String nodeName)
|
| | | {
|
| | | if (null == node)
|
| | | {
|
| | | public static List<Map<String, Object>> listNodes(Element node, String nodeName) {
|
| | | if (null == node) {
|
| | | return null;
|
| | | }
|
| | | // 初始化返回
|
| | |
| | |
|
| | | Map<String, Object> map = null;
|
| | | // 遍历属性节点
|
| | | for (Attribute attribute : list)
|
| | | {
|
| | | if (nodeName.equals(node.getName()))
|
| | | {
|
| | | if (null == map)
|
| | | {
|
| | | for (Attribute attribute : list) {
|
| | | if (nodeName.equals(node.getName())) {
|
| | | if (null == map) {
|
| | | map = new HashMap<String, Object>();
|
| | | listMap.add(map);
|
| | | }
|
| | |
| | | // 遍历当前节点下的所有节点 ,nodeName 要解析的节点名称
|
| | | // 使用递归
|
| | | Iterator<Element> iterator = node.elementIterator();
|
| | | while (iterator.hasNext())
|
| | | {
|
| | | while (iterator.hasNext()) {
|
| | | Element e = iterator.next();
|
| | | listMap.addAll(listNodes(e, nodeName));
|
| | | }
|
| | | return listMap;
|
| | | }
|
| | |
|
| | | /**
|
| | | * xml转json
|
| | | * |
| | | * @param element
|
| | | * @param json
|
| | | */
|
| | | public static void node2Json(Element element, JSONObject json) {
|
| | | // 如果是属性
|
| | | for (Object o : element.attributes()) {
|
| | | Attribute attr = (Attribute) o;
|
| | | if (!isEmpty(attr.getValue())) {
|
| | | json.put("@" + attr.getName(), attr.getValue());
|
| | | }
|
| | | }
|
| | | List<Element> chdEl = element.elements();
|
| | | if (chdEl.isEmpty() && !isEmpty(element.getText())) {// 如果没有子元素,只有一个值
|
| | | json.put(element.getName(), element.getText());
|
| | | }
|
| | |
|
| | | for (Element e : chdEl) { // 有子元素
|
| | | if (!e.elements().isEmpty()) { // 子元素也有子元素
|
| | | JSONObject chdjson = new JSONObject();
|
| | | node2Json(e, chdjson);
|
| | | Object o = json.get(e.getName());
|
| | | if (o != null) {
|
| | | JSONArray jsona = null;
|
| | | if (o instanceof JSONObject) { // 如果此元素已存在,则转为jsonArray
|
| | | JSONObject jsono = (JSONObject) o;
|
| | | json.remove(e.getName());
|
| | | jsona = new JSONArray();
|
| | | jsona.add(jsono);
|
| | | jsona.add(chdjson);
|
| | | }
|
| | | if (o instanceof JSONArray) {
|
| | | jsona = (JSONArray) o;
|
| | | jsona.add(chdjson);
|
| | | }
|
| | | json.put(e.getName(), jsona);
|
| | | } else {
|
| | | if (!chdjson.isEmpty()) {
|
| | | json.put(e.getName(), chdjson);
|
| | | }
|
| | | }
|
| | | } else { // 子元素没有子元素
|
| | | for (Object o : element.attributes()) {
|
| | | Attribute attr = (Attribute) o;
|
| | | if (!isEmpty(attr.getValue())) {
|
| | | json.put("@" + attr.getName(), attr.getValue());
|
| | | }
|
| | | }
|
| | | if (!e.getText().isEmpty()) {
|
| | | json.put(e.getName(), e.getText());
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | public static boolean isEmpty(String str) {
|
| | | if (str == null || str.trim().isEmpty() || "null".equals(str)) {
|
| | | return true;
|
| | | }
|
| | | return false;
|
| | | }
|
| | | }
|
| | |
| | | package com.genersoft.iot.vmp.media.zlm; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.genersoft.iot.vmp.conf.MediaServerConfig; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | // import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| | | // import org.slf4j.Logger; |
| | | // import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.http.HttpHeaders; |
| | | import org.springframework.http.HttpRequest; |
| | | import org.springframework.http.HttpStatus; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.client.HttpClientErrorException; |
| | | import org.springframework.web.client.RestTemplate; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.util.Enumeration; |
| | | |
| | | @RestController |
| | | @RequestMapping("/zlm") |
| | | public class ZLMHTTPProxyController { |
| | | |
| | | |
| | | private final static Logger logger = LoggerFactory.getLogger(ZLMHTTPProxyController.class); |
| | | // private final static Logger logger = LoggerFactory.getLogger(ZLMHTTPProxyController.class); |
| | | |
| | | @Autowired |
| | | private IVideoManagerStorager storager; |
| | | // @Autowired |
| | | // private IVideoManagerStorager storager; |
| | | |
| | | @Autowired |
| | | private IRedisCatchStorage redisCatchStorage; |
| | |
| | | @ResponseBody
|
| | | @PostMapping(value = "/on_flow_report", produces = "application/json;charset=UTF-8")
|
| | | public ResponseEntity<String> onFlowReport(@RequestBody JSONObject json){
|
| | |
|
| | | logger.debug("ZLM HOOK on_flow_report API调用,参数:" + json.toString());
|
| | | // TODO Auto-generated method stub
|
| | |
|
| | | |
| | | if (logger.isDebugEnabled()) {
|
| | | logger.debug("ZLM HOOK on_flow_report API调用,参数:" + json.toString());
|
| | | }
|
| | | JSONObject ret = new JSONObject();
|
| | | ret.put("code", 0);
|
| | | ret.put("msg", "success");
|
| | |
| | | if (logger.isDebugEnabled()) {
|
| | | logger.debug("ZLM HOOK on_http_access API 调用,参数:" + json.toString());
|
| | | }
|
| | | // TODO Auto-generated method stub
|
| | | |
| | | JSONObject ret = new JSONObject();
|
| | | ret.put("code", 0);
|
| | | ret.put("err", "");
|
| | |
| | | if (logger.isDebugEnabled()) {
|
| | | logger.debug("ZLM HOOK on_play API调用,参数:" + json.toString());
|
| | | }
|
| | | // TODO Auto-generated method stub
|
| | | |
| | | JSONObject ret = new JSONObject();
|
| | | ret.put("code", 0);
|
| | | ret.put("msg", "success");
|
| | |
| | | if (logger.isDebugEnabled()) {
|
| | | logger.debug("ZLM HOOK on_publish API调用,参数:" + json.toString());
|
| | | }
|
| | | String app = json.getString("app");
|
| | | String streamId = json.getString("id");
|
| | |
|
| | | ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_publish, json);
|
| | | if (subscribe != null) subscribe.response(json);
|
| | |
|
| | |
|
| | | // TODO Auto-generated method stub
|
| | | |
| | | JSONObject ret = new JSONObject();
|
| | | ret.put("code", 0);
|
| | | ret.put("msg", "success");
|
| | |
| | | if (logger.isDebugEnabled()) {
|
| | | logger.debug("ZLM HOOK on_record_mp4 API调用,参数:" + json.toString());
|
| | | }
|
| | | // TODO Auto-generated method stub
|
| | | |
| | | JSONObject ret = new JSONObject();
|
| | | ret.put("code", 0);
|
| | | ret.put("msg", "success");
|
| | |
| | | if (logger.isDebugEnabled()) {
|
| | | logger.debug("ZLM HOOK on_rtsp_realm API调用,参数:" + json.toString());
|
| | | }
|
| | | // TODO Auto-generated method stub
|
| | | |
| | | JSONObject ret = new JSONObject();
|
| | | ret.put("code", 0);
|
| | | ret.put("realm", "");
|
| | |
| | | if (logger.isDebugEnabled()) {
|
| | | logger.debug("ZLM HOOK on_rtsp_auth API调用,参数:" + json.toString());
|
| | | }
|
| | | // TODO Auto-generated method stub
|
| | | |
| | | JSONObject ret = new JSONObject();
|
| | | ret.put("code", 0);
|
| | | ret.put("encrypted", false);
|
| | |
| | | redisCatchStorage.stopPlayback(streamInfo);
|
| | | }
|
| | | }
|
| | |
|
| | |
|
| | | JSONObject ret = new JSONObject();
|
| | | ret.put("code", 0);
|
| | | ret.put("msg", "success");
|
| | |
| | | if (logger.isDebugEnabled()) {
|
| | | logger.debug("ZLM HOOK on_stream_not_found API调用,参数:" + json.toString());
|
| | | }
|
| | | // TODO Auto-generated method stub
|
| | |
|
| | | if (autoApplyPlay) {
|
| | | String app = json.getString("app");
|
| | | String streamId = json.getString("stream");
|
| | |
| | | mediaServerConfig.setWanIp(StringUtils.isEmpty(mediaWanIp)? mediaIp: mediaWanIp);
|
| | | mediaServerConfig.setLocalIP(mediaIp);
|
| | | redisCatchStorage.updateMediaInfo(mediaServerConfig);
|
| | | // TODO Auto-generated method stub
|
| | | |
| | | JSONObject ret = new JSONObject();
|
| | | ret.put("code", 0);
|
| | | ret.put("msg", "success");
|
| | |
| | | package com.genersoft.iot.vmp.media.zlm; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.genersoft.iot.vmp.common.StreamInfo; |
| | | import com.genersoft.iot.vmp.conf.MediaServerConfig; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.http.HttpStatus; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.util.ConcurrentReferenceHashMap; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.math.BigInteger; |
| | | import java.text.DecimalFormat; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | |
| | | */ |
| | | @Component |
| | | public class ZLMHttpHookSubscribe { |
| | | |
| | | private final static Logger logger = LoggerFactory.getLogger(ZLMHttpHookSubscribe.class); |
| | | |
| | | public enum HookType{ |
| | | on_flow_report, |
| | |
| | | for (JSONObject key : eventMap.keySet()) { |
| | | Boolean result = null; |
| | | for (String s : key.keySet()) { |
| | | String string = hookResponse.getString(s); |
| | | String string1 = key.getString(s); |
| | | if (result == null) { |
| | | result = key.getString(s).equals(hookResponse.getString(s)); |
| | | }else { |
| | |
| | | import java.io.IOException; |
| | | import java.net.ConnectException; |
| | | import java.util.HashMap; |
| | | import java.util.HashSet; |
| | | import java.util.Map; |
| | | |
| | | @Component |
| | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.genersoft.iot.vmp.conf.MediaServerConfig; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| | | import okhttp3.*; |
| | | //import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.util.StringUtils; |
| | | |
| | | import java.io.IOException; |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.net.URLEncoder; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | |
| | | |
| | | private final static Logger logger = LoggerFactory.getLogger(ZLMRunner.class); |
| | | |
| | | @Autowired |
| | | private IVideoManagerStorager storager; |
| | | // @Autowired |
| | | // private IVideoManagerStorager storager; |
| | | |
| | | @Autowired |
| | | private IRedisCatchStorage redisCatchStorage; |
| | |
| | | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
| | | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
| | | import com.genersoft.iot.vmp.vmanager.platform.bean.ChannelReduce;
|
| | | import com.genersoft.iot.vmp.gb28181.bean.MobilePosition;
|
| | | import com.github.pagehelper.PageInfo;
|
| | | import gov.nist.javax.sip.stack.NioTcpMessageProcessor;
|
| | |
|
| | |
| | | DeviceChannel queryChannelInParentPlatform(String platformId, String channelId);
|
| | |
|
| | | Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId);
|
| | |
|
| | |
|
| | | /**
|
| | | * 添加Mobile Position设备移动位置
|
| | | * @param MobilePosition
|
| | | * @return
|
| | | */
|
| | | public boolean insertMobilePosition(MobilePosition mobilePosition);
|
| | |
|
| | | /**
|
| | | * 查询移动位置轨迹
|
| | | * @param deviceId
|
| | | * @param startTime
|
| | | * @param endTime
|
| | | */
|
| | | public List<MobilePosition> queryMobilePositions(String deviceId, String startTime, String endTime);
|
| | |
|
| | | /**
|
| | | * 查询最新移动位置
|
| | | * @param deviceId
|
| | | */
|
| | | public MobilePosition queryLatestPosition(String deviceId);
|
| | |
|
| | | /**
|
| | | * 删除指定设备的所有移动位置
|
| | | * @param deviceId
|
| | | */
|
| | | public int clearMobilePositionsByDeviceId(String deviceId);
|
| | | }
|
New file |
| | |
| | | package com.genersoft.iot.vmp.storager.dao; |
| | | |
| | | import java.util.List; |
| | | |
| | | import com.genersoft.iot.vmp.gb28181.bean.MobilePosition; |
| | | import org.apache.ibatis.annotations.*; |
| | | //import org.springframework.stereotype.Repository; |
| | | |
| | | @Mapper |
| | | //@Repository |
| | | public interface DeviceMobilePositionMapper { |
| | | |
| | | @Insert("INSERT INTO device_mobile_position (deviceId, deviceName, time, longitude, latitude, altitude, speed, direction, reportSource, geodeticSystem, cnLng, cnLat) " + |
| | | "VALUES ('${deviceId}', '${deviceName}', '${time}', ${longitude}, ${latitude}, ${altitude}, ${speed}, ${direction}, '${reportSource}', '${geodeticSystem}', '${cnLng}', '${cnLat}')") |
| | | int insertNewPosition(MobilePosition mobilePosition); |
| | | |
| | | @Select(value = {" <script>" + |
| | | "SELECT * FROM device_mobile_position" + |
| | | " WHERE deviceId = #{deviceId} " + |
| | | "<if test=\"startTime != null\"> AND time>=#{startTime}</if>" + |
| | | "<if test=\"endTime != null\"> AND time<=#{endTime}</if>" + |
| | | " ORDER BY time ASC" + |
| | | " </script>"}) |
| | | List<MobilePosition> queryPositionByDeviceIdAndTime(String deviceId, String startTime, String endTime); |
| | | |
| | | @Select("SELECT * FROM device_mobile_position WHERE deviceId = #{deviceId}" + |
| | | " ORDER BY time DESC LIMIT 1") |
| | | MobilePosition queryLatestPositionByDevice(String deviceId); |
| | | |
| | | @Delete("DELETE FROM device_mobile_position WHERE deviceId = #{deviceId}") |
| | | int clearMobilePositionsByDeviceId(String deviceId); |
| | | |
| | | } |
| | |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | |
| | | |
| | | @Override |
| | | public StreamInfo queryPlaybackByDevice(String deviceId, String code) { |
| | | String format = String.format("%S_*_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, |
| | | deviceId, |
| | | code); |
| | | // String format = String.format("%S_*_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, |
| | | // deviceId, |
| | | // code); |
| | | List<Object> playLeys = redis.scan(String.format("%S_*_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, |
| | | deviceId, |
| | | code)); |
| | |
| | | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| | | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | | import com.genersoft.iot.vmp.gb28181.bean.MobilePosition; |
| | | import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; |
| | | import com.genersoft.iot.vmp.storager.dao.DeviceMapper; |
| | | import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper; |
| | | import com.genersoft.iot.vmp.storager.dao.PatformChannelMapper; |
| | | import com.genersoft.iot.vmp.vmanager.platform.bean.ChannelReduce; |
| | | import com.genersoft.iot.vmp.storager.dao.DeviceMobilePositionMapper; |
| | | import com.github.pagehelper.PageHelper; |
| | | import com.github.pagehelper.PageInfo; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | |
| | | private DeviceMapper deviceMapper; |
| | | |
| | | @Autowired |
| | | private DeviceChannelMapper deviceChannelMapper; |
| | | private DeviceChannelMapper deviceChannelMapper; |
| | | |
| | | @Autowired |
| | | private DeviceMobilePositionMapper deviceMobilePositionMapper; |
| | | |
| | | @Autowired |
| | | private ParentPlatformMapper platformMapper; |
| | |
| | | @Override |
| | | public synchronized boolean online(String deviceId) { |
| | | Device device = deviceMapper.getDeviceByDeviceId(deviceId); |
| | | device.setOnline(1); |
| | | System.out.println("更新设备在线"); |
| | | if (device == null) { |
| | | return false; |
| | | } |
| | | device.setOnline(1); |
| | | System.out.println("更新设备在线"); |
| | | return deviceMapper.update(device) > 0; |
| | | } |
| | | |
| | |
| | | return deviceMapper.update(device) > 0; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 清空通道 |
| | | * @param deviceId |
| | | */ |
| | | @Override |
| | | public void cleanChannelsForDevice(String deviceId) { |
| | | int result = deviceChannelMapper.cleanChannelsByDeviceId(deviceId); |
| | | deviceChannelMapper.cleanChannelsByDeviceId(deviceId); |
| | | } |
| | | |
| | | /** |
| | | * 添加Mobile Position设备移动位置 |
| | | * @param MobilePosition |
| | | */ |
| | | @Override |
| | | public synchronized boolean insertMobilePosition(MobilePosition mobilePosition) { |
| | | return deviceMobilePositionMapper.insertNewPosition(mobilePosition) > 0; |
| | | } |
| | | |
| | | /** |
| | | * 查询移动位置轨迹 |
| | | * @param deviceId |
| | | * @param startTime |
| | | * @param endTime |
| | | */ |
| | | @Override |
| | | public synchronized List<MobilePosition> queryMobilePositions(String deviceId, String startTime, String endTime) { |
| | | return deviceMobilePositionMapper.queryPositionByDeviceIdAndTime(deviceId, startTime, endTime); |
| | | } |
| | | |
| | | @Override |
| | |
| | | |
| | | @Override |
| | | public PageInfo<ChannelReduce> queryAllChannelList(int page, int count, String query, Boolean online, |
| | | Boolean channelType, String platformId, Boolean inPlatform) { |
| | | Boolean channelType, String platformId, Boolean inPlatform) { |
| | | PageHelper.startPage(page, count); |
| | | List<ChannelReduce> all = deviceChannelMapper.queryChannelListInAll(query, online, channelType, platformId, inPlatform); |
| | | return new PageInfo<>(all); |
| | |
| | | Device device = patformChannelMapper.queryVideoDeviceByPlatformIdAndChannelId(platformId, channelId); |
| | | return device; |
| | | } |
| | | |
| | | /** |
| | | * 查询最新移动位置 |
| | | * @param deviceId |
| | | */ |
| | | @Override |
| | | public MobilePosition queryLatestPosition(String deviceId) { |
| | | return deviceMobilePositionMapper.queryLatestPositionByDevice(deviceId); |
| | | } |
| | | |
| | | /** |
| | | * 删除指定设备的所有移动位置 |
| | | * @param deviceId |
| | | */ |
| | | public int clearMobilePositionsByDeviceId(String deviceId) { |
| | | return deviceMobilePositionMapper.clearMobilePositionsByDeviceId(deviceId); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.genersoft.iot.vmp.utils; |
| | | |
| | | import java.io.BufferedReader; |
| | | import java.io.InputStreamReader; |
| | | import java.io.OutputStream; |
| | | import java.net.Socket; |
| | | import java.util.Base64; |
| | | |
| | | import com.genersoft.iot.vmp.gb28181.bean.BaiduPoint; |
| | | |
| | | public class GpsUtil { |
| | | public static BaiduPoint Wgs84ToBd09(String xx, String yy) { |
| | | try { |
| | | Socket s = new Socket("api.map.baidu.com", 80); |
| | | BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream(), "UTF-8")); |
| | | OutputStream out = s.getOutputStream(); |
| | | StringBuffer sb = new StringBuffer("GET /ag/coord/convert?from=0&to=4"); |
| | | sb.append("&x=" + xx + "&y=" + yy); |
| | | sb.append("&callback=BMap.Convertor.cbk_3976 HTTP/1.1\r\n"); |
| | | sb.append("User-Agent: Java/1.6.0_20\r\n"); |
| | | sb.append("Host: api.map.baidu.com:80\r\n"); |
| | | sb.append("Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n"); |
| | | sb.append("Connection: Close\r\n"); |
| | | sb.append("\r\n"); |
| | | out.write(sb.toString().getBytes()); |
| | | String json = ""; |
| | | String tmp = ""; |
| | | while ((tmp = br.readLine()) != null) { |
| | | // System.out.println(tmp); |
| | | json += tmp; |
| | | } |
| | | |
| | | s.close(); |
| | | int start = json.indexOf("cbk_3976"); |
| | | int end = json.lastIndexOf("}"); |
| | | if (start != -1 && end != -1 && json.contains("\"x\":\"")) { |
| | | json = json.substring(start, end); |
| | | String[] point = json.split(","); |
| | | String x = point[1].split(":")[1].replace("\"", ""); |
| | | String y = point[2].split(":")[1].replace("\"", ""); |
| | | BaiduPoint bdPoint= new BaiduPoint(); |
| | | bdPoint.setBdLng(new String(decode(x))); |
| | | bdPoint.setBdLat(new String(decode(y))); |
| | | return bdPoint; |
| | | //return (new String(decode(x)) + "," + new String(decode(y))); |
| | | } else { |
| | | System.out.println("gps坐标无效!!"); |
| | | } |
| | | out.close(); |
| | | br.close(); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * BASE64解码 |
| | | * @param str |
| | | * @return string |
| | | */ |
| | | public static byte[] decode(String str) { |
| | | byte[] bt = null; |
| | | final Base64.Decoder decoder = Base64.getDecoder(); |
| | | bt = decoder.decode(str); // .decodeBuffer(str); |
| | | return bt; |
| | | } |
| | | } |
| | |
| | | import java.util.concurrent.TimeUnit;
|
| | |
|
| | | import org.springframework.beans.factory.annotation.Autowired;
|
| | | import org.springframework.dao.DataAccessException;
|
| | | import org.springframework.data.redis.connection.RedisConnection;
|
| | | import org.springframework.data.redis.core.*;
|
| | | import org.springframework.stereotype.Component;
|
| | | import org.springframework.util.CollectionUtils;
|
| | |
| | | * @date: 2020年5月6日 下午8:27:29
|
| | | */
|
| | | @Component
|
| | | @SuppressWarnings(value = {"rawtypes", "unchecked"})
|
| | | public class RedisUtil {
|
| | |
|
| | | @Autowired
|
New file |
| | |
| | | package com.genersoft.iot.vmp.vmanager.MobilePosition; |
| | | |
| | | import java.util.List; |
| | | |
| | | import javax.sip.message.Response; |
| | | |
| | | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| | | import com.genersoft.iot.vmp.gb28181.bean.MobilePosition; |
| | | 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.cmd.impl.SIPCommander; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| | | import com.github.pagehelper.util.StringUtil; |
| | | |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.http.HttpStatus; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.web.bind.annotation.CrossOrigin; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.PathVariable; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | import org.springframework.web.context.request.async.DeferredResult; |
| | | |
| | | @CrossOrigin |
| | | @RestController |
| | | @RequestMapping("/api") |
| | | public class MobilePositionController { |
| | | |
| | | private final static Logger logger = LoggerFactory.getLogger(MobilePositionController.class); |
| | | |
| | | @Autowired |
| | | private IVideoManagerStorager storager; |
| | | |
| | | @Autowired |
| | | private SIPCommander cmder; |
| | | |
| | | @Autowired |
| | | private DeferredResultHolder resultHolder; |
| | | |
| | | @GetMapping("/positions/{deviceId}/history") |
| | | public ResponseEntity<List<MobilePosition>> positions(@PathVariable String deviceId, |
| | | @RequestParam(required = false) String start, |
| | | @RequestParam(required = false) String end) { |
| | | if (logger.isDebugEnabled()) { |
| | | logger.debug("查询设备" + deviceId + "的历史轨迹"); |
| | | } |
| | | |
| | | if (StringUtil.isEmpty(start)) { |
| | | start = null; |
| | | } |
| | | if (StringUtil.isEmpty(end)) { |
| | | end = null; |
| | | } |
| | | |
| | | List<MobilePosition> result = storager.queryMobilePositions(deviceId, start, end); |
| | | return new ResponseEntity<>(result, HttpStatus.OK); |
| | | } |
| | | |
| | | @GetMapping("/positions/{deviceId}/latest") |
| | | public ResponseEntity<MobilePosition> latestPosition(@PathVariable String deviceId) { |
| | | if (logger.isDebugEnabled()) { |
| | | logger.debug("查询设备" + deviceId + "的最新位置"); |
| | | } |
| | | MobilePosition result = storager.queryLatestPosition(deviceId); |
| | | return new ResponseEntity<>(result, HttpStatus.OK); |
| | | } |
| | | |
| | | @GetMapping("/positions/{deviceId}/realtime") |
| | | public DeferredResult<ResponseEntity<MobilePosition>> realTimePosition(@PathVariable String deviceId) { |
| | | Device device = storager.queryVideoDevice(deviceId); |
| | | cmder.mobilePostitionQuery(device, event -> { |
| | | Response response = event.getResponse(); |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_MOBILEPOSITION + deviceId); |
| | | msg.setData(String.format("获取移动位置信息失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); |
| | | resultHolder.invokeResult(msg); |
| | | }); |
| | | DeferredResult<ResponseEntity<MobilePosition>> result = new DeferredResult<ResponseEntity<MobilePosition>>(5*1000L); |
| | | result.onTimeout(()->{ |
| | | logger.warn(String.format("获取移动位置信息超时")); |
| | | // 释放rtpserver |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId); |
| | | msg.setData("Timeout"); |
| | | resultHolder.invokeResult(msg); |
| | | }); |
| | | resultHolder.put(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId, result); |
| | | return result; |
| | | } |
| | | |
| | | @GetMapping("/positions/{deviceId}/subscribe") |
| | | public ResponseEntity<String> positionSubscribe(@PathVariable String deviceId, |
| | | @RequestParam String expires, |
| | | @RequestParam String interval) { |
| | | String msg = ((expires.equals("0")) ? "取消" : "") + "订阅设备" + deviceId + "的移动位置"; |
| | | if (logger.isDebugEnabled()) { |
| | | logger.debug(msg); |
| | | } |
| | | |
| | | if (StringUtil.isEmpty(interval)) { |
| | | interval = "5"; |
| | | } |
| | | Device device = storager.queryVideoDevice(deviceId); |
| | | |
| | | String result = msg; |
| | | if (cmder.mobilePositionSubscribe(device, Integer.parseInt(expires), Integer.parseInt(interval))) { |
| | | result += ",成功"; |
| | | } else { |
| | | result += ",失败"; |
| | | } |
| | | |
| | | return new ResponseEntity<>(result, HttpStatus.OK); |
| | | } |
| | | } |
| | |
| | | import com.genersoft.iot.vmp.gb28181.event.alarm.AlarmEventListener; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Controller; |
| | | import org.springframework.web.bind.annotation.CrossOrigin; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | | import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; |
| | |
| | | * @data: 2021-01-20 |
| | | */ |
| | | |
| | | @CrossOrigin |
| | | @Controller |
| | | @RequestMapping("/api") |
| | | public class SseController { |
New file |
| | |
| | | /** |
| | | * 设备设置命令API接口 |
| | | * |
| | | * @author lawrencehj |
| | | * @date 2021年2月2日 |
| | | */ |
| | | |
| | | package com.genersoft.iot.vmp.vmanager.device; |
| | | |
| | | import javax.sip.message.Response; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| | | 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.cmd.impl.SIPCommander; |
| | | import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| | | |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.context.request.async.DeferredResult; |
| | | |
| | | @CrossOrigin |
| | | @RestController |
| | | @RequestMapping("/api") |
| | | public class DeviceConfig { |
| | | |
| | | private final static Logger logger = LoggerFactory.getLogger(DeviceQuery.class); |
| | | |
| | | @Autowired |
| | | private IVideoManagerStorager storager; |
| | | |
| | | @Autowired |
| | | private SIPCommander cmder; |
| | | |
| | | @Autowired |
| | | private DeferredResultHolder resultHolder; |
| | | |
| | | /** |
| | | * 看守位控制命令API接口 |
| | | * |
| | | * @param deviceId |
| | | * @param enabled 看守位使能1:开启,0:关闭 |
| | | * @param resetTime 自动归位时间间隔(可选) |
| | | * @param presetIndex 调用预置位编号(可选) |
| | | * @param channelId 通道编码(可选) |
| | | */ |
| | | @GetMapping("/config/{deviceId}/basicParam") |
| | | public DeferredResult<ResponseEntity<String>> homePositionApi(@PathVariable String deviceId, |
| | | @RequestParam(required = false) String channelId, |
| | | @RequestParam(required = false) String name, |
| | | @RequestParam(required = false) String expiration, |
| | | @RequestParam(required = false) String heartBeatInterval, |
| | | @RequestParam(required = false) String heartBeatCount) { |
| | | if (logger.isDebugEnabled()) { |
| | | logger.debug("报警复位API调用"); |
| | | } |
| | | Device device = storager.queryVideoDevice(deviceId); |
| | | cmder.deviceBasicConfigCmd(device, channelId, name, expiration, heartBeatInterval, heartBeatCount, event -> { |
| | | Response response = event.getResponse(); |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICECONFIG + (XmlUtil.isEmpty(channelId) ? deviceId : channelId)); |
| | | msg.setData(String.format("设备配置操作失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); |
| | | resultHolder.invokeResult(msg); |
| | | }); |
| | | DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(3 * 1000L); |
| | | result.onTimeout(() -> { |
| | | logger.warn(String.format("设备配置操作超时, 设备未返回应答指令")); |
| | | // 释放rtpserver |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICECONFIG + (XmlUtil.isEmpty(channelId) ? deviceId : channelId)); |
| | | JSONObject json = new JSONObject(); |
| | | json.put("DeviceID", deviceId); |
| | | json.put("Status", "Timeout"); |
| | | json.put("Description", "设备配置操作超时, 设备未返回应答指令"); |
| | | msg.setData(json); //("看守位控制操作超时, 设备未返回应答指令"); |
| | | resultHolder.invokeResult(msg); |
| | | }); |
| | | resultHolder.put(DeferredResultHolder.CALLBACK_CMD_DEVICECONFIG + (XmlUtil.isEmpty(channelId) ? deviceId : channelId), result); |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 设备配置查询请求API接口 |
| | | * |
| | | * @param deviceId |
| | | */ |
| | | @GetMapping("/config/{deviceId}/query/{configType}") |
| | | public DeferredResult<ResponseEntity<String>> configDownloadApi(@PathVariable String deviceId, |
| | | @PathVariable String configType, |
| | | @RequestParam(required = false) String channelId) { |
| | | if (logger.isDebugEnabled()) { |
| | | logger.debug("设备状态查询API调用"); |
| | | } |
| | | Device device = storager.queryVideoDevice(deviceId); |
| | | cmder.deviceConfigQuery(device, channelId, configType, event -> { |
| | | Response response = event.getResponse(); |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD + (XmlUtil.isEmpty(channelId) ? deviceId : channelId)); |
| | | msg.setData(String.format("获取设备配置失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); |
| | | resultHolder.invokeResult(msg); |
| | | }); |
| | | DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String >> (3 * 1000L); |
| | | result.onTimeout(()->{ |
| | | logger.warn(String.format("获取设备配置超时")); |
| | | // 释放rtpserver |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD + (XmlUtil.isEmpty(channelId) ? deviceId : channelId)); |
| | | msg.setData("Timeout. Device did not response to this command."); |
| | | resultHolder.invokeResult(msg); |
| | | }); |
| | | resultHolder.put(DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD + (XmlUtil.isEmpty(channelId) ? deviceId : channelId), result); |
| | | return result; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /** |
| | | * 设备控制命令API接口 |
| | | * |
| | | * @author lawrencehj |
| | | * @date 2021年2月1日 |
| | | */ |
| | | |
| | | package com.genersoft.iot.vmp.vmanager.device; |
| | | |
| | | import javax.sip.message.Response; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| | | 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.cmd.impl.SIPCommander; |
| | | import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| | | |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.http.HttpStatus; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.context.request.async.DeferredResult; |
| | | |
| | | @CrossOrigin |
| | | @RestController |
| | | @RequestMapping("/api") |
| | | public class DeviceControl { |
| | | |
| | | private final static Logger logger = LoggerFactory.getLogger(DeviceQuery.class); |
| | | |
| | | @Autowired |
| | | private IVideoManagerStorager storager; |
| | | |
| | | @Autowired |
| | | private SIPCommander cmder; |
| | | |
| | | @Autowired |
| | | private DeferredResultHolder resultHolder; |
| | | |
| | | /** |
| | | * 远程启动控制命令API接口 |
| | | * |
| | | * @param deviceId |
| | | */ |
| | | @GetMapping("/control/{deviceId}/teleboot") |
| | | @PostMapping("/control/{deviceId}/teleboot") |
| | | public ResponseEntity<String> teleBootApi(@PathVariable String deviceId) { |
| | | if (logger.isDebugEnabled()) { |
| | | logger.debug("设备远程启动API调用"); |
| | | } |
| | | Device device = storager.queryVideoDevice(deviceId); |
| | | boolean sucsess = cmder.teleBootCmd(device); |
| | | if (sucsess) { |
| | | JSONObject json = new JSONObject(); |
| | | json.put("DeviceID", deviceId); |
| | | json.put("Result", "OK"); |
| | | return new ResponseEntity<>(json.toJSONString(), HttpStatus.OK); |
| | | } else { |
| | | logger.warn("设备远程启动API调用失败!"); |
| | | return new ResponseEntity<String>("设备远程启动API调用失败!", HttpStatus.INTERNAL_SERVER_ERROR); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 录像控制命令API接口 |
| | | * |
| | | * @param deviceId |
| | | * @param recordCmdStr Record:手动录像,StopRecord:停止手动录像 |
| | | * @param channelId 通道编码(可选) |
| | | */ |
| | | @GetMapping("/control/{deviceId}/record/{recordCmdStr}") |
| | | public DeferredResult<ResponseEntity<String>> recordApi(@PathVariable String deviceId, |
| | | @PathVariable String recordCmdStr, @RequestParam(required = false) String channelId) { |
| | | if (logger.isDebugEnabled()) { |
| | | logger.debug("开始/停止录像API调用"); |
| | | } |
| | | Device device = storager.queryVideoDevice(deviceId); |
| | | cmder.recordCmd(device, channelId, recordCmdStr, event -> { |
| | | Response response = event.getResponse(); |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + (XmlUtil.isEmpty(channelId) ? deviceId : channelId)); |
| | | msg.setData(String.format("开始/停止录像操作失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); |
| | | resultHolder.invokeResult(msg); |
| | | }); |
| | | DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(3 * 1000L); |
| | | result.onTimeout(() -> { |
| | | logger.warn(String.format("开始/停止录像操作超时, 设备未返回应答指令")); |
| | | // 释放rtpserver |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + (XmlUtil.isEmpty(channelId) ? deviceId : channelId)); |
| | | msg.setData("Timeout. Device did not response to this command."); |
| | | resultHolder.invokeResult(msg); |
| | | }); |
| | | resultHolder.put(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + (XmlUtil.isEmpty(channelId) ? deviceId : channelId), result); |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 报警布防/撤防命令API接口 |
| | | * |
| | | * @param deviceId |
| | | * @param guardCmdStr SetGuard:布防,ResetGuard:撤防 |
| | | */ |
| | | @GetMapping("/control/{deviceId}/guard/{guardCmdStr}") |
| | | public DeferredResult<ResponseEntity<String>> guardApi(@PathVariable String deviceId, @PathVariable String guardCmdStr) { |
| | | if (logger.isDebugEnabled()) { |
| | | logger.debug("布防/撤防API调用"); |
| | | } |
| | | Device device = storager.queryVideoDevice(deviceId); |
| | | cmder.guardCmd(device, guardCmdStr, event -> { |
| | | Response response = event.getResponse(); |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId); |
| | | msg.setData(String.format("布防/撤防操作失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); |
| | | resultHolder.invokeResult(msg); |
| | | }); |
| | | DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(3 * 1000L); |
| | | result.onTimeout(() -> { |
| | | logger.warn(String.format("布防/撤防操作超时, 设备未返回应答指令")); |
| | | // 释放rtpserver |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId); |
| | | msg.setData("Timeout. Device did not response to this command."); |
| | | resultHolder.invokeResult(msg); |
| | | }); |
| | | resultHolder.put(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId, result); |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 报警复位API接口 |
| | | * |
| | | * @param deviceId |
| | | * @param alarmMethod 报警方式(可选) |
| | | * @param alarmType 报警类型(可选) |
| | | */ |
| | | @GetMapping("/control/{deviceId}/resetAlarm") |
| | | public DeferredResult<ResponseEntity<String>> resetAlarmApi(@PathVariable String deviceId, |
| | | @RequestParam(required = false) String alarmMethod, |
| | | @RequestParam(required = false) String alarmType) { |
| | | if (logger.isDebugEnabled()) { |
| | | logger.debug("报警复位API调用"); |
| | | } |
| | | Device device = storager.queryVideoDevice(deviceId); |
| | | cmder.alarmCmd(device, alarmMethod, alarmType, event -> { |
| | | Response response = event.getResponse(); |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId); |
| | | msg.setData(String.format("报警复位操作失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); |
| | | resultHolder.invokeResult(msg); |
| | | }); |
| | | DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(3 * 1000L); |
| | | result.onTimeout(() -> { |
| | | logger.warn(String.format("报警复位操作超时, 设备未返回应答指令")); |
| | | // 释放rtpserver |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId); |
| | | msg.setData("Timeout. Device did not response to this command."); |
| | | resultHolder.invokeResult(msg); |
| | | }); |
| | | resultHolder.put(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId, result); |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 强制关键帧API接口 |
| | | * |
| | | * @param deviceId |
| | | * @param channelId |
| | | */ |
| | | @GetMapping("/control/{deviceId}/iFrame") |
| | | @PostMapping("/control/{deviceId}/iFrame") |
| | | public ResponseEntity<String> iFrame(@PathVariable String deviceId, |
| | | @RequestParam(required = false) String channelId) { |
| | | if (logger.isDebugEnabled()) { |
| | | logger.debug("强制关键帧API调用"); |
| | | } |
| | | Device device = storager.queryVideoDevice(deviceId); |
| | | boolean sucsess = cmder.iFrameCmd(device, channelId); |
| | | if (sucsess) { |
| | | JSONObject json = new JSONObject(); |
| | | json.put("DeviceID", deviceId); |
| | | json.put("ChannelID", channelId); |
| | | json.put("Result", "OK"); |
| | | return new ResponseEntity<>(json.toJSONString(), HttpStatus.OK); |
| | | } else { |
| | | logger.warn("强制关键帧API调用失败!"); |
| | | return new ResponseEntity<String>("强制关键帧API调用失败!", HttpStatus.INTERNAL_SERVER_ERROR); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 看守位控制命令API接口 |
| | | * |
| | | * @param deviceId |
| | | * @param enabled 看守位使能1:开启,0:关闭 |
| | | * @param resetTime 自动归位时间间隔(可选) |
| | | * @param presetIndex 调用预置位编号(可选) |
| | | * @param channelId 通道编码(可选) |
| | | */ |
| | | @GetMapping("/control/{deviceId}/homePosition/{enabled}") |
| | | public DeferredResult<ResponseEntity<String>> homePositionApi(@PathVariable String deviceId, |
| | | @PathVariable String enabled, |
| | | @RequestParam(required = false) String resetTime, |
| | | @RequestParam(required = false) String presetIndex, |
| | | @RequestParam(required = false) String channelId) { |
| | | if (logger.isDebugEnabled()) { |
| | | logger.debug("报警复位API调用"); |
| | | } |
| | | Device device = storager.queryVideoDevice(deviceId); |
| | | cmder.homePositionCmd(device, channelId, enabled, resetTime, presetIndex, event -> { |
| | | Response response = event.getResponse(); |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + (XmlUtil.isEmpty(channelId) ? deviceId : channelId)); |
| | | msg.setData(String.format("看守位控制操作失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); |
| | | resultHolder.invokeResult(msg); |
| | | }); |
| | | DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(3 * 1000L); |
| | | result.onTimeout(() -> { |
| | | logger.warn(String.format("看守位控制操作超时, 设备未返回应答指令")); |
| | | // 释放rtpserver |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + (XmlUtil.isEmpty(channelId) ? deviceId : channelId)); |
| | | JSONObject json = new JSONObject(); |
| | | json.put("DeviceID", deviceId); |
| | | json.put("Status", "Timeout"); |
| | | json.put("Description", "看守位控制操作超时, 设备未返回应答指令"); |
| | | msg.setData(json); //("看守位控制操作超时, 设备未返回应答指令"); |
| | | resultHolder.invokeResult(msg); |
| | | }); |
| | | resultHolder.put(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + (XmlUtil.isEmpty(channelId) ? deviceId : channelId), result); |
| | | return result; |
| | | } |
| | | } |
File was renamed from src/main/java/com/genersoft/iot/vmp/vmanager/device/DeviceController.java |
| | |
| | | |
| | | import javax.sip.message.Response; |
| | | |
| | | @SuppressWarnings("rawtypes") |
| | | @CrossOrigin |
| | | @RestController |
| | | @RequestMapping("/api") |
| | | public class DeviceController { |
| | | public class DeviceQuery { |
| | | |
| | | private final static Logger logger = LoggerFactory.getLogger(DeviceController.class); |
| | | private final static Logger logger = LoggerFactory.getLogger(DeviceQuery.class); |
| | | |
| | | @Autowired |
| | | private IVideoManagerStorager storager; |
| | |
| | | int page, int count, |
| | | @RequestParam(required = false) String query, |
| | | @RequestParam(required = false) Boolean online, |
| | | @RequestParam(required = false) Boolean channelType |
| | | ){ |
| | | |
| | | @RequestParam(required = false) Boolean channelType) { |
| | | if (logger.isDebugEnabled()) { |
| | | logger.debug("查询所有视频设备API调用"); |
| | | logger.debug("查询视频设备通道API调用"); |
| | | } |
| | | if (StringUtils.isEmpty(query)) { |
| | | query = null; |
| | |
| | | json.put("deviceId", deviceId); |
| | | return new ResponseEntity<>(json.toString(),HttpStatus.OK); |
| | | } else { |
| | | logger.warn("设备预览API调用失败!"); |
| | | return new ResponseEntity<String>("设备预览API调用失败!", HttpStatus.INTERNAL_SERVER_ERROR); |
| | | logger.warn("设备信息删除API调用失败!"); |
| | | return new ResponseEntity<String>("设备信息删除API调用失败!", HttpStatus.INTERNAL_SERVER_ERROR); |
| | | } |
| | | } |
| | | |
| | |
| | | @RequestParam(required = false) Boolean channelType){ |
| | | |
| | | if (logger.isDebugEnabled()) { |
| | | logger.debug("查询所有视频设备API调用"); |
| | | logger.debug("查询所有视频通道API调用"); |
| | | } |
| | | DeviceChannel deviceChannel = storager.queryChannel(deviceId,channelId); |
| | | if (deviceChannel == null) { |
| | |
| | | storager.updateDevice(device); |
| | | return new ResponseEntity<>(null,HttpStatus.OK); |
| | | } |
| | | |
| | | /** |
| | | * 设备状态查询请求API接口 |
| | | * |
| | | * @param deviceId |
| | | */ |
| | | @GetMapping("/devices/{deviceId}/status") |
| | | public DeferredResult<ResponseEntity<String>> deviceStatusApi(@PathVariable String deviceId) { |
| | | if (logger.isDebugEnabled()) { |
| | | logger.debug("设备状态查询API调用"); |
| | | } |
| | | Device device = storager.queryVideoDevice(deviceId); |
| | | cmder.deviceStatusQuery(device, event -> { |
| | | Response response = event.getResponse(); |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS + deviceId); |
| | | msg.setData(String.format("获取设备状态失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); |
| | | resultHolder.invokeResult(msg); |
| | | }); |
| | | DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(2*1000L); |
| | | result.onTimeout(()->{ |
| | | logger.warn(String.format("获取设备状态超时")); |
| | | // 释放rtpserver |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS + deviceId); |
| | | msg.setData("Timeout. Device did not response to this command."); |
| | | resultHolder.invokeResult(msg); |
| | | }); |
| | | resultHolder.put(DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS + deviceId, result); |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 设备报警查询请求API接口 |
| | | * |
| | | * @param deviceId |
| | | */ |
| | | @GetMapping("/alarm/{deviceId}") |
| | | public DeferredResult<ResponseEntity<String>> alarmApi(@PathVariable String deviceId, |
| | | @RequestParam(required = false) String startPriority, |
| | | @RequestParam(required = false) String endPriority, |
| | | @RequestParam(required = false) String alarmMethod, |
| | | @RequestParam(required = false) String alarmType, |
| | | @RequestParam(required = false) String startTime, |
| | | @RequestParam(required = false) String endTime) { |
| | | if (logger.isDebugEnabled()) { |
| | | logger.debug("设备报警查询API调用"); |
| | | } |
| | | Device device = storager.queryVideoDevice(deviceId); |
| | | cmder.alarmInfoQuery(device, startPriority, endPriority, alarmMethod, alarmType, startTime, endTime, event -> { |
| | | Response response = event.getResponse(); |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_ALARM + deviceId); |
| | | msg.setData(String.format("设备报警查询失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); |
| | | resultHolder.invokeResult(msg); |
| | | }); |
| | | DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String >> (3 * 1000L); |
| | | result.onTimeout(()->{ |
| | | logger.warn(String.format("设备报警查询超时")); |
| | | // 释放rtpserver |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_ALARM + deviceId); |
| | | msg.setData("设备报警查询超时"); |
| | | resultHolder.invokeResult(msg); |
| | | }); |
| | | resultHolder.put(DeferredResultHolder.CALLBACK_CMD_ALARM + deviceId, result); |
| | | return result; |
| | | } |
| | | |
| | | |
| | | } |
| | |
| | | package com.genersoft.iot.vmp.vmanager.play; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.genersoft.iot.vmp.common.StreamInfo; |
| | | import com.genersoft.iot.vmp.conf.MediaServerConfig; |
| | | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; |
| | | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
| | | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | | import com.genersoft.iot.vmp.vmanager.play.bean.PlayResult; |
| | | import com.genersoft.iot.vmp.vmanager.service.IPlayService; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.http.HttpStatus; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.web.bind.annotation.CrossOrigin; |
| | |
| | | import org.springframework.web.context.request.async.DeferredResult; |
| | | |
| | | import javax.sip.message.Response; |
| | | import java.text.DecimalFormat; |
| | | import java.util.UUID; |
| | | |
| | | @CrossOrigin |
| | |
| | | storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_STOP + uuid); |
| | | Response response = event.getResponse(); |
| | | //Response response = event.getResponse(); |
| | | msg.setData(String.format("success")); |
| | | resultHolder.invokeResult(msg); |
| | | } |
| | |
| | | package com.genersoft.iot.vmp.vmanager.playback; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.genersoft.iot.vmp.common.StreamInfo; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; |
| | | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
| | | //import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | | import com.genersoft.iot.vmp.vmanager.service.IPlayService; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.http.HttpStatus; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.util.StringUtils; |
| | | import org.springframework.web.bind.annotation.CrossOrigin; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.PathVariable; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | |
| | | @Autowired |
| | | private IRedisCatchStorage redisCatchStorage; |
| | | |
| | | @Autowired |
| | | private ZLMRESTfulUtils zlmresTfulUtils; |
| | | // @Autowired |
| | | // private ZLMRESTfulUtils zlmresTfulUtils; |
| | | |
| | | @Autowired |
| | | private IPlayService playService; |
| | |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.http.HttpStatus; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.web.bind.annotation.CrossOrigin; |
| | | import org.springframework.web.bind.annotation.PathVariable; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.context.request.async.DeferredResult; |
| | | |
| | | import javax.sip.message.Response; |
| | | |
| | | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| | | 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.cmd.impl.SIPCommander; |
| | | import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| | | |
| | | @CrossOrigin |
| | |
| | | @Autowired |
| | | private IVideoManagerStorager storager; |
| | | |
| | | @Autowired |
| | | private DeferredResultHolder resultHolder; |
| | | |
| | | /*** |
| | | * 云台控制 |
| | | * @param deviceId 设备id |
| | |
| | | cmder.frontEndCmd(device, channelId, cmdCode, horizonSpeed, verticalSpeed, zoomSpeed); |
| | | return new ResponseEntity<String>("success",HttpStatus.OK); |
| | | } |
| | | // public ResponseEntity<String> ptz(@PathVariable String deviceId,@PathVariable String channelId,int leftRight, int upDown, int inOut, int moveSpeed, int zoomSpeed){ |
| | | |
| | | // if (logger.isDebugEnabled()) { |
| | | // logger.debug(String.format("设备云台控制 API调用,deviceId:%s ,channelId:%s ,leftRight:%d ,upDown:%d ,inOut:%d ,moveSpeed:%d ,zoomSpeed:%d",deviceId, channelId, leftRight, upDown, inOut, moveSpeed, zoomSpeed)); |
| | | // } |
| | | // Device device = storager.queryVideoDevice(deviceId); |
| | | |
| | | // cmder.ptzCmd(device, channelId, leftRight, upDown, inOut, moveSpeed, zoomSpeed); |
| | | // return new ResponseEntity<String>("success",HttpStatus.OK); |
| | | // } |
| | | |
| | | /** |
| | | * 通用前端控制命令API接口 |
| | | * |
| | | * @param deviceId |
| | | * @param channelId |
| | | * @param cmdCode |
| | | * @param parameter1 |
| | | * @param parameter2 |
| | | * @param combindCode2 |
| | | * @return |
| | | */ |
| | | @PostMapping("/frontEndCommand/{deviceId}/{channelId}") |
| | | public ResponseEntity<String> frontEndCommand(@PathVariable String deviceId,@PathVariable String channelId,int cmdCode, int parameter1, int parameter2, int combindCode2){ |
| | | |
| | |
| | | cmder.frontEndCmd(device, channelId, cmdCode, parameter1, parameter2, combindCode2); |
| | | return new ResponseEntity<String>("success",HttpStatus.OK); |
| | | } |
| | | |
| | | /** |
| | | * 预置位查询命令API接口 |
| | | * |
| | | * @param deviceId |
| | | * @param channelId |
| | | * @return |
| | | */ |
| | | @GetMapping("/presetQuery/{deviceId}/{channelId}") |
| | | public DeferredResult<ResponseEntity<String>> presetQueryApi(@PathVariable String deviceId, @PathVariable String channelId) { |
| | | if (logger.isDebugEnabled()) { |
| | | logger.debug("设备预置位查询API调用"); |
| | | } |
| | | Device device = storager.queryVideoDevice(deviceId); |
| | | cmder.presetQuery(device, channelId, event -> { |
| | | Response response = event.getResponse(); |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_PRESETQUERY + (XmlUtil.isEmpty(channelId) ? deviceId : channelId)); |
| | | msg.setData(String.format("获取设备预置位失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); |
| | | resultHolder.invokeResult(msg); |
| | | }); |
| | | DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String >> (3 * 1000L); |
| | | result.onTimeout(()->{ |
| | | logger.warn(String.format("获取设备预置位超时")); |
| | | // 释放rtpserver |
| | | RequestMessage msg = new RequestMessage(); |
| | | msg.setId(DeferredResultHolder.CALLBACK_CMD_PRESETQUERY + (XmlUtil.isEmpty(channelId) ? deviceId : channelId)); |
| | | msg.setData("获取设备预置位超时"); |
| | | resultHolder.invokeResult(msg); |
| | | }); |
| | | resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PRESETQUERY + (XmlUtil.isEmpty(channelId) ? deviceId : channelId), result); |
| | | return result; |
| | | } |
| | | } |
| | |
| | | package com.genersoft.iot.vmp.vmanager.service; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.genersoft.iot.vmp.common.StreamInfo; |
| | | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; |
| | | import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; |
| | | import com.genersoft.iot.vmp.vmanager.play.bean.PlayResult; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.web.context.request.async.DeferredResult; |
| | | |
| | | /** |
| | | * 点播处理 |
| | |
| | | package com.genersoft.iot.vmp.vmanager.user; |
| | | |
| | | import com.genersoft.iot.vmp.vmanager.play.PlayController; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.util.StringUtils; |
| | | import org.springframework.web.bind.annotation.CrossOrigin; |
| | |
| | | @RestController |
| | | @RequestMapping("/api") |
| | | public class UserController { |
| | | |
| | | private final static Logger logger = LoggerFactory.getLogger(UserController.class); |
| | | |
| | | |
| | | @Value("${auth.username}") |
| | | private String usernameConfig; |
| | |
| | | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| | | import com.genersoft.iot.vmp.vmanager.ptz.PtzController; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.http.HttpStatus; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | /** |
| | |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Controller; |
| | | import org.springframework.web.bind.annotation.CrossOrigin; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | | import org.springframework.web.bind.annotation.ResponseBody; |
| | | |
| | | /** |
| | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| | | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| | | import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; |
| | | // import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector; |
| | | // import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; |
| | | // import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| | | import com.github.pagehelper.PageInfo; |
| | | import org.slf4j.Logger; |
| | |
| | | /** |
| | | * 兼容LiveGBS的API:设备信息 |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | @CrossOrigin |
| | | @RestController |
| | | @RequestMapping(value = "/api/v1/device") |
| | |
| | | @Autowired |
| | | private IVideoManagerStorager storager; |
| | | |
| | | @Autowired |
| | | private SIPCommander cmder; |
| | | // @Autowired |
| | | // private SIPCommander cmder; |
| | | |
| | | @Autowired |
| | | private DeferredResultHolder resultHolder; |
| | | // @Autowired |
| | | // private DeferredResultHolder resultHolder; |
| | | |
| | | @Autowired |
| | | private DeviceOffLineDetector offLineDetector; |
| | | // @Autowired |
| | | // private DeviceOffLineDetector offLineDetector; |
| | | |
| | | /** |
| | | * 分页获取设备列表 TODO 现在直接返回,尚未实现分页 |
| | |
| | | package com.genersoft.iot.vmp.web; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.genersoft.iot.vmp.common.StreamInfo; |
| | | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| | | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; |
| | | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
| | | // import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| | | import com.genersoft.iot.vmp.vmanager.play.PlayController; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.http.HttpStatus; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.context.request.async.DeferredResult; |
| | |
| | | /** |
| | | * 兼容LiveGBS的API:实时直播 |
| | | */ |
| | | @SuppressWarnings(value = {"rawtypes", "unchecked"}) |
| | | @CrossOrigin |
| | | @RestController |
| | | @RequestMapping(value = "/api/v1/stream") |
| | |
| | | private IRedisCatchStorage redisCatchStorage; |
| | | |
| | | |
| | | @Autowired |
| | | private ZLMRESTfulUtils zlmresTfulUtils; |
| | | // @Autowired |
| | | // private ZLMRESTfulUtils zlmresTfulUtils; |
| | | |
| | | |
| | | @Autowired |
| | |
| | | package com.genersoft.iot.vmp.web; |
| | | |
| | | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.stereotype.Controller; |
| | | import org.springframework.util.StringUtils; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | |
| | | level: |
| | | com: |
| | | genersoft: |
| | | iot: debug |
| | | iot: debug |
| | | # [根据业务需求配置] |
| | | userSettings: |
| | | # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) |
| | | savePositionHistory: false |
| | |
| | | // to edit target browsers: use "browserslist" field in package.json |
| | | "autoprefixer": {}, |
| | | 'postcss-pxtorem': { |
| | | rootValue: 16, |
| | | rootValue: 24, |
| | | propList: ['font-size'] // 只转化font-size |
| | | } |
| | | } |
| | |
| | | </head> |
| | | <body> |
| | | <script type="text/javascript" src="./js/EasyWasmPlayer.js"></script> |
| | | <script type="text/javascript" src="//api.map.baidu.com/api?v=2.0&ak=rk73w8dv1rkE4UdZsataG68VarhYQzrx&s=1"></script> |
| | | <div id="app"></div> |
| | | <!-- built files will be auto injected --> |
| | | </body> |
| | |
| | | "integrity": "sha1-nyKcFb4nJFT/qXOs4NvueaGww28=", |
| | | "dev": true |
| | | }, |
| | | "bmaplib.curveline": { |
| | | "version": "1.0.0", |
| | | "resolved": "https://registry.npmjs.org/bmaplib.curveline/-/bmaplib.curveline-1.0.0.tgz", |
| | | "integrity": "sha512-9wcFMVhiYxNPqpvsLDAADn3qDhNzXp2mA6VyHSHg2XOAgSooC7ZiujdFhy0sp+0QYjTfJ/MjmLuNoUg2HHxH4Q==" |
| | | }, |
| | | "bmaplib.heatmap": { |
| | | "version": "1.0.4", |
| | | "resolved": "https://registry.npmjs.org/bmaplib.heatmap/-/bmaplib.heatmap-1.0.4.tgz", |
| | | "integrity": "sha512-rmhqUARBpUSJ9jXzUI2j7dIOqnc38bqubkx/8a349U2qtw/ulLUwyzRD535OrA8G7w5cz4aPKm6/rNvUAarg/Q==" |
| | | }, |
| | | "bmaplib.lushu": { |
| | | "version": "1.0.7", |
| | | "resolved": "https://registry.npmjs.org/bmaplib.lushu/-/bmaplib.lushu-1.0.7.tgz", |
| | | "integrity": "sha512-LVvgpESPii6xGxyjnQjq8u+ic4NjvhdCPV/RiSS/PGTUdZKeTDS7prSpleJLZH3ES0+oc0gYn8bw0LtPYUSz2w==" |
| | | }, |
| | | "bmaplib.markerclusterer": { |
| | | "version": "1.0.13", |
| | | "resolved": "https://registry.npmjs.org/bmaplib.markerclusterer/-/bmaplib.markerclusterer-1.0.13.tgz", |
| | | "integrity": "sha512-VrLyWSiuDEVNi0yUfwOhFQ6z1oEEHS4w36GNu3iASu6p52QIx9uAXMUkuSCHReNR0bj2Cp9SA1dSx5RpojXajQ==", |
| | | "requires": { |
| | | "bmaplib.texticonoverlay": "^1.0.2" |
| | | } |
| | | }, |
| | | "bmaplib.texticonoverlay": { |
| | | "version": "1.0.2", |
| | | "resolved": "https://registry.npmjs.org/bmaplib.texticonoverlay/-/bmaplib.texticonoverlay-1.0.2.tgz", |
| | | "integrity": "sha512-4ZTWr4ZP3B6qEWput5Tut16CfZgII38YwM3bpyb4gFTQyORlKYryFp9WHWrwZZaHlOyYDAXG9SX0hka43jTADg==" |
| | | }, |
| | | "bn.js": { |
| | | "version": "5.1.3", |
| | | "resolved": "https://registry.npm.taobao.org/bn.js/download/bn.js-5.1.3.tgz", |
| | |
| | | "invert-kv": "^1.0.0" |
| | | } |
| | | }, |
| | | "linkify-it": { |
| | | "version": "2.2.0", |
| | | "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", |
| | | "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", |
| | | "requires": { |
| | | "uc.micro": "^1.0.1" |
| | | } |
| | | }, |
| | | "load-json-file": { |
| | | "version": "2.0.0", |
| | | "resolved": "https://registry.npm.taobao.org/load-json-file/download/load-json-file-2.0.0.tgz", |
| | |
| | | "object-visit": "^1.0.0" |
| | | } |
| | | }, |
| | | "markdown-it": { |
| | | "version": "8.4.2", |
| | | "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz", |
| | | "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==", |
| | | "requires": { |
| | | "argparse": "^1.0.7", |
| | | "entities": "~1.1.1", |
| | | "linkify-it": "^2.0.0", |
| | | "mdurl": "^1.0.1", |
| | | "uc.micro": "^1.0.5" |
| | | }, |
| | | "dependencies": { |
| | | "entities": { |
| | | "version": "1.1.2", |
| | | "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", |
| | | "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" |
| | | } |
| | | } |
| | | }, |
| | | "math-expression-evaluator": { |
| | | "version": "1.2.22", |
| | | "resolved": "https://registry.npm.taobao.org/math-expression-evaluator/download/math-expression-evaluator-1.2.22.tgz", |
| | |
| | | "resolved": "https://registry.npm.taobao.org/mdn-data/download/mdn-data-2.0.4.tgz", |
| | | "integrity": "sha1-aZs8OKxvHXKAkaZGULZdOIUC/Vs=", |
| | | "dev": true |
| | | }, |
| | | "mdurl": { |
| | | "version": "1.0.1", |
| | | "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", |
| | | "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" |
| | | }, |
| | | "media-typer": { |
| | | "version": "0.3.0", |
| | |
| | | "sprintf-js": { |
| | | "version": "1.0.3", |
| | | "resolved": "https://registry.npm.taobao.org/sprintf-js/download/sprintf-js-1.0.3.tgz", |
| | | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", |
| | | "dev": true |
| | | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" |
| | | }, |
| | | "ssri": { |
| | | "version": "5.3.0", |
| | |
| | | "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", |
| | | "dev": true |
| | | }, |
| | | "uc.micro": { |
| | | "version": "1.0.6", |
| | | "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", |
| | | "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" |
| | | }, |
| | | "uglify-js": { |
| | | "version": "3.4.10", |
| | | "resolved": "https://registry.npm.taobao.org/uglify-js/download/uglify-js-3.4.10.tgz?cache=0&sync_timestamp=1601823880483&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fuglify-js%2Fdownload%2Fuglify-js-3.4.10.tgz", |
| | |
| | | "resolved": "https://registry.npm.taobao.org/vue/download/vue-2.6.12.tgz?cache=0&sync_timestamp=1600441238751&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue%2Fdownload%2Fvue-2.6.12.tgz", |
| | | "integrity": "sha1-9evU+mvShpQD4pqJau1JBEVskSM=" |
| | | }, |
| | | "vue-baidu-map": { |
| | | "version": "0.21.22", |
| | | "resolved": "https://registry.npmjs.org/vue-baidu-map/-/vue-baidu-map-0.21.22.tgz", |
| | | "integrity": "sha512-WQMPCih4UTh0AZCKKH/OVOYnyAWjfRNeK6BIeoLmscyY5aF8zzlJhz/NOHLb3mdztIpB0Z6aohn4Jd9mfCSjQw==", |
| | | "requires": { |
| | | "bmaplib.curveline": "^1.0.0", |
| | | "bmaplib.heatmap": "^1.0.4", |
| | | "bmaplib.lushu": "^1.0.7", |
| | | "bmaplib.markerclusterer": "^1.0.13", |
| | | "markdown-it": "^8.4.0" |
| | | } |
| | | }, |
| | | "vue-clipboard2": { |
| | | "version": "0.3.1", |
| | | "resolved": "https://registry.npm.taobao.org/vue-clipboard2/download/vue-clipboard2-0.3.1.tgz", |
| | |
| | | "moment": "^2.29.1", |
| | | "postcss-pxtorem": "^5.1.1", |
| | | "vue": "^2.6.11", |
| | | "vue-baidu-map": "^0.21.22", |
| | | "vue-clipboard2": "^0.3.1", |
| | | "vue-cookies": "^1.7.4", |
| | | "vue-router": "^3.1.6" |
New file |
| | |
| | | /** |
| | | * 经纬度转换 |
| | | */ |
| | | export default { |
| | | PI: 3.1415926535897932384626, |
| | | //PI: 3.14159265358979324, |
| | | x_pi: (3.1415926535897932384626 * 3000.0) / 180.0, |
| | | delta: function (lat, lng) { |
| | | // Krasovsky 1940 |
| | | // |
| | | // a = 6378245.0, 1/f = 298.3 |
| | | // b = a * (1 - f) |
| | | // ee = (a^2 - b^2) / a^2; |
| | | var a = 6378245.0; // a: 卫星椭球坐标投影到平面地图坐标系的投影因子。 |
| | | var ee = 0.00669342162296594323; // ee: 椭球的偏心率。 |
| | | var dLat = this.transformLat(lng - 105.0, lat - 35.0); |
| | | var dLng = this.transformLng(lng - 105.0, lat - 35.0); |
| | | var radLat = (lat / 180.0) * this.PI; |
| | | var magic = Math.sin(radLat); |
| | | magic = 1 - ee * magic * magic; |
| | | var sqrtMagic = Math.sqrt(magic); |
| | | dLat = (dLat * 180.0) / (((a * (1 - ee)) / (magic * sqrtMagic)) * this.PI); |
| | | dLng = (dLng * 180.0) / ((a / sqrtMagic) * Math.cos(radLat) * this.PI); |
| | | return { |
| | | lat: dLat, |
| | | lng: dLng |
| | | }; |
| | | }, |
| | | /** |
| | | * WGS-84 to GCJ-02 GPS坐标转中国坐标 |
| | | * @param {number} wgsLat GPS纬度 |
| | | * @param {number} wgsLng GPS经度 |
| | | * @return {object} 返回中国坐标经纬度对象 |
| | | */ |
| | | GPSToChina: function (wgsLat, wgsLng) { |
| | | if (this.outOfChina(wgsLat, wgsLng)) return { |
| | | lat: wgsLat, |
| | | lng: wgsLng |
| | | }; |
| | | var d = this.delta(wgsLat, wgsLng); |
| | | return { |
| | | lat: Number(wgsLat) + Number(d.lat), |
| | | lng: Number(wgsLng) + Number(d.lng) |
| | | }; |
| | | }, |
| | | /** |
| | | * GCJ-02 to WGS-84 中国标准坐标转GPS坐标 |
| | | * @param {number} gcjLat 中国标准坐标纬度 |
| | | * @param {number} gcjLng 中国标准坐标经度 |
| | | * @return {object} 返回GPS经纬度对象 |
| | | */ |
| | | chinaToGPS: function (gcjLat, gcjLng) { |
| | | if (this.outOfChina(gcjLat, gcjLng)) return { |
| | | lat: gcjLat, |
| | | lng: gcjLng |
| | | }; |
| | | var d = this.delta(gcjLat, gcjLng); |
| | | return { |
| | | lat: Number(gcjLat) - Number(d.lat), |
| | | lng: Number(gcjLng) - Number(d.lng) |
| | | }; |
| | | }, |
| | | /** |
| | | * GCJ-02 to WGS-84 exactly 中国标准坐标转GPS坐标(精确) |
| | | * @param {number} gcjLat 中国标准坐标纬度 |
| | | * @param {number} gcjLng 中国标准坐标经度 |
| | | * @return {object} 返回GPS经纬度对象(精确) |
| | | */ |
| | | chinaToGPSExact: function (gcjLat, gcjLng) { |
| | | var initDelta = 0.01; |
| | | var threshold = 0.000000001; |
| | | var dLat = initDelta, |
| | | dLng = initDelta; |
| | | var mLat = gcjLat - dLat, |
| | | mLng = gcjLng - dLng; |
| | | var pLat = gcjLat + dLat, |
| | | pLng = gcjLng + dLng; |
| | | var wgsLat, |
| | | wgsLng, |
| | | i = 0; |
| | | while (1) { |
| | | wgsLat = (mLat + pLat) / 2; |
| | | wgsLng = (mLng + pLng) / 2; |
| | | var tmp = this.gcj_encrypt(wgsLat, wgsLng); |
| | | dLat = tmp.lat - gcjLat; |
| | | dLng = tmp.lng - gcjLng; |
| | | if (Math.abs(dLat) < threshold && Math.abs(dLng) < threshold) break; |
| | | |
| | | if (dLat > 0) pLat = wgsLat; |
| | | else mLat = wgsLat; |
| | | if (dLng > 0) pLng = wgsLng; |
| | | else mLng = wgsLng; |
| | | |
| | | if (++i > 10000) break; |
| | | } |
| | | //console.log(i); |
| | | return { |
| | | lat: wgsLat, |
| | | lng: wgsLng |
| | | }; |
| | | }, |
| | | /** |
| | | * GCJ-02 to BD-09 中国标准坐标转百度坐标(精确) |
| | | * @param {number} gcjLat 中国标准坐标纬度 |
| | | * @param {number} gcjLng 中国标准坐标经度 |
| | | * @return {object} 返回百度经纬度对象 |
| | | */ |
| | | chinaToBaidu: function (gcjLat, gcjLng) { |
| | | var x = gcjLng, |
| | | y = gcjLat; |
| | | var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * this.x_pi); |
| | | var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * this.x_pi); |
| | | var bdLng = z * Math.cos(theta) + 0.0065; |
| | | var bdLat = z * Math.sin(theta) + 0.006; |
| | | return { |
| | | lat: bdLat, |
| | | lng: bdLng |
| | | }; |
| | | }, |
| | | /** |
| | | * BD-09 to GCJ-02 百度坐标转中国标准坐标 |
| | | * @param {number} bdLat 百度坐标纬度 |
| | | * @param {number} bdLng 百度坐标经度 |
| | | * @return {object} 返回中国标准经纬度对象 |
| | | */ |
| | | baiduToChina: function (bdLat, bdLng) { |
| | | var x = bdLng - 0.0065, |
| | | y = bdLat - 0.006; |
| | | var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * this.x_pi); |
| | | var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * this.x_pi); |
| | | var gcjLng = z * Math.cos(theta); |
| | | var gcjLat = z * Math.sin(theta); |
| | | return { |
| | | lat: gcjLat, |
| | | lng: gcjLng |
| | | }; |
| | | }, |
| | | /** |
| | | * BD-09 to GCJ-02 百度坐标转gps坐标 |
| | | * @param {number} bdLat 百度坐标纬度 |
| | | * @param {number} bdLng 百度坐标经度 |
| | | * @return {object} 返回gps经纬度对象 |
| | | */ |
| | | baiduToGPS: function (bdLat, bdLng) { |
| | | let china = this.baiduToChina(bdLat, bdLng); |
| | | return this.chinaToGPS(china.lat, china.lng); |
| | | }, |
| | | /** |
| | | * WGS-84 to to BD-09 GPS坐标转Baidu坐标 |
| | | * @param {number} gpsLat GPS纬度 |
| | | * @param {number} gpsLng GPS经度 |
| | | * @return {object} 返回百度经纬度对象 |
| | | */ |
| | | GPSToBaidu: function (gpsLat, gpsLng) { |
| | | var china = this.GPSToChina(gpsLat, gpsLng); |
| | | return this.chinaToBaidu(china.lat, china.lng); |
| | | }, |
| | | /** |
| | | * WGS-84 to Web mercator GPS坐标转墨卡托坐标 |
| | | * @param {number} wgsLat GPS纬度 |
| | | * @param {number} wgsLng GPS经度 |
| | | * @return {object} 返回墨卡托经纬度对象 |
| | | */ |
| | | GPSToMercator: function (wgsLat, wgsLng) { |
| | | var x = (wgsLng * 20037508.34) / 180; |
| | | var y = Math.log(Math.tan(((90 + wgsLat) * this.PI) / 360)) / (this.PI / 180); |
| | | y = (y * 20037508.34) / 180; |
| | | return { |
| | | lat: y, |
| | | lng: x |
| | | }; |
| | | /* |
| | | if ((Math.abs(wgsLng) > 180 || Math.abs(wgsLat) > 90)) |
| | | return null; |
| | | var x = 6378137.0 * wgsLng * 0.017453292519943295; |
| | | var a = wgsLat * 0.017453292519943295; |
| | | var y = 3189068.5 * Math.log((1.0 + Math.sin(a)) / (1.0 - Math.sin(a))); |
| | | return {'lat' : y, 'lng' : x}; |
| | | //*/ |
| | | }, |
| | | /** |
| | | * Web mercator to WGS-84 墨卡托坐标转GPS坐标 |
| | | * @param {number} mercatorLat 墨卡托纬度 |
| | | * @param {number} mercatorLng 墨卡托经度 |
| | | * @return {object} 返回GPS经纬度对象 |
| | | */ |
| | | mercatorToGPS: function (mercatorLat, mercatorLng) { |
| | | var x = (mercatorLng / 20037508.34) * 180; |
| | | var y = (mercatorLat / 20037508.34) * 180; |
| | | y = (180 / this.PI) * (2 * Math.atan(Math.exp((y * this.PI) / 180)) - this.PI / 2); |
| | | return { |
| | | lat: y, |
| | | lng: x |
| | | }; |
| | | /* |
| | | if (Math.abs(mercatorLng) < 180 && Math.abs(mercatorLat) < 90) |
| | | return null; |
| | | if ((Math.abs(mercatorLng) > 20037508.3427892) || (Math.abs(mercatorLat) > 20037508.3427892)) |
| | | return null; |
| | | var a = mercatorLng / 6378137.0 * 57.295779513082323; |
| | | var x = a - (Math.floor(((a + 180.0) / 360.0)) * 360.0); |
| | | var y = (1.5707963267948966 - (2.0 * Math.atan(Math.exp((-1.0 * mercatorLat) / 6378137.0)))) * 57.295779513082323; |
| | | return {'lat' : y, 'lng' : x}; |
| | | //*/ |
| | | }, |
| | | /** |
| | | * 两点之间的距离 |
| | | * @param {number} latA 起点纬度 |
| | | * @param {number} lngA 起点经度 |
| | | * @param {number} latB 终点纬度 |
| | | * @param {number} lngB 终点经度 |
| | | * @return {number} 返回距离(米) |
| | | */ |
| | | distance: function (latA, lngA, latB, lngB) { |
| | | var earthR = 6371000; |
| | | var x = Math.cos((latA * this.PI) / 180) * Math.cos((latB * this.PI) / 180) * Math.cos(((lngA - lngB) * this.PI) / 180); |
| | | var y = Math.sin((latA * this.PI) / 180) * Math.sin((latB * this.PI) / 180); |
| | | var s = x + y; |
| | | if (s > 1) s = 1; |
| | | if (s < -1) s = -1; |
| | | var alpha = Math.acos(s); |
| | | var distance = alpha * earthR; |
| | | return distance; |
| | | }, |
| | | /** |
| | | * 是否在中国之外 |
| | | * @param {number} lat 纬度 |
| | | * @param {number} lng 经度 |
| | | * @return {boolean]} 返回结果真或假 |
| | | */ |
| | | outOfChina: function (lat, lng) { |
| | | if (lat < 72.004 || lat > 137.8347) return true; |
| | | if (lng < 0.8293 || lng > 55.8271) return true; |
| | | return false; |
| | | }, |
| | | transformLat: function (x, y) { |
| | | var ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x)); |
| | | ret += ((20.0 * Math.sin(6.0 * x * this.PI) + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0) / 3.0; |
| | | ret += ((20.0 * Math.sin(y * this.PI) + 40.0 * Math.sin((y / 3.0) * this.PI)) * 2.0) / 3.0; |
| | | ret += ((160.0 * Math.sin((y / 12.0) * this.PI) + 320 * Math.sin((y * this.PI) / 30.0)) * 2.0) / 3.0; |
| | | return ret; |
| | | }, |
| | | transformLng: function (x, y) { |
| | | var ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x)); |
| | | ret += ((20.0 * Math.sin(6.0 * x * this.PI) + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0) / 3.0; |
| | | ret += ((20.0 * Math.sin(x * this.PI) + 40.0 * Math.sin((x / 3.0) * this.PI)) * 2.0) / 3.0; |
| | | ret += ((150.0 * Math.sin((x / 12.0) * this.PI) + 300.0 * Math.sin((x / 30.0) * this.PI)) * 2.0) / 3.0; |
| | | return ret; |
| | | } |
| | | }; |
| | |
| | | } |
| | | }, |
| | | created(){ |
| | | var that = this; |
| | | document.onkeydown = function(e) { |
| | | var key = window.event.keyCode; |
| | | if (key == 13) { |
| | | that.login(); |
| | | var that = this; |
| | | document.onkeydown = function(e) { |
| | | var key = window.event.keyCode; |
| | | if (key == 13) { |
| | | that.login(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | }, |
| | | methods:{ |
| | | |
| | |
| | | if (res.data == "success") { |
| | | that.$cookies.set("session", {"username": that.username}) ; |
| | | //登录成功后 |
| | | that.cancelEnterkeyDefaultAction(); |
| | | that.$router.push('/'); |
| | | }else{ |
| | | that.isLoging = false; |
| | |
| | | that.$message.error(error.response.statusText); |
| | | that.isLoging = false; |
| | | }); |
| | | |
| | | |
| | | |
| | | }, |
| | | setCookie: function (cname, cvalue, exdays) { |
| | | var d = new Date(); |
| | | d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000)); |
| | | var expires = "expires=" + d.toUTCString(); |
| | | console.info(cname + "=" + cvalue + "; " + expires); |
| | | document.cookie = cname + "=" + cvalue + "; " + expires; |
| | | console.info(document.cookie); |
| | | }, |
| | | setCookie: function (cname, cvalue, exdays) { |
| | | var d = new Date(); |
| | | d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000)); |
| | | var expires = "expires=" + d.toUTCString(); |
| | | console.info(cname + "=" + cvalue + "; " + expires); |
| | | document.cookie = cname + "=" + cvalue + "; " + expires; |
| | | console.info(document.cookie); |
| | | }, |
| | | cancelEnterkeyDefaultAction: function() { |
| | | document.onkeydown = function(e) { |
| | | var key = window.event.keyCode; |
| | | if (key == 13) { |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | |
| | | let that = this; |
| | | if (this.alarmNotify) { |
| | | console.log("申请SSE推送API调用,浏览器ID: " + this.$browserId); |
| | | this.sseSource = new EventSource('/api/emit?browserId=' + this.$browserId); |
| | | this.sseSource = new EventSource('/api/emit?browserId=' + this.$browserId); |
| | | this.sseSource.addEventListener('message', function(evt) { |
| | | that.$notify({ |
| | | title: '收到报警信息', |
| | |
| | | this.sseSource.removeEventListener('message', null); |
| | | this.sseSource.removeEventListener('error', null); |
| | | this.sseSource.close(); |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | mounted() { |
New file |
| | |
| | | <template> |
| | | <div id="devicePosition" style="height: 100%"> |
| | | <el-container style="height: 100%"> |
| | | <el-header> |
| | | <uiHeader></uiHeader> |
| | | </el-header> |
| | | <el-main> |
| | | <div style="background-color: #ffffff; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center;"> |
| | | <span style="font-size: 1rem; font-weight: 500">设备定位 ({{ parentChannelId == 0 ? deviceId : parentChannelId }})</span> |
| | | </div> |
| | | <div style="background-color: #ffffff; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left; font-size: 14px;"> |
| | | <el-button icon="el-icon-arrow-left" size="mini" style="margin-right: 1rem" type="primary" @click="showDevice">返回</el-button> |
| | | <!-- <span class="demonstration">从</span> --> |
| | | <el-date-picker v-model="searchFrom" type="datetime" placeholder="选择开始日期时间" default-time="00:00:00" size="mini" style="width: 11rem;" align="right" :picker-options="pickerOptions"></el-date-picker> |
| | | <el-date-picker v-model="searchTo" type="datetime" placeholder="选择结束日期时间" default-time="00:00:00" size="mini" style="width: 11rem;" align="right" :picker-options="pickerOptions"></el-date-picker> |
| | | <el-button-group> |
| | | <el-button icon="el-icon-search" size="mini" type="primary" @click="showHistoryPath">历史轨迹</el-button> |
| | | <el-button icon="el-icon-search" size="mini" style="margin-right: 1rem" type="primary" @click="showLatestPosition">最新位置</el-button> |
| | | </el-button-group> |
| | | <el-tag style="width: 5rem; text-align: center" size="medium">过期时间</el-tag> |
| | | <el-input-number size="mini" v-model="expired" :min="300" :controls="false" style="width: 4rem;"></el-input-number> |
| | | <el-tag style="width: 5rem; text-align: center" size="medium">上报周期</el-tag> |
| | | <el-input-number size="mini" v-model="interval" :min="1" :controls="false" style="width: 4rem;"></el-input-number> |
| | | <el-button-group> |
| | | <el-button icon="el-icon-search" size="mini" type="primary" @click="subscribeMobilePosition">位置订阅</el-button> |
| | | <el-button icon="el-icon-search" size="mini" type="primary" @click="unSubscribeMobilePosition">取消订阅</el-button> |
| | | </el-button-group> |
| | | <el-checkbox size="mini" style="margin-right: 1rem; float: right" v-model="autoList" @change="autoListChange" >自动刷新</el-checkbox> |
| | | </div> |
| | | <div class="mapContainer" style="background-color: #ffffff; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center; height: calc(100% - 10rem);"> |
| | | <div class="baidumap" id="allmap"></div> |
| | | </div> |
| | | </el-main> |
| | | </el-container> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import uiHeader from "./UiHeader.vue"; |
| | | import moment from "moment"; |
| | | import geoTools from "./GeoConvertTools.js"; |
| | | export default { |
| | | name: "devicePosition", |
| | | components: { |
| | | uiHeader, |
| | | }, |
| | | data() { |
| | | return { |
| | | pickerOptions: { |
| | | shortcuts: [{ |
| | | text: '今天', |
| | | onClick(picker) { |
| | | picker.$emit('pick', new Date()); |
| | | } |
| | | }, { |
| | | text: '昨天', |
| | | onClick(picker) { |
| | | const date = new Date(); |
| | | date.setTime(date.getTime() - 3600 * 1000 * 24); |
| | | picker.$emit('pick', date); |
| | | } |
| | | }, { |
| | | text: '一周前', |
| | | onClick(picker) { |
| | | const date = new Date(); |
| | | date.setTime(date.getTime() - 3600 * 1000 * 24 * 7); |
| | | picker.$emit('pick', date); |
| | | } |
| | | }] |
| | | }, |
| | | deviceId: this.$route.params.deviceId, |
| | | showHistoryPosition: false, //显示历史轨迹 |
| | | startTime: null, |
| | | endTime: null, |
| | | searchFrom: null, |
| | | searchTo: null, |
| | | expired: 600, |
| | | interval: 5, |
| | | mobilePositionList: [], |
| | | mapPointList: [], |
| | | parentChannelId: this.$route.params.parentChannelId, |
| | | updateLooper: 0, //数据刷新轮训标志 |
| | | total: 0, |
| | | beforeUrl: "/videoList", |
| | | isLoging: false, |
| | | autoList: false, |
| | | }; |
| | | }, |
| | | mounted() { |
| | | this.initData(); |
| | | this.initBaiduMap(); |
| | | if (this.autoList) { |
| | | this.updateLooper = setInterval(this.initData, 5000); |
| | | } |
| | | }, |
| | | destroyed() { |
| | | // this.$destroy("videojs"); |
| | | clearTimeout(this.updateLooper); |
| | | }, |
| | | methods: { |
| | | initData: function () { |
| | | // if (this.parentChannelId == "" || this.parentChannelId == 0) { |
| | | // this.getDeviceChannelList(); |
| | | // } else { |
| | | // this.showSubchannels(); |
| | | // } |
| | | }, |
| | | initParam: function () { |
| | | // this.deviceId = this.$route.params.deviceId; |
| | | // this.parentChannelId = this.$route.params.parentChannelId; |
| | | // this.currentPage = parseInt(this.$route.params.page); |
| | | // this.count = parseInt(this.$route.params.count); |
| | | // if (this.parentChannelId == "" || this.parentChannelId == 0) { |
| | | // this.beforeUrl = "/videoList"; |
| | | // } |
| | | }, |
| | | initBaiduMap() { |
| | | this.map = new BMap.Map("allmap"); // 创建地图实例 |
| | | let points = []; |
| | | let point = new BMap.Point(116.231398, 39.567445); // 创建点坐标 |
| | | this.map.centerAndZoom(point, 5); // 初始化地图,设置中心点坐标和地图级别 |
| | | this.map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放 |
| | | this.map.addControl(new BMap.NavigationControl()); |
| | | this.map.addControl(new BMap.ScaleControl()); |
| | | this.map.addControl(new BMap.OverviewMapControl()); |
| | | this.map.addControl(new BMap.MapTypeControl()); |
| | | //map.setMapStyle({ style: 'midnight' }) //地图风格 |
| | | }, |
| | | currentChange: function (val) { |
| | | // var url = `/${this.$router.currentRoute.name}/${this.deviceId}/${this.parentChannelId}/${this.count}/${val}`; |
| | | // console.log(url); |
| | | // this.$router.push(url).then(() => { |
| | | // this.initParam(); |
| | | // this.initData(); |
| | | // }); |
| | | }, |
| | | handleSizeChange: function (val) { |
| | | // var url = `/${this.$router.currentRoute.name}/${this.$router.params.deviceId}/${this.$router.params.parentChannelId}/${val}/1`; |
| | | // this.$router.push(url).then(() => { |
| | | // this.initParam(); |
| | | // this.initData(); |
| | | // }); |
| | | }, |
| | | showDevice: function () { |
| | | this.$router.push(this.beforeUrl).then(() => { |
| | | this.initParam(); |
| | | this.initData(); |
| | | }); |
| | | }, |
| | | autoListChange: function () { |
| | | if (this.autoList) { |
| | | this.updateLooper = setInterval(this.initData, 1500); |
| | | } else { |
| | | window.clearInterval(this.updateLooper); |
| | | } |
| | | }, |
| | | showHistoryPath: function () { |
| | | this.map.clearOverlays(); |
| | | this.mapPointList = []; |
| | | this.mobilePositionList = []; |
| | | if (!!this.searchFrom) { |
| | | this.startTime = this.toGBString(this.searchFrom); |
| | | console.log(this.startTime); |
| | | } else{ |
| | | this.startTime = null; |
| | | } |
| | | if (!!this.searchTo) { |
| | | this.endTime = this.toGBString(this.searchTo); |
| | | console.log(this.endTime); |
| | | } else { |
| | | this.endTime = null; |
| | | } |
| | | let self = this; |
| | | this.$axios.get(`/api/positions/${this.deviceId}/history`, { |
| | | params: { |
| | | start: self.startTime, |
| | | end: self.endTime, |
| | | }, |
| | | }) |
| | | .then(function (res) { |
| | | self.total = res.data.length; |
| | | self.mobilePositionList = res.data; |
| | | console.log(self.mobilePositionList); |
| | | if (self.total == 0) { |
| | | self.$message({ |
| | | showClose: true, |
| | | message: '未找到符合条件的移动位置信息', |
| | | type: 'error' |
| | | }); |
| | | } else { |
| | | self.$nextTick(() => { |
| | | self.showMarkPoints(self); |
| | | }); |
| | | } |
| | | }) |
| | | .catch(function (error) { |
| | | console.log(error); |
| | | }); |
| | | }, |
| | | showLatestPosition: function() { |
| | | this.map.clearOverlays(); |
| | | this.mapPointList = []; |
| | | this.mobilePositionList = []; |
| | | let self = this; |
| | | this.$axios.get(`/api/positions/${this.deviceId}/latest`) |
| | | .then(function (res) { |
| | | console.log(res.data); |
| | | self.total = res.data.length; |
| | | self.mobilePositionList.push(res.data); |
| | | console.log(self.mobilePositionList); |
| | | if (self.total == 0) { |
| | | self.$message({ |
| | | showClose: true, |
| | | message: '未找到符合条件的移动位置信息', |
| | | type: 'error' |
| | | }); |
| | | } else { |
| | | self.$nextTick(() => { |
| | | self.showMarkPoints(self); |
| | | }); |
| | | } |
| | | }) |
| | | .catch(function (error) { |
| | | console.log(error); |
| | | }); |
| | | }, |
| | | subscribeMobilePosition: function() { |
| | | let self = this; |
| | | this.$axios.get(`/api/positions/${this.deviceId}/subscribe`, { |
| | | params: { |
| | | expires: self.expired, |
| | | interval: self.interval, |
| | | }, |
| | | }) |
| | | .then(function (res) { |
| | | console.log(res.data); |
| | | }) |
| | | .catch(function (error) { |
| | | console.log(error); |
| | | }); |
| | | }, |
| | | unSubscribeMobilePosition: function() { |
| | | let self = this; |
| | | this.$axios.get(`/api/positions/${this.deviceId}/subscribe`, { |
| | | params: { |
| | | expires: 0, |
| | | interval: self.interval, |
| | | }, |
| | | }) |
| | | .then(function (res) { |
| | | console.log(res.data); |
| | | }) |
| | | .catch(function (error) { |
| | | console.log(error); |
| | | }); |
| | | }, |
| | | toGBString: function (dateTime) { |
| | | return ( |
| | | dateTime.getFullYear() + |
| | | "-" + this.twoDigits(dateTime.getMonth() + 1) + |
| | | "-" + this.twoDigits(dateTime.getDate()) + |
| | | "T" + this.twoDigits(dateTime.getHours()) + |
| | | ":" + this.twoDigits(dateTime.getMinutes()) + |
| | | ":" + this.twoDigits(dateTime.getSeconds()) |
| | | ); |
| | | }, |
| | | twoDigits: function (num) { |
| | | if (num < 10) { |
| | | return "0" + num; |
| | | } else { |
| | | return "" + num; |
| | | } |
| | | }, |
| | | showMarkPoints: function(self) { |
| | | let that = self; |
| | | let npointJ = null; |
| | | let npointW = null; |
| | | let point = null; |
| | | for (let i = 0; i < self.mobilePositionList.length; i++) { |
| | | if (self.mobilePositionList[i].geodeticSystem == "BD-09") { |
| | | npointJ = self.mobilePositionList[i].cnLng; |
| | | npointW = self.mobilePositionList[i].cnLat; |
| | | point = new BMap.Point(npointJ, npointW); |
| | | } else { |
| | | npointJ = self.mobilePositionList[i].longitude; |
| | | npointW = self.mobilePositionList[i].latitude; |
| | | let bd2 = geoTools.GPSToBaidu(npointJ, npointW); |
| | | point = new BMap.Point(bd2.lat, bd2.lng); |
| | | } |
| | | self.mapPointList.push(point); |
| | | let marker = new BMap.Marker(point); // 创建标注 |
| | | self.map.addOverlay(marker); // 将标注添加到地图中 |
| | | //提示信息 可以解析 HTML标签以及CSS |
| | | let infoWindow = new BMap.InfoWindow(`<p style='text-align:left;font-weight:800'>设备: ${self.mobilePositionList[i].deviceId}</p> |
| | | <p style='text-align:left;font-weight:0'>时间: ${self.mobilePositionList[i].time}</p>`); |
| | | // 鼠标移上标注点要发生的事 |
| | | marker.addEventListener("mouseover", function () { |
| | | this.openInfoWindow(infoWindow); |
| | | }); |
| | | // 鼠标移开标注点要发生的事 |
| | | marker.addEventListener("mouseout", function () { |
| | | this.closeInfoWindow(infoWindow); |
| | | }); |
| | | // 鼠标点击标注点要发生的事情 |
| | | marker.addEventListener("click", function () { |
| | | alert("点击"); |
| | | }); |
| | | } |
| | | let view = that.map.getViewport(eval(self.mapPointList)); |
| | | that.map.centerAndZoom(view.center, view.zoom); |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style> |
| | | .videoList { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | align-content: flex-start; |
| | | } |
| | | |
| | | .video-item { |
| | | position: relative; |
| | | width: 15rem; |
| | | height: 10rem; |
| | | margin-right: 1rem; |
| | | background-color: #000000; |
| | | } |
| | | |
| | | .video-item-img { |
| | | position: absolute; |
| | | top: 0; |
| | | bottom: 0; |
| | | left: 0; |
| | | right: 0; |
| | | margin: auto; |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | |
| | | .video-item-img:after { |
| | | content: ""; |
| | | display: inline-block; |
| | | position: absolute; |
| | | z-index: 2; |
| | | top: 0; |
| | | bottom: 0; |
| | | left: 0; |
| | | right: 0; |
| | | margin: auto; |
| | | width: 3rem; |
| | | height: 3rem; |
| | | background-image: url("../assets/loading.png"); |
| | | background-size: cover; |
| | | background-color: #000000; |
| | | } |
| | | |
| | | .video-item-title { |
| | | position: absolute; |
| | | bottom: 0; |
| | | color: #000000; |
| | | background-color: #ffffff; |
| | | line-height: 1.5rem; |
| | | padding: 0.3rem; |
| | | width: 14.4rem; |
| | | } |
| | | |
| | | .baidumap { |
| | | width: 100%; |
| | | height: 100%; |
| | | border: none; |
| | | position: absolute; |
| | | left: 0; |
| | | top: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | margin: auto; |
| | | } |
| | | |
| | | /* 去除百度地图版权那行字 和 百度logo */ |
| | | .baidumap > .BMap_cpyCtrl { |
| | | display: none !important; |
| | | } |
| | | .baidumap > .anchorBL { |
| | | display: none !important; |
| | | } |
| | | </style> |
| | |
| | | <el-button icon="el-icon-refresh-right" circle size="mini" :loading="getDeviceListLoading" @click="getDeviceList()"></el-button> |
| | | </div> |
| | | </div> |
| | | <devicePlayer ref="devicePlayer"></devicePlayer> |
| | | <!-- <devicePlayer ref="devicePlayer"></devicePlayer> --> |
| | | <!--设备列表--> |
| | | <el-table :data="deviceList" border style="width: 100%" :height="winHeight"> |
| | | <el-table-column prop="name" label="名称" width="180" align="center"> |
| | |
| | | </el-table-column> |
| | | <el-table-column prop="channelCount" label="通道数" align="center"> |
| | | </el-table-column> |
| | | <el-table-column label="状态" width="180" align="center"> |
| | | <el-table-column label="状态" width="80" align="center"> |
| | | <template slot-scope="scope"> |
| | | <div slot="reference" class="name-wrapper"> |
| | | <el-tag size="medium" v-if="scope.row.online == 1">在线</el-tag> |
| | |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column label="操作" width="240" align="center" fixed="right"> |
| | | <el-table-column label="操作" width="360" align="center" fixed="right"> |
| | | <template slot-scope="scope"> |
| | | <el-button size="mini" :ref="scope.row.deviceId + 'refbtn' " icon="el-icon-refresh" @click="refDevice(scope.row)">刷新通道</el-button> |
| | | <el-button size="mini" icon="el-icon-s-open" v-bind:disabled="scope.row.online==0" type="primary" @click="showChannelList(scope.row)">查看通道</el-button> |
| | | </template> |
| | | <el-button size="mini" :ref="scope.row.deviceId + 'refbtn' " icon="el-icon-refresh" @click="refDevice(scope.row)">刷新</el-button> |
| | | <el-button-group> |
| | | <el-button size="mini" icon="el-icon-video-camera-solid" v-bind:disabled="scope.row.online==0" type="primary" @click="showChannelList(scope.row)">通道</el-button> |
| | | <el-button size="mini" icon="el-icon-location" v-bind:disabled="scope.row.online==0" type="primary" @click="showDevicePosition(scope.row)">定位</el-button> |
| | | <el-button size="mini" icon="el-icon-s-tools" v-bind:disabled="scope.row.online==0" type="primary">控制</el-button> |
| | | </el-button-group> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <el-pagination |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import uiHeader from './UiHeader.vue' |
| | | import uiHeader from './UiHeader.vue' |
| | | export default { |
| | | name: 'app', |
| | | components: { |
| | |
| | | console.log(JSON.stringify(row)) |
| | | this.$router.push(`/channelList/${row.deviceId}/0/15/1`); |
| | | }, |
| | | |
| | | showDevicePosition: function(row) { |
| | | console.log(JSON.stringify(row)) |
| | | this.$router.push(`/devicePosition/${row.deviceId}/0/15/1`); |
| | | }, |
| | | |
| | | //gb28181平台对接 |
| | | //刷新设备信息 |
| | |
| | | }, |
| | | //通知设备上传媒体流 |
| | | sendDevicePush: function(itemData) { |
| | | let deviceId = this.currentDevice.deviceId; |
| | | let channelId = itemData.channelId; |
| | | console.log("通知设备推流1:" + deviceId + " : " + channelId); |
| | | let that = this; |
| | | this.$axios({ |
| | | method: 'get', |
| | | url: '/api/play/' + deviceId + '/' + channelId |
| | | }).then(function(res) { |
| | | let ssrc = res.data.ssrc; |
| | | that.$refs.devicePlayer.play(ssrc,deviceId,channelId); |
| | | }).catch(function(e) { |
| | | }); |
| | | // let deviceId = this.currentDevice.deviceId; |
| | | // let channelId = itemData.channelId; |
| | | // console.log("通知设备推流1:" + deviceId + " : " + channelId); |
| | | // let that = this; |
| | | // this.$axios({ |
| | | // method: 'get', |
| | | // url: '/api/play/' + deviceId + '/' + channelId |
| | | // }).then(function(res) { |
| | | // let ssrc = res.data.ssrc; |
| | | // that.$refs.devicePlayer.play(ssrc,deviceId,channelId); |
| | | // }).catch(function(e) { |
| | | // }); |
| | | }, |
| | | transportChange: function (row) { |
| | | console.log(row); |
| | |
| | | import { Notification } from 'element-ui'; |
| | | import Fingerprint2 from 'fingerprintjs2'; |
| | | |
| | | // 生成唯一ID |
| | | // 生成唯一ID |
| | | Fingerprint2.get(function(components) { |
| | | const values = components.map(function(component,index) { |
| | | if (index === 0) { //把微信浏览器里UA的wifi或4G等网络替换成空,不然切换网络会ID不一样 |
| | | if (index === 0) { //把微信浏览器里UA的wifi或4G等网络替换成空,不然切换网络会ID不一样 |
| | | return component.value.replace(/\bNetType\/\w+\b/, ''); |
| | | } |
| | | return component.value; |
| | | }) |
| | | //console.log(values) //使用的浏览器信息npm |
| | | // 生成最终id |
| | | //console.log(values) //使用的浏览器信息npm |
| | | // 生成最终id |
| | | let port = window.location.port; |
| | | console.log(port); |
| | | const fingerPrint = Fingerprint2.x64hash128(values.join(port), 31) |
| | | Vue.prototype.$browserId = fingerPrint; |
| | | console.log("唯一标识码:" + fingerPrint); |
| | | console.log("唯一标识码:" + fingerPrint); |
| | | }); |
| | | |
| | | Vue.use(VueClipboard); |
| | |
| | | import control from '../components/control.vue' |
| | | import videoList from '../components/videoList.vue' |
| | | import channelList from '../components/channelList.vue' |
| | | import devicePosition from '../components/devicePosition.vue' |
| | | import login from '../components/Login.vue' |
| | | import parentPlatformList from '../components/ParentPlatformList.vue' |
| | | |
| | |
| | | name: 'parentPlatformList', |
| | | component: parentPlatformList, |
| | | }, |
| | | { |
| | | path: '/devicePosition/:deviceId/:parentChannelId/:count/:page', |
| | | name: 'devicePosition', |
| | | component: devicePosition, |
| | | }, |
| | | ] |
| | | }) |