From 3d83775468dc9dd69a52332ba566f7e07e931325 Mon Sep 17 00:00:00 2001
From: panlinlin <648540858@qq.com>
Date: 星期四, 31 十二月 2020 13:15:50 +0800
Subject: [PATCH] 存储部分使用sqlite代替redis

---
 src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java                                    |   34 
 src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java                           |   70 +
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java                 |   68 ++
 pom.xml                                                                                         |    7 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java                     |    3 
 src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java                              |   24 
 src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java                             |   27 
 src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java                    |  172 ++++++
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java |    8 
 src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java                  |   10 
 src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java                            |   58 ++
 src/main/java/com/genersoft/iot/vmp/web/ApiDeviceController.java                                |    2 
 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java                                    |    6 
 src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java                             |   27 
 src/main/java/com/genersoft/iot/vmp/storager/VodeoMannagerTask.java                             |    4 
 src/main/resources/wvp.sqlite                                                                   |    0 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java         |    2 
 src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java                 |  401 ++++++++++++++
 src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java                         |   54 -
 src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java                                |    8 
 /dev/null                                                                                       |  561 --------------------
 src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java                                       |   13 
 web_src/src/components/channelList.vue                                                          |    2 
 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java                          |   24 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java                   |    9 
 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHTTPProxyController.java                       |    8 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java  |   14 
 src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java                       |   20 
 28 files changed, 933 insertions(+), 703 deletions(-)

diff --git a/pom.xml b/pom.xml
index 2ac45ec..ae4d666 100644
--- a/pom.xml
+++ b/pom.xml
@@ -99,6 +99,13 @@
 			<version>8.0.22</version>
 		</dependency>
 
+		<!-- 娣诲姞sqlite-jdbc鏁版嵁搴撻┍鍔� -->
+		<dependency>
+			<groupId>org.xerial</groupId>
+			<artifactId>sqlite-jdbc</artifactId>
+			<version>3.32.3.2</version>
+		</dependency>
+
 		<!--Mybatis -->
 		<dependency>
 			<groupId>org.mybatis</groupId>
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
index 92ba204..e171297 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
@@ -138,16 +138,25 @@
 				// TODO Auto-generated catch block
 				e.printStackTrace();
 			}
+			if (evt.getResponse() != null && sipSubscribe.getOkSubscribesSize() > 0 ) {
+				CallIdHeader callIdHeader = (CallIdHeader)evt.getResponse().getHeader(CallIdHeader.NAME);
+				if (callIdHeader != null) {
+					SipSubscribe.Event subscribe = sipSubscribe.getOkSubscribe(callIdHeader.getCallId());
+					if (subscribe != null) {
+						subscribe.response(evt);
+					}
+				}
+			}
 		// } else if (status == Response.TRYING) {
 			// trying涓嶄細鍥炲
 		} else if ((status >= 100) && (status < 200)) {
 			// 澧炲姞鍏跺畠鏃犻渶鍥炲鐨勫搷搴旓紝濡�101銆�180绛�
 		} else {
 			logger.warn("鎺ユ敹鍒板け璐ョ殑response鍝嶅簲锛乻tatus锛�" + status + ",message:" + response.getReasonPhrase()/* .getContent().toString()*/);
-			if (evt.getResponse() != null && sipSubscribe.getSize() > 0 ) {
+			if (evt.getResponse() != null && sipSubscribe.getErrorSubscribesSize() > 0 ) {
 				CallIdHeader callIdHeader = (CallIdHeader)evt.getResponse().getHeader(CallIdHeader.NAME);
 				if (callIdHeader != null) {
-					SipSubscribe.Event subscribe = sipSubscribe.getSubscribe(callIdHeader.getCallId());
+					SipSubscribe.Event subscribe = sipSubscribe.getErrorSubscribe(callIdHeader.getCallId());
 					if (subscribe != null) {
 						subscribe.response(evt);
 					}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
index de52ac6..12b8a00 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
@@ -1,10 +1,16 @@
 package com.genersoft.iot.vmp.gb28181.bean;
 
 
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
 public class Device {
+
+	/**
+	 * 鏁版嵁搴撳瓨鍌↖D
+	 */
+	private int id;
 
 	/**
 	 * 璁惧Id
@@ -55,14 +61,24 @@
 	 */
 	private int online;
 
-	/**
-	 * 閫氶亾鍒楄〃
-	 */
-//	private Map<String,DeviceChannel> channelMap;
 
+	/**
+	 * 娉ㄥ唽鏃堕棿
+	 */
+	private Long registerTimeMillis;
+
+	/**
+	 * 閫氶亾涓暟
+	 */
 	private int channelCount;
 
-	private List<String> channelList;
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
 
 	public String getDeviceId() {
 		return deviceId;
@@ -144,11 +160,11 @@
 		this.channelCount = channelCount;
 	}
 
-	public List<String> getChannelList() {
-		return channelList;
+	public Long getRegisterTimeMillis() {
+		return registerTimeMillis;
 	}
 
-	public void setChannelList(List<String> channelList) {
-		this.channelList = channelList;
+	public void setRegisterTimeMillis(Long registerTimeMillis) {
+		this.registerTimeMillis = registerTimeMillis;
 	}
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java
index 19e9eda..ca6ef60 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java
@@ -2,10 +2,17 @@
 
 public class DeviceChannel {
 
+
+
 	/**
 	 * 閫氶亾id
 	 */
 	private String channelId;
+
+	/**
+	 * 璁惧id
+	 */
+	private String deviceId;
 	
 	/**
 	 * 閫氶亾鍚�
@@ -146,13 +153,15 @@
 	/**
 	 *  鏄惁鍚湁闊抽
 	 */
-	private  boolean hasAudio;
+	private boolean hasAudio;
 
-	/**
-	 *  鏄惁姝e湪鎾斁
-	 */
-	private  boolean play;
+	public String getDeviceId() {
+		return deviceId;
+	}
 
+	public void setDeviceId(String deviceId) {
+		this.deviceId = deviceId;
+	}
 
 	public void setPTZType(int PTZType) {
 		this.PTZType = PTZType;
@@ -385,14 +394,6 @@
 
 	public void setHasAudio(boolean hasAudio) {
 		this.hasAudio = hasAudio;
-	}
-
-	public boolean isPlay() {
-		return play;
-	}
-
-	public void setPlay(boolean play) {
-		this.play = play;
 	}
 
 	public String getStreamId() {
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java
index 1f78df4..176a435 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java
@@ -17,21 +17,34 @@
 
     private final static Logger logger = LoggerFactory.getLogger(SipSubscribe.class);
 
-    private Map<String, SipSubscribe.Event> allSubscribes = new ConcurrentHashMap<>();
+    private Map<String, SipSubscribe.Event> errorSubscribes = new ConcurrentHashMap<>();
+
+    private Map<String, SipSubscribe.Event> okSubscribes = new ConcurrentHashMap<>();
 
     public interface Event {
         void response(ResponseEvent event);
     }
 
-    public void addSubscribe(String key, SipSubscribe.Event event) {
-        allSubscribes.put(key, event);
+    public void addErrorSubscribe(String key, SipSubscribe.Event event) {
+        errorSubscribes.put(key, event);
     }
 
-    public SipSubscribe.Event getSubscribe(String key) {
-        return allSubscribes.get(key);
+    public void addOkSubscribe(String key, SipSubscribe.Event event) {
+        okSubscribes.put(key, event);
     }
 
-    public int getSize(){
-        return allSubscribes.size();
+    public SipSubscribe.Event getErrorSubscribe(String key) {
+        return errorSubscribes.get(key);
+    }
+
+    public SipSubscribe.Event getOkSubscribe(String key) {
+        return okSubscribes.get(key);
+    }
+
+    public int getErrorSubscribesSize(){
+        return errorSubscribes.size();
+    }
+    public int getOkSubscribesSize(){
+        return okSubscribes.size();
     }
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
index d37259a..b50cc95 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
@@ -4,13 +4,10 @@
 import javax.sip.ResponseEvent;
 import javax.sip.SipProvider;
 import javax.sip.header.CSeqHeader;
-import javax.sip.header.CallIdHeader;
-import javax.sip.header.Header;
 import javax.sip.message.Request;
 import javax.sip.message.Response;
 
-import com.alibaba.fastjson.JSON;
-import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
+import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -59,6 +56,9 @@
 	
 	@Autowired
 	private IVideoManagerStorager storager;
+
+	@Autowired
+	private IRedisCatchStorage redisCatchStorage;
 	
 	@Autowired
 	private EventPublisher publisher;
@@ -143,6 +143,7 @@
 			processor.setOffLineDetector(offLineDetector);
 			processor.setCmder(cmder);
 			processor.setStorager(storager);
+			processor.setRedisCatchStorage(redisCatchStorage);
 			return processor;
 		} else {
 			return new OtherRequestProcessor();
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
index 692e31e..5fd8cbc 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
@@ -25,6 +25,8 @@
 
 	public static final String CALLBACK_CMD_PlAY = "CALLBACK_PLAY";
 
+	public static final String CALLBACK_CMD_STOP = "CALLBACK_STOP";
+
 	private Map<String, DeferredResult> map = new ConcurrentHashMap<String, DeferredResult>();
 	
 	public void put(String key, DeferredResult result) {
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
index 732b2cd..67fd996 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
@@ -101,8 +101,9 @@
 	 * 
 	 * @param ssrc  ssrc
 	 */
+	void streamByeCmd(String ssrc, SipSubscribe.Event okEvent);
 	void streamByeCmd(String ssrc);
-	
+
 	/**
 	 * 璇煶骞挎挱
 	 * 
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
index 3f0adfd..af9030b 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
@@ -1,6 +1,7 @@
 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;
 
@@ -12,11 +13,13 @@
 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.storager.IRedisCatchStorage;
 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -53,6 +56,9 @@
 
 	@Autowired
 	private IVideoManagerStorager storager;
+
+	@Autowired
+	private IRedisCatchStorage redisCatchStorage;
 	
 	@Autowired
 	@Qualifier(value="tcpSipProvider")
@@ -229,7 +235,7 @@
 			
 			Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "ViaPtzBranch", "FromPtzTag", "ToPtzTag");
 			
-			transmitRequest(device, request, null);
+			transmitRequest(device, request);
 			return true;
 		} catch (SipException | ParseException | InvalidArgumentException e) {
 			e.printStackTrace();
@@ -264,7 +270,7 @@
 			ptzXml.append("</Control>\r\n");
 			
 			Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "ViaPtzBranch", "FromPtzTag", "ToPtzTag");
-			transmitRequest(device, request, null);
+			transmitRequest(device, request);
 			return true;
 		} catch (SipException | ParseException | InvalidArgumentException e) {
 			e.printStackTrace();
@@ -291,7 +297,7 @@
 				streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase();
 			}
 			String streamMode = device.getStreamMode().toUpperCase();
-			MediaServerConfig mediaInfo = storager.getMediaInfo();
+			MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
 			if (mediaInfo == null) {
 				logger.warn("鐐规挱鏃跺彂鐜癦LM灏氭湭杩炴帴...");
 				return;
@@ -344,6 +350,9 @@
 			}
 			content.append("y="+ssrc+"\r\n");//ssrc
 
+//			String fromTag = UUID.randomUUID().toString();
+//			Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, fromTag, null, ssrc);
+
 			Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, "live", null, ssrc);
 
 			ClientTransaction transaction = transmitRequest(device, request, errorEvent);
@@ -372,7 +381,7 @@
 	public void playbackStreamCmd(Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event
 			, SipSubscribe.Event errorEvent) {
 		try {
-			MediaServerConfig mediaInfo = storager.getMediaInfo();
+			MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
 			String ssrc = streamSession.createPlayBackSsrc();
 			String streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase();
 			// 娣诲姞璁㈤槄
@@ -457,17 +466,28 @@
 			e.printStackTrace();
 		}
 	}
-	
+
+
+
 	/**
 	 * 瑙嗛娴佸仠姝�
 	 * 
 	 */
 	@Override
-	public void streamByeCmd(String streamId) {
+	public void streamByeCmd(String ssrc) {
+		streamByeCmd(ssrc, null);
+	}
+	@Override
+	public void streamByeCmd(String streamId, SipSubscribe.Event okEvent) {
 		
 		try {
 			ClientTransaction transaction = streamSession.get(streamId);
+			// 鏈嶅姟閲嶅惎鍚�
 			if (transaction == null) {
+				StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId);
+				if (streamInfo != null) {
+
+				}
 				return;
 			}
 			
@@ -475,6 +495,9 @@
 			if (dialog == null) {
 				return;
 			}
+
+
+
 			Request byeRequest = dialog.createRequest(Request.BYE);
 			SipURI byeURI = (SipURI) byeRequest.getRequestURI();
 			String vh = transaction.getRequest().getHeader(ViaHeader.NAME).toString();
@@ -491,7 +514,14 @@
 			} else if("UDP".equals(protocol)) {
 				clientTransaction = udpSipProvider.getNewClientTransaction(byeRequest);
 			}
+
+			CallIdHeader callIdHeader = (CallIdHeader) byeRequest.getHeader(CallIdHeader.NAME);
+			if (okEvent != null) {
+				sipSubscribe.addOkSubscribe(callIdHeader.getCallId(), okEvent);
+			}
+
 			dialog.sendRequest(clientTransaction);
+
 			streamSession.remove(streamId);
 			zlmrtpServerFactory.closeRTPServer(streamId);
 		} catch (TransactionDoesNotExistException e) {
@@ -612,7 +642,7 @@
 			
 			Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "ViaDeviceInfoBranch", "FromDeviceInfoTag", "ToDeviceInfoTag");
 
-			transmitRequest(device, request, null);
+			transmitRequest(device, request);
 			
 		} catch (SipException | ParseException | InvalidArgumentException e) {
 			e.printStackTrace();
@@ -676,7 +706,7 @@
 			Request request = headerProvider.createMessageRequest(device, recordInfoXml.toString(), "ViaRecordInfoBranch", "FromRecordInfoTag", null);
 
 
-			transmitRequest(device, request, null);
+			transmitRequest(device, request);
 		} catch (SipException | ParseException | InvalidArgumentException e) {
 			e.printStackTrace();
 			return false;
@@ -727,8 +757,16 @@
 		// TODO Auto-generated method stub
 		return false;
 	}
-	
+
+	private ClientTransaction transmitRequest(Device device, Request request) throws SipException {
+		return transmitRequest(device, request, null, null);
+	}
+
 	private ClientTransaction transmitRequest(Device device, Request request, SipSubscribe.Event errorEvent) throws SipException {
+		return transmitRequest(device, request, errorEvent, null);
+	}
+
+	private ClientTransaction transmitRequest(Device device, Request request, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws SipException {
 		ClientTransaction clientTransaction = null;
 		if("TCP".equals(device.getTransport())) {
 			clientTransaction = tcpSipProvider.getNewClientTransaction(request);
@@ -736,10 +774,14 @@
 			clientTransaction = udpSipProvider.getNewClientTransaction(request);
 		}
 
-		// 娣诲姞璁㈤槄
+		CallIdHeader callIdHeader = (CallIdHeader)request.getHeader(CallIdHeader.NAME);
+		// 娣诲姞閿欒璁㈤槄
 		if (errorEvent != null) {
-			CallIdHeader callIdHeader = (CallIdHeader)request.getHeader(CallIdHeader.NAME);
-			sipSubscribe.addSubscribe(callIdHeader.getCallId(), errorEvent);
+			sipSubscribe.addErrorSubscribe(callIdHeader.getCallId(), errorEvent);
+		}
+		// 娣诲姞璁㈤槄
+		if (okEvent != null) {
+			sipSubscribe.addOkSubscribe(callIdHeader.getCallId(), okEvent);
 		}
 
 		clientTransaction.sendRequest();
@@ -747,6 +789,8 @@
 	}
 
 
+
+
 	@Override
 	public void closeRTPServer(Device device, String channelId) {
 		if (rtpEnable) {
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
index 7b793c0..cab4a9b 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
@@ -10,6 +10,7 @@
 import javax.sip.message.Request;
 import javax.sip.message.Response;
 
+import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
 import org.dom4j.Document;
 import org.dom4j.DocumentException;
 import org.dom4j.Element;
@@ -47,6 +48,8 @@
 	private SIPCommander cmder;
 
 	private IVideoManagerStorager storager;
+
+	private IRedisCatchStorage redisCatchStorage;
 
 	private EventPublisher publisher;
 
@@ -451,9 +454,9 @@
 			String NotifyType =XmlUtil.getText(rootElement, "NotifyType");
 			if (NotifyType.equals("121")){
 				logger.info("濯掍綋鎾斁瀹屾瘯锛岄�氱煡鍏虫祦");
-				StreamInfo streamInfo = storager.queryPlaybackByDevice(deviceId, "*");
+				StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, "*");
 				if (streamInfo != null) {
-					storager.stopPlayback(streamInfo);
+					redisCatchStorage.stopPlayback(streamInfo);
 					cmder.streamByeCmd(streamInfo.getStreamId());
 				}
 			}
@@ -507,4 +510,11 @@
 		this.offLineDetector = offLineDetector;
 	}
 
+	public IRedisCatchStorage getRedisCatchStorage() {
+		return redisCatchStorage;
+	}
+
+	public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) {
+		this.redisCatchStorage = redisCatchStorage;
+	}
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java
index be076bd..bcd4482 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java
@@ -141,9 +141,15 @@
 			// 涓嬪彂catelog鏌ヨ鐩綍
 			if (registerFlag == 1 && device != null) {
 				logger.info("娉ㄥ唽鎴愬姛! deviceId:" + device.getDeviceId());
+				boolean exists = storager.exists(device.getDeviceId());
+				device.setRegisterTimeMillis(System.currentTimeMillis());
 				storager.updateDevice(device);
 				publisher.onlineEventPublish(device.getDeviceId(), VideoManagerConstants.EVENT_ONLINE_REGISTER);
-				handler.onRegister(device);
+
+				// 鍙湁绗竴娆℃敞鍐屾墠鏇存柊閫氶亾
+				if (!exists) {
+					handler.onRegister(device);
+				}
 			} else if (registerFlag == 2) {
 				logger.info("娉ㄩ攢鎴愬姛! deviceId:" + device.getDeviceId());
 				publisher.outlineEventPublish(device.getDeviceId(), VideoManagerConstants.EVENT_OUTLINE_UNREGISTER);
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHTTPProxyController.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHTTPProxyController.java
index f76cdd9..9daef23 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHTTPProxyController.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHTTPProxyController.java
@@ -2,6 +2,7 @@
 
 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;
@@ -29,6 +30,9 @@
     @Autowired
     private IVideoManagerStorager storager;
 
+    @Autowired
+    private IRedisCatchStorage redisCatchStorage;
+
     @Value("${media.port}")
     private int mediaHttpPort;
 
@@ -36,10 +40,10 @@
     @RequestMapping(value = "/**/**/**", produces = "application/json;charset=UTF-8")
     public Object proxy(HttpServletRequest request, HttpServletResponse response){
 
-        if (storager.getMediaInfo() == null) {
+        if (redisCatchStorage.getMediaInfo() == null) {
             return "鏈帴鍏ユ祦濯掍綋";
         }
-        MediaServerConfig mediaInfo = storager.getMediaInfo();
+        MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
         String requestURI = String.format("http://%s:%s%s?%s&%s",
                 mediaInfo.getLocalIP(),
                 mediaHttpPort,
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
index 1116ae5..cb8ad05 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -11,6 +11,7 @@
 import com.genersoft.iot.vmp.common.StreamInfo;
 import com.genersoft.iot.vmp.conf.MediaServerConfig;
 import com.genersoft.iot.vmp.gb28181.bean.Device;
+import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
 import com.genersoft.iot.vmp.utils.IpUtil;
 import com.genersoft.iot.vmp.vmanager.service.IPlayService;
@@ -51,6 +52,9 @@
 
 	@Autowired
 	private IVideoManagerStorager storager;
+
+	@Autowired
+	private IRedisCatchStorage redisCatchStorage;
 
 	@Autowired
 	private ZLMRESTfulUtils zlmresTfulUtils;
@@ -249,13 +253,13 @@
 		String app = json.getString("app");
 		String streamId = json.getString("stream");
 		boolean regist = json.getBoolean("regist");
-		StreamInfo streamInfo = storager.queryPlayByStreamId(streamId);
+		StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId);
 		if ("rtp".equals(app) && !regist ) {
 			if (streamInfo!=null){
-				storager.stopPlay(streamInfo);
+				redisCatchStorage.stopPlay(streamInfo);
 			}else{
-				streamInfo = storager.queryPlaybackByStreamId(streamId);
-				storager.stopPlayback(streamInfo);
+				streamInfo = redisCatchStorage.queryPlaybackByStreamId(streamId);
+				redisCatchStorage.stopPlayback(streamInfo);
 			}
 		}
 
@@ -281,12 +285,12 @@
 		String streamId = json.getString("stream");
 
 		cmder.streamByeCmd(streamId);
-		StreamInfo streamInfo = storager.queryPlayByStreamId(streamId);
+		StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId);
 		if (streamInfo!=null){
-			storager.stopPlay(streamInfo);
+			redisCatchStorage.stopPlay(streamInfo);
 		}else{
-			streamInfo = storager.queryPlaybackByStreamId(streamId);
-			storager.stopPlayback(streamInfo);
+			streamInfo = redisCatchStorage.queryPlaybackByStreamId(streamId);
+			redisCatchStorage.stopPlayback(streamInfo);
 		}
 		
 		JSONObject ret = new JSONObject();
@@ -311,7 +315,7 @@
 		if (autoApplyPlay) {
 			String app = json.getString("app");
 			String streamId = json.getString("stream");
-				StreamInfo streamInfo = storager.queryPlayByStreamId(streamId);
+				StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId);
 			if ("rtp".equals(app) && streamId.indexOf("gb_play") > -1 && streamInfo == null) {
 				String[] s = streamId.split("_");
 				if (s.length == 4) {
@@ -355,7 +359,7 @@
 //		MediaServerConfig mediaServerConfig = mediaServerConfigs.get(0);
 		MediaServerConfig mediaServerConfig = JSON.toJavaObject(json, MediaServerConfig.class);
 		mediaServerConfig.setLocalIP(mediaIp);
-		storager.updateMediaInfo(mediaServerConfig);
+		redisCatchStorage.updateMediaInfo(mediaServerConfig);
 		// TODO Auto-generated method stub
 		
 		JSONObject ret = new JSONObject();
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
index 3f88b2a..282699f 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
@@ -4,6 +4,7 @@
 import com.alibaba.fastjson.JSONArray;
 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 org.slf4j.Logger;
@@ -29,6 +30,9 @@
 
     @Autowired
     private IVideoManagerStorager storager;
+
+    @Autowired
+    private IRedisCatchStorage redisCatchStorage;
 
     @Value("${media.ip}")
     private String mediaIp;
@@ -69,7 +73,7 @@
             logger.info("zlm鎺ュ叆鎴愬姛...");
             if (autoConfig) saveZLMConfig();
             mediaServerConfig = getMediaServerConfig();
-            storager.updateMediaInfo(mediaServerConfig);
+            redisCatchStorage.updateMediaInfo(mediaServerConfig);
         }
     }
 
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
new file mode 100644
index 0000000..8bc78b9
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
@@ -0,0 +1,58 @@
+package com.genersoft.iot.vmp.storager;
+
+import com.genersoft.iot.vmp.common.StreamInfo;
+import com.genersoft.iot.vmp.conf.MediaServerConfig;
+
+import java.util.Map;
+
+public interface IRedisCatchStorage {
+
+    /**
+     * 寮�濮嬫挱鏀炬椂灏嗘祦瀛樺叆
+     *
+     * @param stream 娴佷俊鎭�
+     * @return
+     */
+    boolean startPlay(StreamInfo stream);
+
+
+    /**
+     * 鍋滄鎾斁鏃跺垹闄�
+     *
+     * @return
+     */
+    boolean stopPlay(StreamInfo streamInfo);
+
+    /**
+     * 鏌ヨ鎾斁鍒楄〃
+     * @return
+     */
+    StreamInfo queryPlay(StreamInfo streamInfo);
+
+    StreamInfo queryPlayByStreamId(String steamId);
+
+    StreamInfo queryPlaybackByStreamId(String steamId);
+
+    StreamInfo queryPlayByDevice(String deviceId, String code);
+
+    /**
+     * 鏇存柊娴佸獟浣撲俊鎭�
+     * @param mediaServerConfig
+     * @return
+     */
+    boolean updateMediaInfo(MediaServerConfig mediaServerConfig);
+
+    /**
+     * 鑾峰彇娴佸獟浣撲俊鎭�
+     * @return
+     */
+    MediaServerConfig getMediaInfo();
+
+    Map<String, StreamInfo> queryPlayByDeviceId(String deviceId);
+
+    boolean startPlayback(StreamInfo stream);
+
+    boolean stopPlayback(StreamInfo streamInfo);
+
+    StreamInfo queryPlaybackByDevice(String deviceId, String code);
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
index e85d1ff..4174507 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
@@ -17,19 +17,6 @@
  */
 public interface IVideoManagerStorager {
 
-	/**
-	 * 鏇存柊娴佸獟浣撲俊鎭�
-	 * @param mediaServerConfig
-	 * @return
-	 */
-	public boolean updateMediaInfo(MediaServerConfig mediaServerConfig);
-
-	/**
-	 * 鑾峰彇娴佸獟浣撲俊鎭�
-	 * @return
-	 */
-	public MediaServerConfig getMediaInfo();
-
 	/**   
 	 * 鏍规嵁璁惧ID鍒ゆ柇璁惧鏄惁瀛樺湪
 	 * 
@@ -106,10 +93,9 @@
 	/**
 	 * 鑾峰彇澶氫釜璁惧
 	 *
-	 * @param deviceIds 璁惧ID鏁扮粍
 	 * @return List<Device> 璁惧瀵硅薄鏁扮粍
 	 */
-	public List<Device> queryVideoDeviceList(String[] deviceIds);
+	public List<Device> queryVideoDeviceList();
 
 	/**   
 	 * 鍒犻櫎璁惧
@@ -135,27 +121,6 @@
 	 */
 	public boolean outline(String deviceId);
 
-	/**
-	 * 寮�濮嬫挱鏀炬椂灏嗘祦瀛樺叆
-	 *
-	 * @param stream 娴佷俊鎭�
-	 * @return
-	 */
-	public boolean startPlay(StreamInfo stream);
-
-	/**
-	 * 鍋滄鎾斁鏃跺垹闄�
-	 *
-	 * @return
-	 */
-	public boolean stopPlay(StreamInfo streamInfo);
-
-	/**
-	 * 鏌ユ壘瑙嗛娴�
-	 *
-	 * @return
-	 */
-	public StreamInfo queryPlay(StreamInfo streamInfo);
 
 	/**
 	 * 鏌ヨ瀛愯澶�
@@ -168,10 +133,6 @@
 	 */
     PageResult querySubChannels(String deviceId, String channelId, String query, Boolean hasSubChannel, String online, int page, int count);
 
-	/**
-	 * 鏇存柊缂撳瓨
-	 */
-	public void updateCatch();
 
 	/**
 	 * 娓呯┖閫氶亾
@@ -179,17 +140,4 @@
 	 */
 	void cleanChannelsForDevice(String deviceId);
 
-	StreamInfo queryPlayByStreamId(String streamId);
-
-	StreamInfo queryPlayByDevice(String deviceId, String code);
-
-	Map<String, StreamInfo> queryPlayByDeviceId(String deviceId);
-
-	boolean startPlayback(StreamInfo streamInfo);
-
-	boolean stopPlayback(StreamInfo streamInfo);
-
-	StreamInfo queryPlaybackByDevice(String deviceId, String channelId);
-
-	StreamInfo queryPlaybackByStreamId(String streamId);
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/VideoManagerStoragerFactory.java b/src/main/java/com/genersoft/iot/vmp/storager/VideoManagerStoragerFactory.java
deleted file mode 100644
index 70bdad7..0000000
--- a/src/main/java/com/genersoft/iot/vmp/storager/VideoManagerStoragerFactory.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.genersoft.iot.vmp.storager;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Bean;
-import org.springframework.stereotype.Component;
-
-import com.genersoft.iot.vmp.conf.VManagerConfig;
-
-/**    
- * @Description:瑙嗛璁惧鏁版嵁瀛樺偍宸ュ巶锛屾牴鎹瓨鍌ㄧ瓥鐣ワ紝杩斿洖瀵瑰簲鐨勫瓨鍌ㄥ櫒
- * @author: swwheihei
- * @date:   2020骞�5鏈�6鏃� 涓嬪崍2:15:16     
- */
-@Component
-public class VideoManagerStoragerFactory {
-	
-	@Autowired
-	private VManagerConfig vmConfig;
-
-	@Autowired
-	private IVideoManagerStorager jdbcStorager;
-	
-	@Autowired
-	private IVideoManagerStorager redisStorager;
-	
-	@Bean("storager")
-	public IVideoManagerStorager getStorager() {
-		if ("redis".equals(vmConfig.getDatabase().toLowerCase())) {
-			return redisStorager;
-		} else  if ("jdbc".equals(vmConfig.getDatabase().toLowerCase())) {
-			return jdbcStorager;
-		}
-		return redisStorager;
-	}
-	
-}
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/VodeoMannagerTask.java b/src/main/java/com/genersoft/iot/vmp/storager/VodeoMannagerTask.java
index c96e4bb..c207484 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/VodeoMannagerTask.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/VodeoMannagerTask.java
@@ -8,10 +8,10 @@
 public class VodeoMannagerTask implements CommandLineRunner {
 
     @Autowired
-    private IVideoManagerStorager storager;
+    private IVideoManagerStorager redisStorager;
 
     @Override
     public void run(String... strings) throws Exception {
-        storager.updateCatch();
+        redisStorager.updateCatch();
     }
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java
new file mode 100644
index 0000000..bf67095
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java
@@ -0,0 +1,20 @@
+package com.genersoft.iot.vmp.storager.dao;
+
+import com.genersoft.iot.vmp.common.PageResult;
+import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+@Mapper
+public interface DeviceChannelMapper {
+    int update(DeviceChannel channel);
+
+    List<DeviceChannel> queryChannelsByDeviceId(String deviceId);
+
+    List<DeviceChannel> queryChannelsByDeviceId(String deviceId, String parentChannelId);
+
+    DeviceChannel queryChannel(String deviceId, String channelId);
+
+    int cleanChannelsByDeviceId(String deviceId);
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java
new file mode 100644
index 0000000..da455fb
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java
@@ -0,0 +1,24 @@
+package com.genersoft.iot.vmp.storager.dao;
+
+import com.genersoft.iot.vmp.gb28181.bean.Device;
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+@Mapper
+public interface DeviceMapper {
+
+    @Select("SELECT * FROM device WHERE deviceId = #{deviceId}")
+    Device getDeviceByDeviceId(String deviceId);
+
+    @Insert("SELECT * FROM device WHERE deviceId = #{deviceId}")
+    int add(Device device);
+
+    int update(Device device);
+
+    List<Device> getDevices();
+
+    int del(String deviceId);
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
new file mode 100644
index 0000000..8eaaf68
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
@@ -0,0 +1,172 @@
+package com.genersoft.iot.vmp.storager.impl;
+
+import com.genersoft.iot.vmp.common.StreamInfo;
+import com.genersoft.iot.vmp.common.VideoManagerConstants;
+import com.genersoft.iot.vmp.conf.MediaServerConfig;
+import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
+import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
+import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
+import com.genersoft.iot.vmp.storager.dao.DeviceMapper;
+import com.genersoft.iot.vmp.utils.redis.RedisUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+@Component
+public class RedisCatchStorageImpl implements IRedisCatchStorage {
+
+    @Autowired
+	private RedisUtil redis;
+
+    @Autowired
+    private DeviceMapper deviceMapper;
+
+    @Autowired
+    private DeviceChannelMapper deviceChannelMapper;
+
+
+    /**
+     * 寮�濮嬫挱鏀炬椂灏嗘祦瀛樺叆redis
+     *
+     * @return
+     */
+    @Override
+    public boolean startPlay(StreamInfo stream) {
+        return redis.set(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX, stream.getStreamId(),stream.getDeviceID(), stream.getCahnnelId()),
+                stream);
+    }
+
+    /**
+     * 鍋滄鎾斁鏃朵粠redis鍒犻櫎
+     *
+     * @return
+     */
+    @Override
+    public boolean stopPlay(StreamInfo streamInfo) {
+        if (streamInfo == null) return false;
+        DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(streamInfo.getDeviceID(), streamInfo.getCahnnelId());
+        if (deviceChannel != null) {
+            deviceChannel.setStreamId(null);
+            deviceChannel.setPlay(false);
+            deviceChannel.setDeviceId(streamInfo.getDeviceID());
+            deviceChannelMapper.update(deviceChannel);
+        }
+        return redis.del(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX,
+                streamInfo.getStreamId(),
+                streamInfo.getDeviceID(),
+                streamInfo.getCahnnelId()));
+    }
+
+    /**
+     * 鏌ヨ鎾斁鍒楄〃
+     * @return
+     */
+    @Override
+    public StreamInfo queryPlay(StreamInfo streamInfo) {
+        return (StreamInfo)redis.get(String.format("%S_%s_%s_%s",
+                VideoManagerConstants.PLAYER_PREFIX,
+                streamInfo.getStreamId(),
+                streamInfo.getDeviceID(),
+                streamInfo.getCahnnelId()));
+    }
+    @Override
+    public StreamInfo queryPlayByStreamId(String steamId) {
+        List<Object> playLeys = redis.scan(String.format("%S_%s_*", VideoManagerConstants.PLAYER_PREFIX, steamId));
+        if (playLeys == null || playLeys.size() == 0) return null;
+        return (StreamInfo)redis.get(playLeys.get(0).toString());
+    }
+
+    @Override
+    public StreamInfo queryPlaybackByStreamId(String steamId) {
+        List<Object> playLeys = redis.scan(String.format("%S_%s_*", VideoManagerConstants.PLAY_BLACK_PREFIX, steamId));
+        if (playLeys == null || playLeys.size() == 0) return null;
+        return (StreamInfo)redis.get(playLeys.get(0).toString());
+    }
+
+    @Override
+    public StreamInfo queryPlayByDevice(String deviceId, String code) {
+//		List<Object> playLeys = redis.keys(String.format("%S_*_%s_%s", VideoManagerConstants.PLAYER_PREFIX,
+        List<Object> playLeys = redis.scan(String.format("%S_*_%s_%s", VideoManagerConstants.PLAYER_PREFIX,
+                deviceId,
+                code));
+        if (playLeys == null || playLeys.size() == 0) return null;
+        return (StreamInfo)redis.get(playLeys.get(0).toString());
+    }
+
+    /**
+     * 鏇存柊娴佸獟浣撲俊鎭�
+     * @param mediaServerConfig
+     * @return
+     */
+    @Override
+    public boolean updateMediaInfo(MediaServerConfig mediaServerConfig) {
+        return redis.set(VideoManagerConstants.MEDIA_SERVER_PREFIX,mediaServerConfig);
+    }
+
+    /**
+     * 鑾峰彇娴佸獟浣撲俊鎭�
+     * @return
+     */
+    @Override
+    public MediaServerConfig getMediaInfo() {
+        return (MediaServerConfig)redis.get(VideoManagerConstants.MEDIA_SERVER_PREFIX);
+    }
+
+    @Override
+    public Map<String, StreamInfo> queryPlayByDeviceId(String deviceId) {
+        Map<String, StreamInfo> streamInfos = new HashMap<>();
+//		List<Object> playLeys = redis.keys(String.format("%S_*_%S_*", VideoManagerConstants.PLAYER_PREFIX, deviceId));
+        List<Object> players = redis.scan(String.format("%S_*_%S_*", VideoManagerConstants.PLAYER_PREFIX, deviceId));
+        if (players.size() == 0) return streamInfos;
+        for (int i = 0; i < players.size(); i++) {
+            String key = (String) players.get(i);
+            StreamInfo streamInfo = (StreamInfo)redis.get(key);
+            streamInfos.put(streamInfo.getDeviceID() + "_" + streamInfo.getCahnnelId(), streamInfo);
+        }
+        return streamInfos;
+    }
+
+
+    @Override
+    public boolean startPlayback(StreamInfo stream) {
+        return redis.set(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, stream.getStreamId(),stream.getDeviceID(), stream.getCahnnelId()),
+                stream);
+    }
+
+
+    @Override
+    public boolean stopPlayback(StreamInfo streamInfo) {
+        if (streamInfo == null) return false;
+        DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(streamInfo.getDeviceID(), streamInfo.getCahnnelId());
+        if (deviceChannel != null) {
+            deviceChannel.setStreamId(null);
+            deviceChannel.setPlay(false);
+            deviceChannel.setDeviceId(streamInfo.getDeviceID());
+            deviceChannelMapper.update(deviceChannel);
+        }
+        return redis.del(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX,
+                streamInfo.getStreamId(),
+                streamInfo.getDeviceID(),
+                streamInfo.getCahnnelId()));
+    }
+
+    @Override
+    public StreamInfo queryPlaybackByDevice(String deviceId, String 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));
+        if (playLeys == null || playLeys.size() == 0) {
+            playLeys = redis.scan(String.format("%S_*_*_%s", VideoManagerConstants.PLAY_BLACK_PREFIX,
+                    deviceId));
+        }
+        if (playLeys == null || playLeys.size() == 0) return null;
+        return (StreamInfo)redis.get(playLeys.get(0).toString());
+    }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
new file mode 100644
index 0000000..1288efc
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
@@ -0,0 +1,401 @@
+package com.genersoft.iot.vmp.storager.impl;
+
+import java.util.*;
+
+import com.genersoft.iot.vmp.common.PageResult;
+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.storager.dao.DeviceChannelMapper;
+import com.genersoft.iot.vmp.storager.dao.DeviceMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.genersoft.iot.vmp.common.VideoManagerConstants;
+import com.genersoft.iot.vmp.gb28181.bean.Device;
+import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
+import com.genersoft.iot.vmp.utils.redis.RedisUtil;
+import org.springframework.util.StringUtils;
+
+/**    
+ * @Description:瑙嗛璁惧鏁版嵁瀛樺偍-jdbc瀹炵幇
+ * @author: swwheihei
+ * @date:   2020骞�5鏈�6鏃� 涓嬪崍2:31:42
+ */
+@Component
+public class VideoManagerStoragerImpl implements IVideoManagerStorager {
+
+	@Autowired
+    private DeviceMapper deviceMapper;
+
+	@Autowired
+    private DeviceChannelMapper deviceChannelMapper;
+
+
+	/**
+	 * 鏍规嵁璁惧ID鍒ゆ柇璁惧鏄惁瀛樺湪
+	 *
+	 * @param deviceId 璁惧ID
+	 * @return true:瀛樺湪  false锛氫笉瀛樺湪
+	 */
+	@Override
+	public boolean exists(String deviceId) {
+		return deviceMapper.getDeviceByDeviceId(deviceId) != null;
+	}
+
+	/**
+	 * 瑙嗛璁惧鍒涘缓
+	 *
+	 * @param device 璁惧瀵硅薄
+	 * @return true锛氬垱寤烘垚鍔�  false锛氬垱寤哄け璐�
+	 */
+	@Override
+	public boolean create(Device device) {
+		return deviceMapper.add(device) > 0;
+	}
+
+
+
+	/**
+	 * 瑙嗛璁惧鏇存柊
+	 *
+	 * @param device 璁惧瀵硅薄
+	 * @return true锛氭洿鏂版垚鍔�  false锛氭洿鏂板け璐�
+	 */
+	@Override
+	public boolean updateDevice(Device device) {
+//		if (deviceMap.get(device.getDeviceId()) == null) {
+//			deviceMap.put(device.getDeviceId(), new HashMap<String, HashSet<String>>());
+//		}
+		// 鏇存柊device涓殑閫氶亾鏁伴噺
+//		device.setChannelCount(deviceMap.get(device.getDeviceId()).size());
+		int result = deviceMapper.update(device);
+		// 瀛樺偍device
+		return result > 0;
+
+
+	}
+
+	@Override
+	public void updateChannel(String deviceId, DeviceChannel channel) {
+		String channelId = channel.getChannelId();
+		channel.setDeviceId(deviceId);
+		deviceChannelMapper.update(channel);
+
+//		HashMap<String, HashSet<String>> channelMap = deviceMap.get(deviceId);
+//		if (channelMap == null) return;
+//		// 浣滀负鐖惰澶�, 纭畾鑷繁鐨勫瓙鑺傜偣鏁�
+//		if (channelMap.get(channelId) == null) {
+//			channelMap.put(channelId, new HashSet<String>());
+//		}else if (channelMap.get(channelId).size() > 0) {
+//			channel.setSubCount(channelMap.get(channelId).size());
+//		}
+//
+//		// 瀛樺偍閫氶亾
+//		redis.set(VideoManagerConstants.CACHEKEY_PREFIX + deviceId +
+//						"_" + channel.getChannelId() +
+//						"_" + (channel.getStatus() == 1 ? "on":"off") +
+//						"_" + (channelMap.get(channelId).size() > 0)+
+//						"_" + (StringUtils.isEmpty(channel.getParentId())?null:channel.getParentId()),
+//				channel);
+//		// 鏇存柊device涓殑閫氶亾鏁伴噺
+//		Device device = (Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceId);
+//		device.setChannelCount(deviceMap.get(deviceId).size());
+//		redis.set(VideoManagerConstants.DEVICE_PREFIX+device.getDeviceId(), device);
+//
+//
+//		// 濡傛灉鏈夌埗璁惧,鏇存柊鐖惰澶囧唴瀛愯妭鐐规暟
+//		String parentId = channel.getParentId();
+//		if (!StringUtils.isEmpty(parentId) && !parentId.equals(deviceId)) {
+//
+//			if (channelMap.get(parentId) == null) {
+//				channelMap.put(parentId, new HashSet<String>());
+//			}
+//			channelMap.get(parentId).add(channelId);
+//
+//			DeviceChannel deviceChannel = queryChannel(deviceId, parentId);
+//			if (deviceChannel != null) {
+//				deviceChannel.setSubCount(channelMap.get(parentId).size());
+//				redis.set(VideoManagerConstants.CACHEKEY_PREFIX + deviceId +
+//								"_" + deviceChannel.getChannelId() +
+//								"_" + (deviceChannel.getStatus() == 1 ? "on":"off") +
+//								"_" + (channelMap.get(deviceChannel.getChannelId()).size() > 0)+
+//								"_" + (StringUtils.isEmpty(deviceChannel.getParentId())?null:deviceChannel.getParentId()),
+//						deviceChannel);
+//
+//			}
+//		}
+
+	}
+
+	/**
+	 * 鑾峰彇璁惧
+	 *
+	 * @param deviceId 璁惧ID
+	 * @return Device 璁惧瀵硅薄
+	 */
+	@Override
+	public Device queryVideoDevice(String deviceId) {
+		return deviceMapper.getDeviceByDeviceId(deviceId);
+	}
+
+	@Override
+	public PageResult queryChannelsByDeviceId(String deviceId, String query, Boolean hasSubChannel, String online, int page, int count) {
+		// 鑾峰彇鍒版墍鏈夋鍦ㄦ挱鏀剧殑娴�
+		List<DeviceChannel> result = new ArrayList<>();
+		PageResult pageResult = new PageResult<DeviceChannel>();
+
+		deviceChannelMapper.queryChannelsByDeviceId(deviceId);
+//		String queryContent = "*";
+//		if (!StringUtils.isEmpty(query)) queryContent = String.format("*%S*",query);
+//		String queryHasSubChannel = "*";
+//		if (hasSubChannel != null) queryHasSubChannel = hasSubChannel?"true":"false";
+//		String queryOnline = "*";
+//		if (!StringUtils.isEmpty(online)) queryOnline = online;
+//		String queryStr = VideoManagerConstants.CACHEKEY_PREFIX + deviceId +
+//				"_" + queryContent + // 鎼滅储缂栧彿鍜屽悕绉�
+//				"_" + queryOnline + // 鎼滅储鏄惁鍦ㄧ嚎
+//				"_" + queryHasSubChannel + // 鎼滅储鏄惁鍚湁瀛愯妭鐐�
+//				"_" + "*";
+//		List<Object> deviceChannelList = redis.scan(queryStr);
+//		//瀵规煡璇㈢粨鏋滄帓搴忥紝閬垮厤鍑虹幇閫氶亾鎺掑垪椤哄簭涔卞簭鐨勬儏鍐�
+//		Collections.sort(deviceChannelList,new Comparator<Object>(){
+//			@Override
+//			public int compare(Object o1, Object o2) {
+//				return o1.toString().compareToIgnoreCase(o2.toString());
+//			}
+//		});
+//		pageResult.setPage(page);
+//		pageResult.setCount(count);
+//		pageResult.setTotal(deviceChannelList.size());
+//		int maxCount = (page + 1 ) * count;
+//		if (deviceChannelList != null && deviceChannelList.size() > 0 ) {
+//			for (int i = page * count; i < (pageResult.getTotal() > maxCount ? maxCount : pageResult.getTotal() ); i++) {
+//				DeviceChannel deviceChannel = (DeviceChannel)redis.get((String)deviceChannelList.get(i));
+//				StreamInfo streamInfo = stringStreamInfoMap.get(deviceId + "_" + deviceChannel.getChannelId());
+//				deviceChannel.setPlay(streamInfo != null);
+//				if (streamInfo != null) deviceChannel.setStreamId(streamInfo.getStreamId());
+//				result.add(deviceChannel);
+//			}
+//			pageResult.setData(result);
+//		}
+
+		return pageResult;
+	}
+
+
+
+	@Override
+	public List<DeviceChannel> queryChannelsByDeviceId(String deviceId) {
+//		List<DeviceChannel> result = new ArrayList<>();
+////		List<Object> deviceChannelList = redis.keys(VideoManagerConstants.CACHEKEY_PREFIX + deviceId + "_" + "*");
+//		List<Object> deviceChannelList = redis.scan(VideoManagerConstants.CACHEKEY_PREFIX + deviceId + "_" + "*");
+//
+//		if (deviceChannelList != null && deviceChannelList.size() > 0 ) {
+//			for (int i = 0; i < deviceChannelList.size(); i++) {
+//				result.add((DeviceChannel)redis.get((String) deviceChannelList.get(i)));
+//			}
+//		}
+		return deviceChannelMapper.queryChannelsByDeviceId(deviceId);
+	}
+
+	@Override
+	public PageResult querySubChannels(String deviceId, String parentChannelId, String query, Boolean hasSubChannel, String online, int page, int count) {
+
+		deviceChannelMapper.queryChannelsByDeviceId(deviceId, parentChannelId);
+
+//		List<DeviceChannel> allDeviceChannels = new ArrayList<>();
+//		String queryContent = "*";
+//		if (!StringUtils.isEmpty(query)) queryContent = String.format("*%S*",query);
+//		String queryHasSubChannel = "*";
+//		if (hasSubChannel != null) queryHasSubChannel = hasSubChannel?"true":"false";
+//		String queryOnline = "*";
+//		if (!StringUtils.isEmpty(online)) queryOnline = online;
+//		String queryStr = VideoManagerConstants.CACHEKEY_PREFIX + deviceId +
+//				"_" + queryContent + // 鎼滅储缂栧彿鍜屽悕绉�
+//				"_" + queryOnline + // 鎼滅储鏄惁鍦ㄧ嚎
+//				"_" + queryHasSubChannel + // 鎼滅储鏄惁鍚湁瀛愯妭鐐�
+//				"_" + parentChannelId;
+//
+////		List<Object> deviceChannelList = redis.keys(queryStr);
+//		List<Object> deviceChannelList = redis.scan(queryStr);
+//
+//		if (deviceChannelList != null && deviceChannelList.size() > 0 ) {
+//			for (int i = 0; i < deviceChannelList.size(); i++) {
+//				DeviceChannel deviceChannel = (DeviceChannel)redis.get((String)deviceChannelList.get(i));
+//				if (deviceChannel.getParentId() != null && deviceChannel.getParentId().equals(parentChannelId)) {
+//					allDeviceChannels.add(deviceChannel);
+//				}
+//			}
+//		}
+//		int maxCount = (page + 1 ) * count;
+		PageResult pageResult = new PageResult<DeviceChannel>();
+//		pageResult.setPage(page);
+//		pageResult.setCount(count);
+//		pageResult.setTotal(allDeviceChannels.size());
+//
+//		if (allDeviceChannels.size() > 0) {
+//			pageResult.setData(allDeviceChannels.subList(
+//					page * count, pageResult.getTotal() > maxCount ? maxCount : pageResult.getTotal()
+//			));
+//		}
+		return pageResult;
+	}
+
+	public List<DeviceChannel> querySubChannels(String deviceId, String parentChannelId) {
+		List<DeviceChannel> allDeviceChannels = new ArrayList<>();
+//		List<Object> deviceChannelList = redis.keys(VideoManagerConstants.CACHEKEY_PREFIX + deviceId + "_" + "*");
+//		List<Object> deviceChannelList = redis.scan(VideoManagerConstants.CACHEKEY_PREFIX + deviceId + "_" + "*");
+//
+//		if (deviceChannelList != null && deviceChannelList.size() > 0 ) {
+//			for (int i = 0; i < deviceChannelList.size(); i++) {
+//				DeviceChannel deviceChannel = (DeviceChannel)redis.get((String)deviceChannelList.get(i));
+//				if (deviceChannel.getParentId() != null && deviceChannel.getParentId().equals(parentChannelId)) {
+//					allDeviceChannels.add(deviceChannel);
+//				}
+//			}
+//		}
+
+		return allDeviceChannels;
+	}
+
+	@Override
+	public DeviceChannel queryChannel(String deviceId, String channelId) {
+		DeviceChannel deviceChannel = null;
+		return deviceChannelMapper.queryChannel(deviceId, channelId);
+////		List<Object> deviceChannelList = redis.keys(VideoManagerConstants.CACHEKEY_PREFIX + deviceId +
+//		List<Object> deviceChannelList = redis.scan(VideoManagerConstants.CACHEKEY_PREFIX + deviceId +
+//				"_" + channelId  + "*");
+//		if (deviceChannelList != null && deviceChannelList.size() > 0 ) {
+//			deviceChannel = (DeviceChannel)redis.get((String)deviceChannelList.get(0));
+//		}
+//		return deviceChannel;
+	}
+
+
+	/**
+	 * 鑾峰彇澶氫釜璁惧
+	 *
+	 * @param deviceIds 璁惧ID鏁扮粍
+	 * @return List<Device> 璁惧瀵硅薄鏁扮粍
+	 */
+	@Override
+	public PageResult<Device> queryVideoDeviceList(String[] deviceIds, int page, int count) {
+		List<Device> devices = new ArrayList<>();
+		PageResult pageResult = new PageResult<Device>();
+//		pageResult.setPage(page);
+//		pageResult.setCount(count);
+//		Device device = null;
+//
+//		if (deviceIds == null || deviceIds.length == 0) {
+//
+////			List<Object> deviceIdList = redis.keys(VideoManagerConstants.DEVICE_PREFIX+"*");
+//			List<Object> deviceIdList = redis.scan(VideoManagerConstants.DEVICE_PREFIX+"*");
+//			pageResult.setTotal(deviceIdList.size());
+//			int maxCount = (page + 1)* count;
+//			for (int i = page * count; i < (pageResult.getTotal() > maxCount ? maxCount : pageResult.getTotal() ); i++) {
+//				// devices.add((Device)redis.get((String)deviceIdList.get(i)));
+//				device =(Device)redis.get((String)deviceIdList.get(i));
+//				if (redis.scan(VideoManagerConstants.KEEPLIVEKEY_PREFIX+device.getDeviceId()).size() == 0){
+//					// outline(device.getDeviceId());
+//				}
+//				devices.add(device);
+//			}
+//		} else {
+//			for (int i = 0; i < deviceIds.length; i++) {
+//				// devices.add((Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceIds[i]));
+//				device = (Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceIds[i]);
+//				if (redis.scan(VideoManagerConstants.KEEPLIVEKEY_PREFIX+device.getDeviceId()).size() == 0){
+//					// outline(device.getDeviceId());
+//				}
+//				devices.add(device);
+//			}
+//		}
+//		pageResult.setData(devices);
+		return pageResult;
+	}
+
+	/**
+	 * 鑾峰彇澶氫釜璁惧
+	 *
+	 * @return List<Device> 璁惧瀵硅薄鏁扮粍
+	 */
+	@Override
+	public List<Device> queryVideoDeviceList() {
+
+//		if (deviceIds == null || deviceIds.length == 0) {
+////			List<Object> deviceIdList = redis.keys(VideoManagerConstants.DEVICE_PREFIX+"*");
+//			List<Object> deviceIdList = redis.scan(VideoManagerConstants.DEVICE_PREFIX+"*");
+//			for (int i = 0; i < deviceIdList.size(); i++) {
+//				device =(Device)redis.get((String)deviceIdList.get(i));
+//				if (redis.scan(VideoManagerConstants.KEEPLIVEKEY_PREFIX+device.getDeviceId()).size() == 0){
+//					outline(device.getDeviceId());
+//				}
+//				devices.add(device);
+//			}
+//		} else {
+//			for (int i = 0; i < deviceIds.length; i++) {
+//				device = (Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceIds[i]);
+//				if (redis.scan(VideoManagerConstants.KEEPLIVEKEY_PREFIX+device.getDeviceId()).size() == 0){
+//					outline(device.getDeviceId());
+//				}
+//				devices.add(device);
+//			}
+//		}
+
+		List<Device> deviceList =  deviceMapper.getDevices();
+		return deviceList;
+	}
+
+	/**
+	 * 鍒犻櫎璁惧
+	 *
+	 * @param deviceId 璁惧ID
+	 * @return true锛氬垹闄ゆ垚鍔�  false锛氬垹闄ゅけ璐�
+	 */
+	@Override
+	public boolean delete(String deviceId) {
+		int result = deviceMapper.del(deviceId);
+
+		return result > 0;
+	}
+
+	/**
+	 * 鏇存柊璁惧鍦ㄧ嚎
+	 *
+	 * @param deviceId 璁惧ID
+	 * @return true锛氭洿鏂版垚鍔�  false锛氭洿鏂板け璐�
+	 */
+	@Override
+	public boolean online(String deviceId) {
+		Device device = deviceMapper.getDeviceByDeviceId(deviceId);
+		device.setOnline(1);
+		return deviceMapper.update(device) > 0;
+	}
+
+	/**
+	 * 鏇存柊璁惧绂荤嚎
+	 *
+	 * @param deviceId 璁惧ID
+	 * @return true锛氭洿鏂版垚鍔�  false锛氭洿鏂板け璐�
+	 */
+	@Override
+	public boolean outline(String deviceId) {
+//		Device device = (Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceId);
+//		if (device == null) return false;
+//		device.setOnline(0);
+//		return redis.set(VideoManagerConstants.DEVICE_PREFIX+device.getDeviceId(), device);
+
+		Device device = deviceMapper.getDeviceByDeviceId(deviceId);
+		device.setOnline(0);
+		return deviceMapper.update(device) > 0;
+	}
+
+
+	@Override
+	public void cleanChannelsForDevice(String deviceId) {
+		int result = deviceChannelMapper.cleanChannelsByDeviceId(deviceId);
+	}
+
+
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java
deleted file mode 100644
index 3302aa3..0000000
--- a/src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java
+++ /dev/null
@@ -1,217 +0,0 @@
-package com.genersoft.iot.vmp.storager.jdbc;
-
-import java.util.List;
-import java.util.Map;
-
-import com.genersoft.iot.vmp.common.PageResult;
-import com.genersoft.iot.vmp.common.StreamInfo;
-import com.genersoft.iot.vmp.conf.MediaServerConfig;
-import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
-import org.springframework.stereotype.Component;
-import org.springframework.stereotype.Service;
-
-import com.genersoft.iot.vmp.common.VideoManagerConstants;
-import com.genersoft.iot.vmp.gb28181.bean.Device;
-import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
-
-/**    
- * @Description:瑙嗛璁惧鏁版嵁瀛樺偍-jdbc瀹炵幇  
- * @author: swwheihei
- * @date:   2020骞�5鏈�6鏃� 涓嬪崍2:28:12     
- */
-@Component("jdbcStorager")
-public class VideoManagerJdbcStoragerImpl implements IVideoManagerStorager {
-
-	@Override
-	public boolean updateMediaInfo(MediaServerConfig mediaServerConfig) {
-		return false;
-	}
-
-	@Override
-	public MediaServerConfig getMediaInfo() {
-		return null;
-	}
-
-	/**
-	 * 鏍规嵁璁惧ID鍒ゆ柇璁惧鏄惁瀛樺湪
-	 * 
-	 * @param deviceId 璁惧ID
-	 * @return true:瀛樺湪  false锛氫笉瀛樺湪
-	 */ 
-	@Override
-	public boolean exists(String deviceId) {
-		// TODO Auto-generated method stub
-		return false;
-	}
-
-	/**   
-	 * 瑙嗛璁惧鍒涘缓
-	 * 
-	 * @param device 璁惧瀵硅薄
-	 * @return true锛氬垱寤烘垚鍔�  false锛氬垱寤哄け璐�
-	 */ 
-	@Override
-	public boolean create(Device device) {
-		// TODO Auto-generated method stub
-		return false;
-	}
-
-	@Override
-	public boolean updateDevice(Device device) {
-		return false;
-	}
-
-	@Override
-	public void updateChannel(String deviceId, DeviceChannel channel) {
-
-	}
-
-
-	/**   
-	 * 鑾峰彇璁惧
-	 * 
-	 * @param deviceId 璁惧ID
-	 * @return Device 璁惧瀵硅薄
-	 */  
-	@Override
-	public Device queryVideoDevice(String deviceId) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	@Override
-	public PageResult queryChannelsByDeviceId(String deviceId, String query, Boolean hasSubChannel, String online, int page, int count) {
-		return null;
-	}
-
-
-	@Override
-	public List<DeviceChannel> queryChannelsByDeviceId(String deviceId) {
-		return null;
-	}
-
-	@Override
-	public DeviceChannel queryChannel(String deviceId, String channelId) {
-		return null;
-	}
-
-	@Override
-	public PageResult<Device> queryVideoDeviceList(String[] deviceIds, int page, int count) {
-		return null;
-	}
-
-	/**   
-	 * 鑾峰彇澶氫釜璁惧
-	 * 
-	 * @param deviceIds 璁惧ID鏁扮粍
-	 * @return List<Device> 璁惧瀵硅薄鏁扮粍
-	 */  
-	@Override
-	public List<Device> queryVideoDeviceList(String[] deviceIds) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	/**   
-	 * 鍒犻櫎璁惧
-	 * 
-	 * @param deviceId 璁惧ID
-	 * @return true锛氬垹闄ゆ垚鍔�  false锛氬垹闄ゅけ璐�
-	 */  
-	@Override
-	public boolean delete(String deviceId) {
-		// TODO Auto-generated method stub
-		return false;
-	}
-
-	/**   
-	 * 鏇存柊璁惧鍦ㄧ嚎
-	 * 
-	 * @param deviceId 璁惧ID
-	 * @return true锛氭洿鏂版垚鍔�  false锛氭洿鏂板け璐�
-	 */ 
-	@Override
-	public boolean online(String deviceId) {
-		// TODO Auto-generated method stub
-		return false;
-	}
-
-	/**   
-	 * 鏇存柊璁惧绂荤嚎
-	 * 
-	 * @param deviceId 璁惧ID
-	 * @return true锛氭洿鏂版垚鍔�  false锛氭洿鏂板け璐�
-	 */ 
-	@Override
-	public boolean outline(String deviceId) {
-		// TODO Auto-generated method stub
-		return false;
-	}
-
-	@Override
-	public boolean stopPlay(StreamInfo streamInfo) {
-		return false;
-	}
-
-	@Override
-	public StreamInfo queryPlay(StreamInfo streamInfo) {
-		return null;
-	}
-
-	@Override
-	public PageResult querySubChannels(String deviceId, String channelId, String query, Boolean hasSubChannel, String online, int page, int count) {
-		return null;
-	}
-
-	@Override
-	public void updateCatch() {
-		System.out.println("##################");
-	}
-
-	@Override
-	public void cleanChannelsForDevice(String deviceId) {
-
-	}
-
-	@Override
-	public boolean startPlay(StreamInfo stream) {
-		return false;
-	}
-
-
-	@Override
-	public StreamInfo queryPlayByDevice(String deviceId, String code) {
-		return null;
-	}
-
-	@Override
-	public Map<String, StreamInfo> queryPlayByDeviceId(String deviceId) {
-
-		return null;
-	}
-
-	@Override
-	public boolean startPlayback(StreamInfo streamInfo) {
-		return false;
-	}
-
-	@Override
-	public boolean stopPlayback(StreamInfo streamInfo) {
-		return false;
-	}
-
-	@Override
-	public StreamInfo queryPlaybackByDevice(String deviceId, String channelId) {
-		return null;
-	}
-
-	@Override
-	public StreamInfo queryPlayByStreamId(String streamId) {
-		return null;
-	}
-
-	@Override
-	public StreamInfo queryPlaybackByStreamId(String streamId) {
-		return null;
-	}
-}
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java
deleted file mode 100644
index 00d41fc..0000000
--- a/src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java
+++ /dev/null
@@ -1,561 +0,0 @@
-package com.genersoft.iot.vmp.storager.redis;
-
-import java.util.*;
-
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
-import com.genersoft.iot.vmp.common.PageResult;
-import com.genersoft.iot.vmp.common.StreamInfo;
-import com.genersoft.iot.vmp.conf.MediaServerConfig;
-import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-import com.genersoft.iot.vmp.common.VideoManagerConstants;
-import com.genersoft.iot.vmp.gb28181.bean.Device;
-import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
-import com.genersoft.iot.vmp.utils.redis.RedisUtil;
-import org.springframework.util.StringUtils;
-
-/**    
- * @Description:瑙嗛璁惧鏁版嵁瀛樺偍-redis瀹炵幇
- * @author: swwheihei
- * @date:   2020骞�5鏈�6鏃� 涓嬪崍2:31:42
- */
-@Component("redisStorager")
-public class VideoManagerRedisStoragerImpl implements IVideoManagerStorager {
-
-	@Autowired
-    private RedisUtil redis;
-
-	private HashMap<String, HashMap<String, HashSet<String>>> deviceMap = new HashMap<>();
-
-
-	/**
-	 * 鏍规嵁璁惧ID鍒ゆ柇璁惧鏄惁瀛樺湪
-	 *
-	 * @param deviceId 璁惧ID
-	 * @return true:瀛樺湪  false锛氫笉瀛樺湪
-	 */
-	@Override
-	public boolean exists(String deviceId) {
-		return redis.hasKey(VideoManagerConstants.DEVICE_PREFIX+deviceId);
-	}
-
-	/**
-	 * 瑙嗛璁惧鍒涘缓
-	 *
-	 * @param device 璁惧瀵硅薄
-	 * @return true锛氬垱寤烘垚鍔�  false锛氬垱寤哄け璐�
-	 */
-	@Override
-	public boolean create(Device device) {
-		return redis.set(VideoManagerConstants.DEVICE_PREFIX+device.getDeviceId(), device);
-	}
-
-
-
-	/**
-	 * 瑙嗛璁惧鏇存柊
-	 *
-	 * @param device 璁惧瀵硅薄
-	 * @return true锛氭洿鏂版垚鍔�  false锛氭洿鏂板け璐�
-	 */
-	@Override
-	public boolean updateDevice(Device device) {
-		if (deviceMap.get(device.getDeviceId()) == null) {
-			deviceMap.put(device.getDeviceId(), new HashMap<String, HashSet<String>>());
-		}
-		// 鏇存柊device涓殑閫氶亾鏁伴噺
-		device.setChannelCount(deviceMap.get(device.getDeviceId()).size());
-		// 瀛樺偍device
-		return redis.set(VideoManagerConstants.DEVICE_PREFIX+device.getDeviceId(), device);
-
-
-	}
-
-	@Override
-	public void updateChannel(String deviceId, DeviceChannel channel) {
-		String channelId = channel.getChannelId();
-		HashMap<String, HashSet<String>> channelMap = deviceMap.get(deviceId);
-		if (channelMap == null) return;
-		// 浣滀负鐖惰澶�, 纭畾鑷繁鐨勫瓙鑺傜偣鏁�
-		if (channelMap.get(channelId) == null) {
-			channelMap.put(channelId, new HashSet<String>());
-		}else if (channelMap.get(channelId).size() > 0) {
-			channel.setSubCount(channelMap.get(channelId).size());
-		}
-
-		// 瀛樺偍閫氶亾
-		redis.set(VideoManagerConstants.CACHEKEY_PREFIX + deviceId +
-						"_" + channel.getChannelId() +
-						"_" + (channel.getStatus() == 1 ? "on":"off") +
-						"_" + (channelMap.get(channelId).size() > 0)+
-						"_" + (StringUtils.isEmpty(channel.getParentId())?null:channel.getParentId()),
-				channel);
-		// 鏇存柊device涓殑閫氶亾鏁伴噺
-		Device device = (Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceId);
-		device.setChannelCount(deviceMap.get(deviceId).size());
-		redis.set(VideoManagerConstants.DEVICE_PREFIX+device.getDeviceId(), device);
-
-
-		// 濡傛灉鏈夌埗璁惧,鏇存柊鐖惰澶囧唴瀛愯妭鐐规暟
-		String parentId = channel.getParentId();
-		if (!StringUtils.isEmpty(parentId) && !parentId.equals(deviceId)) {
-
-			if (channelMap.get(parentId) == null) {
-				channelMap.put(parentId, new HashSet<String>());
-			}
-			channelMap.get(parentId).add(channelId);
-
-			DeviceChannel deviceChannel = queryChannel(deviceId, parentId);
-			if (deviceChannel != null) {
-				deviceChannel.setSubCount(channelMap.get(parentId).size());
-				redis.set(VideoManagerConstants.CACHEKEY_PREFIX + deviceId +
-								"_" + deviceChannel.getChannelId() +
-								"_" + (deviceChannel.getStatus() == 1 ? "on":"off") +
-								"_" + (channelMap.get(deviceChannel.getChannelId()).size() > 0)+
-								"_" + (StringUtils.isEmpty(deviceChannel.getParentId())?null:deviceChannel.getParentId()),
-						deviceChannel);
-
-			}
-		}
-
-	}
-
-	/**
-	 * 鑾峰彇璁惧
-	 *
-	 * @param deviceId 璁惧ID
-	 * @return Device 璁惧瀵硅薄
-	 */
-	@Override
-	public Device queryVideoDevice(String deviceId) {
-		return (Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceId);
-	}
-
-	@Override
-	public PageResult queryChannelsByDeviceId(String deviceId, String query, Boolean hasSubChannel, String online, int page, int count) {
-		// 鑾峰彇鍒版墍鏈夋鍦ㄦ挱鏀剧殑娴�
-		Map<String, StreamInfo> stringStreamInfoMap = queryPlayByDeviceId(deviceId);
-		List<DeviceChannel> result = new ArrayList<>();
-		PageResult pageResult = new PageResult<DeviceChannel>();
-		String queryContent = "*";
-		if (!StringUtils.isEmpty(query)) queryContent = String.format("*%S*",query);
-		String queryHasSubChannel = "*";
-		if (hasSubChannel != null) queryHasSubChannel = hasSubChannel?"true":"false";
-		String queryOnline = "*";
-		if (!StringUtils.isEmpty(online)) queryOnline = online;
-		String queryStr = VideoManagerConstants.CACHEKEY_PREFIX + deviceId +
-				"_" + queryContent + // 鎼滅储缂栧彿鍜屽悕绉�
-				"_" + queryOnline + // 鎼滅储鏄惁鍦ㄧ嚎
-				"_" + queryHasSubChannel + // 鎼滅储鏄惁鍚湁瀛愯妭鐐�
-				"_" + "*";
-		List<Object> deviceChannelList = redis.scan(queryStr);
-		//瀵规煡璇㈢粨鏋滄帓搴忥紝閬垮厤鍑虹幇閫氶亾鎺掑垪椤哄簭涔卞簭鐨勬儏鍐�
-		Collections.sort(deviceChannelList,new Comparator<Object>(){
-			@Override
-			public int compare(Object o1, Object o2) {
-				return o1.toString().compareToIgnoreCase(o2.toString());
-			}
-		});
-		pageResult.setPage(page);
-		pageResult.setCount(count);
-		pageResult.setTotal(deviceChannelList.size());
-		int maxCount = (page + 1 ) * count;
-		if (deviceChannelList != null && deviceChannelList.size() > 0 ) {
-			for (int i = page * count; i < (pageResult.getTotal() > maxCount ? maxCount : pageResult.getTotal() ); i++) {
-				DeviceChannel deviceChannel = (DeviceChannel)redis.get((String)deviceChannelList.get(i));
-				StreamInfo streamInfo = stringStreamInfoMap.get(deviceId + "_" + deviceChannel.getChannelId());
-				deviceChannel.setPlay(streamInfo != null);
-				if (streamInfo != null) deviceChannel.setStreamId(streamInfo.getStreamId());
-				result.add(deviceChannel);
-			}
-			pageResult.setData(result);
-		}
-
-		return pageResult;
-	}
-
-
-
-	@Override
-	public List<DeviceChannel> queryChannelsByDeviceId(String deviceId) {
-		List<DeviceChannel> result = new ArrayList<>();
-//		List<Object> deviceChannelList = redis.keys(VideoManagerConstants.CACHEKEY_PREFIX + deviceId + "_" + "*");
-		List<Object> deviceChannelList = redis.scan(VideoManagerConstants.CACHEKEY_PREFIX + deviceId + "_" + "*");
-
-		if (deviceChannelList != null && deviceChannelList.size() > 0 ) {
-			for (int i = 0; i < deviceChannelList.size(); i++) {
-				result.add((DeviceChannel)redis.get((String) deviceChannelList.get(i)));
-			}
-		}
-		return result;
-	}
-
-	@Override
-	public PageResult querySubChannels(String deviceId, String parentChannelId, String query, Boolean hasSubChannel, String online, int page, int count) {
-		List<DeviceChannel> allDeviceChannels = new ArrayList<>();
-		String queryContent = "*";
-		if (!StringUtils.isEmpty(query)) queryContent = String.format("*%S*",query);
-		String queryHasSubChannel = "*";
-		if (hasSubChannel != null) queryHasSubChannel = hasSubChannel?"true":"false";
-		String queryOnline = "*";
-		if (!StringUtils.isEmpty(online)) queryOnline = online;
-		String queryStr = VideoManagerConstants.CACHEKEY_PREFIX + deviceId +
-				"_" + queryContent + // 鎼滅储缂栧彿鍜屽悕绉�
-				"_" + queryOnline + // 鎼滅储鏄惁鍦ㄧ嚎
-				"_" + queryHasSubChannel + // 鎼滅储鏄惁鍚湁瀛愯妭鐐�
-				"_" + parentChannelId;
-
-//		List<Object> deviceChannelList = redis.keys(queryStr);
-		List<Object> deviceChannelList = redis.scan(queryStr);
-
-		if (deviceChannelList != null && deviceChannelList.size() > 0 ) {
-			for (int i = 0; i < deviceChannelList.size(); i++) {
-				DeviceChannel deviceChannel = (DeviceChannel)redis.get((String)deviceChannelList.get(i));
-				if (deviceChannel.getParentId() != null && deviceChannel.getParentId().equals(parentChannelId)) {
-					allDeviceChannels.add(deviceChannel);
-				}
-			}
-		}
-		int maxCount = (page + 1 ) * count;
-		PageResult pageResult = new PageResult<DeviceChannel>();
-		pageResult.setPage(page);
-		pageResult.setCount(count);
-		pageResult.setTotal(allDeviceChannels.size());
-
-		if (allDeviceChannels.size() > 0) {
-			pageResult.setData(allDeviceChannels.subList(
-					page * count, pageResult.getTotal() > maxCount ? maxCount : pageResult.getTotal()
-			));
-		}
-		return pageResult;
-	}
-
-	public List<DeviceChannel> querySubChannels(String deviceId, String parentChannelId) {
-		List<DeviceChannel> allDeviceChannels = new ArrayList<>();
-//		List<Object> deviceChannelList = redis.keys(VideoManagerConstants.CACHEKEY_PREFIX + deviceId + "_" + "*");
-		List<Object> deviceChannelList = redis.scan(VideoManagerConstants.CACHEKEY_PREFIX + deviceId + "_" + "*");
-
-		if (deviceChannelList != null && deviceChannelList.size() > 0 ) {
-			for (int i = 0; i < deviceChannelList.size(); i++) {
-				DeviceChannel deviceChannel = (DeviceChannel)redis.get((String)deviceChannelList.get(i));
-				if (deviceChannel.getParentId() != null && deviceChannel.getParentId().equals(parentChannelId)) {
-					allDeviceChannels.add(deviceChannel);
-				}
-			}
-		}
-
-		return allDeviceChannels;
-	}
-
-	@Override
-	public DeviceChannel queryChannel(String deviceId, String channelId) {
-		DeviceChannel deviceChannel = null;
-//		List<Object> deviceChannelList = redis.keys(VideoManagerConstants.CACHEKEY_PREFIX + deviceId +
-		List<Object> deviceChannelList = redis.scan(VideoManagerConstants.CACHEKEY_PREFIX + deviceId +
-				"_" + channelId  + "*");
-		if (deviceChannelList != null && deviceChannelList.size() > 0 ) {
-			deviceChannel = (DeviceChannel)redis.get((String)deviceChannelList.get(0));
-		}
-		return deviceChannel;
-	}
-
-
-	/**
-	 * 鑾峰彇澶氫釜璁惧
-	 *
-	 * @param deviceIds 璁惧ID鏁扮粍
-	 * @return List<Device> 璁惧瀵硅薄鏁扮粍
-	 */
-	@Override
-	public PageResult<Device> queryVideoDeviceList(String[] deviceIds, int page, int count) {
-		List<Device> devices = new ArrayList<>();
-		PageResult pageResult = new PageResult<Device>();
-		pageResult.setPage(page);
-		pageResult.setCount(count);
-		Device device = null;
-
-		if (deviceIds == null || deviceIds.length == 0) {
-
-//			List<Object> deviceIdList = redis.keys(VideoManagerConstants.DEVICE_PREFIX+"*");
-			List<Object> deviceIdList = redis.scan(VideoManagerConstants.DEVICE_PREFIX+"*");
-			pageResult.setTotal(deviceIdList.size());
-			int maxCount = (page + 1)* count;
-			for (int i = page * count; i < (pageResult.getTotal() > maxCount ? maxCount : pageResult.getTotal() ); i++) {
-				// devices.add((Device)redis.get((String)deviceIdList.get(i)));
-				device =(Device)redis.get((String)deviceIdList.get(i));
-				if (redis.scan(VideoManagerConstants.KEEPLIVEKEY_PREFIX+device.getDeviceId()).size() == 0){
-					// outline(device.getDeviceId());
-				}
-				devices.add(device);
-			}
-		} else {
-			for (int i = 0; i < deviceIds.length; i++) {
-				// devices.add((Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceIds[i]));
-				device = (Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceIds[i]);
-				if (redis.scan(VideoManagerConstants.KEEPLIVEKEY_PREFIX+device.getDeviceId()).size() == 0){
-					// outline(device.getDeviceId());
-				}
-				devices.add(device);
-			}
-		}
-		pageResult.setData(devices);
-		return pageResult;
-	}
-
-	/**
-	 * 鑾峰彇澶氫釜璁惧
-	 *
-	 * @param deviceIds 璁惧ID鏁扮粍
-	 * @return List<Device> 璁惧瀵硅薄鏁扮粍
-	 */
-	@Override
-	public List<Device> queryVideoDeviceList(String[] deviceIds) {
-		List<Device> devices = new ArrayList<>();
-		Device device = null;
-
-		if (deviceIds == null || deviceIds.length == 0) {
-//			List<Object> deviceIdList = redis.keys(VideoManagerConstants.DEVICE_PREFIX+"*");
-			List<Object> deviceIdList = redis.scan(VideoManagerConstants.DEVICE_PREFIX+"*");
-			for (int i = 0; i < deviceIdList.size(); i++) {
-				device =(Device)redis.get((String)deviceIdList.get(i));
-				if (redis.scan(VideoManagerConstants.KEEPLIVEKEY_PREFIX+device.getDeviceId()).size() == 0){
-					outline(device.getDeviceId());
-				}
-				devices.add(device);
-			}
-		} else {
-			for (int i = 0; i < deviceIds.length; i++) {
-				device = (Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceIds[i]);
-				if (redis.scan(VideoManagerConstants.KEEPLIVEKEY_PREFIX+device.getDeviceId()).size() == 0){
-					outline(device.getDeviceId());
-				}
-				devices.add(device);
-			}
-		}
-		return devices;
-	}
-
-	/**
-	 * 鍒犻櫎璁惧
-	 *
-	 * @param deviceId 璁惧ID
-	 * @return true锛氬垹闄ゆ垚鍔�  false锛氬垹闄ゅけ璐�
-	 */
-	@Override
-	public boolean delete(String deviceId) {
-		return redis.del(VideoManagerConstants.DEVICE_PREFIX+deviceId);
-	}
-
-	/**
-	 * 鏇存柊璁惧鍦ㄧ嚎
-	 *
-	 * @param deviceId 璁惧ID
-	 * @return true锛氭洿鏂版垚鍔�  false锛氭洿鏂板け璐�
-	 */
-	@Override
-	public boolean online(String deviceId) {
-		Device device = (Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceId);
-		device.setOnline(1);
-		return redis.set(VideoManagerConstants.DEVICE_PREFIX+device.getDeviceId(), device);
-	}
-
-	/**
-	 * 鏇存柊璁惧绂荤嚎
-	 *
-	 * @param deviceId 璁惧ID
-	 * @return true锛氭洿鏂版垚鍔�  false锛氭洿鏂板け璐�
-	 */
-	@Override
-	public boolean outline(String deviceId) {
-		Device device = (Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceId);
-		if (device == null) return false;
-		device.setOnline(0);
-		return redis.set(VideoManagerConstants.DEVICE_PREFIX+device.getDeviceId(), device);
-	}
-
-	/**
-	 * 寮�濮嬫挱鏀炬椂灏嗘祦瀛樺叆redis
-	 *
-	 * @return
-	 */
-	@Override
-	public boolean startPlay(StreamInfo stream) {
-		return redis.set(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX, stream.getStreamId(),stream.getDeviceID(), stream.getCahnnelId()),
-				stream);
-	}
-
-	/**
-	 * 鍋滄鎾斁鏃朵粠redis鍒犻櫎
-	 *
-	 * @return
-	 */
-	@Override
-	public boolean stopPlay(StreamInfo streamInfo) {
-		if (streamInfo == null) return false;
-		DeviceChannel deviceChannel = queryChannel(streamInfo.getDeviceID(), streamInfo.getCahnnelId());
-		if (deviceChannel != null) {
-			deviceChannel.setStreamId(null);
-			deviceChannel.setPlay(false);
-			updateChannel(streamInfo.getDeviceID(), deviceChannel);
-		}
-		return redis.del(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX,
-				streamInfo.getStreamId(),
-				streamInfo.getDeviceID(),
-				streamInfo.getCahnnelId()));
-	}
-
-	/**
-	 * 鏌ヨ鎾斁鍒楄〃
-	 * @return
-	 */
-	@Override
-	public StreamInfo queryPlay(StreamInfo streamInfo) {
-		return (StreamInfo)redis.get(String.format("%S_%s_%s_%s",
-				VideoManagerConstants.PLAYER_PREFIX,
-				streamInfo.getStreamId(),
-				streamInfo.getDeviceID(),
-				streamInfo.getCahnnelId()));
-	}
-	@Override
-	public StreamInfo queryPlayByStreamId(String steamId) {
-		List<Object> playLeys = redis.scan(String.format("%S_%s_*", VideoManagerConstants.PLAYER_PREFIX, steamId));
-		if (playLeys == null || playLeys.size() == 0) return null;
-		return (StreamInfo)redis.get(playLeys.get(0).toString());
-	}
-
-	@Override
-	public StreamInfo queryPlaybackByStreamId(String steamId) {
-		List<Object> playLeys = redis.scan(String.format("%S_%s_*", VideoManagerConstants.PLAY_BLACK_PREFIX, steamId));
-		if (playLeys == null || playLeys.size() == 0) return null;
-		return (StreamInfo)redis.get(playLeys.get(0).toString());
-	}
-
-	@Override
-	public StreamInfo queryPlayByDevice(String deviceId, String code) {
-//		List<Object> playLeys = redis.keys(String.format("%S_*_%s_%s", VideoManagerConstants.PLAYER_PREFIX,
-		List<Object> playLeys = redis.scan(String.format("%S_*_%s_%s", VideoManagerConstants.PLAYER_PREFIX,
-				deviceId,
-				code));
-		if (playLeys == null || playLeys.size() == 0) return null;
-		return (StreamInfo)redis.get(playLeys.get(0).toString());
-	}
-
-	/**
-	 * 鏇存柊娴佸獟浣撲俊鎭�
-	 * @param mediaServerConfig
-	 * @return
-	 */
-	@Override
-	public boolean updateMediaInfo(MediaServerConfig mediaServerConfig) {
-		return redis.set(VideoManagerConstants.MEDIA_SERVER_PREFIX,mediaServerConfig);
-	}
-
-	/**
-	 * 鑾峰彇娴佸獟浣撲俊鎭�
-	 * @return
-	 */
-	@Override
-	public MediaServerConfig getMediaInfo() {
-		return (MediaServerConfig)redis.get(VideoManagerConstants.MEDIA_SERVER_PREFIX);
-	}
-
-	@Override
-	public void updateCatch() {
-		deviceMap = new HashMap<>();
-		// 鏇存柊璁惧
-		List<Device> devices = queryVideoDeviceList(null);
-		if (devices == null && devices.size() == 0) return;
-		for (Device device : devices) {
-			// 鏇存柊璁惧涓嬬殑閫氶亾
-			HashMap<String, HashSet<String>> channelMap = new HashMap<String, HashSet<String>>();
-			List<Object> deviceChannelList = redis.scan(VideoManagerConstants.CACHEKEY_PREFIX +
-					device.getDeviceId() + "_" + "*");
-			if (deviceChannelList != null && deviceChannelList.size() > 0 ) {
-				for (int i = 0; i < deviceChannelList.size(); i++) {
-					String key = (String)deviceChannelList.get(i);
-					String[] s = key.split("_");
-					String channelId = s[3];
-					HashSet<String> subChannel = channelMap.get(channelId);
-					if (subChannel == null) {
-						subChannel = new HashSet<>();
-					}
-					System.out.println(key);
-					if (s.length == 6 && !"null".equals(s[5])) {
-						subChannel.add(s[5]);
-					}
-					channelMap.put(channelId, subChannel);
-				}
-			}
-			deviceMap.put(device.getDeviceId(),channelMap);
-		}
-		System.out.println();
-	}
-
-	@Override
-	public void cleanChannelsForDevice(String deviceId) {
-		List<DeviceChannel> result = new ArrayList<>();
-//		List<Object> deviceChannelList = redis.keys(VideoManagerConstants.CACHEKEY_PREFIX + deviceId + "_" + "*");
-		List<Object> deviceChannelList = redis.scan(VideoManagerConstants.CACHEKEY_PREFIX + deviceId + "_" + "*");
-		if (deviceChannelList != null && deviceChannelList.size() > 0 ) {
-			for (int i = 0; i < deviceChannelList.size(); i++) {
-				redis.del((String)deviceChannelList.get(i));
-			}
-		}
-	}
-
-	@Override
-	public Map<String, StreamInfo> queryPlayByDeviceId(String deviceId) {
-		Map<String, StreamInfo> streamInfos = new HashMap<>();
-//		List<Object> playLeys = redis.keys(String.format("%S_*_%S_*", VideoManagerConstants.PLAYER_PREFIX, deviceId));
-		List<Object> playLeys = redis.scan(String.format("%S_*_%S_*", VideoManagerConstants.PLAYER_PREFIX, deviceId));
-		if (playLeys.size() == 0) return streamInfos;
-		for (int i = 0; i < playLeys.size(); i++) {
-			String key = (String) playLeys.get(i);
-			StreamInfo streamInfo = (StreamInfo)redis.get(key);
-			streamInfos.put(streamInfo.getDeviceID() + "_" + streamInfo.getCahnnelId(), streamInfo);
-		}
-		return streamInfos;
-	}
-
-
-	@Override
-	public boolean startPlayback(StreamInfo stream) {
-		return redis.set(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, stream.getStreamId(),stream.getDeviceID(), stream.getCahnnelId()),
-				stream);
-	}
-
-
-	@Override
-	public boolean stopPlayback(StreamInfo streamInfo) {
-		if (streamInfo == null) return false;
-		DeviceChannel deviceChannel = queryChannel(streamInfo.getDeviceID(), streamInfo.getCahnnelId());
-		if (deviceChannel != null) {
-			deviceChannel.setStreamId(null);
-			deviceChannel.setPlay(false);
-			updateChannel(streamInfo.getDeviceID(), deviceChannel);
-		}
-		return redis.del(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX,
-				streamInfo.getStreamId(),
-				streamInfo.getDeviceID(),
-				streamInfo.getCahnnelId()));
-	}
-
-	@Override
-	public StreamInfo queryPlaybackByDevice(String deviceId, String 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));
-		if (playLeys == null || playLeys.size() == 0) {
-			playLeys = redis.scan(String.format("%S_*_*_%s", VideoManagerConstants.PLAY_BLACK_PREFIX,
-				deviceId));
-		}
-		if (playLeys == null || playLeys.size() == 0) return null;
-		return (StreamInfo)redis.get(playLeys.get(0).toString());
-	}
-}
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java
index eba40bb..59667d0 100644
--- a/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java
@@ -8,6 +8,7 @@
 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.service.IPlayService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -46,6 +47,9 @@
 	private IVideoManagerStorager storager;
 
 	@Autowired
+	private IRedisCatchStorage redisCatchStorage;
+
+	@Autowired
 	private ZLMRESTfulUtils zlmresTfulUtils;
 
 	@Autowired
@@ -60,7 +64,7 @@
 
 
 		Device device = storager.queryVideoDevice(deviceId);
-		StreamInfo streamInfo = storager.queryPlayByDevice(deviceId, channelId);
+		StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
 
 		UUID uuid = UUID.randomUUID();
 		DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>();
@@ -89,7 +93,7 @@
 				msg.setData(JSON.toJSONString(streamInfo));
 				resultHolder.invokeResult(msg);
 			} else {
-				storager.stopPlay(streamInfo);
+				redisCatchStorage.stopPlay(streamInfo);
 				cmder.playStreamCmd(device, channelId, (JSONObject response) -> {
 					logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString());
 					playService.onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString());
@@ -117,25 +121,59 @@
 	}
 
 	@PostMapping("/play/{streamId}/stop")
-	public ResponseEntity<String> playStop(@PathVariable String streamId) {
+	public DeferredResult<ResponseEntity<String>> playStop(@PathVariable String streamId) {
 
-		cmder.streamByeCmd(streamId);
-		StreamInfo streamInfo = storager.queryPlayByStreamId(streamId);
-		if (streamInfo == null)
-			return new ResponseEntity<String>("streamId not found", HttpStatus.OK);
-		storager.stopPlay(streamInfo);
-		if (logger.isDebugEnabled()) {
-			logger.debug(String.format("璁惧棰勮鍋滄API璋冪敤锛宻treamId锛�%s", streamId));
-		}
+		logger.debug(String.format("璁惧棰勮/鍥炴斁鍋滄API璋冪敤锛宻treamId锛�%s", streamId));
+
+		UUID uuid = UUID.randomUUID();
+		DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>();
+
+		// 褰曞儚鏌ヨ浠hannelId浣滀负deviceId鏌ヨ
+		resultHolder.put(DeferredResultHolder.CALLBACK_CMD_STOP + uuid, result);
+
+		cmder.streamByeCmd(streamId, event -> {
+			StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId);
+			if (streamInfo == null) {
+				RequestMessage msg = new RequestMessage();
+				msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
+				msg.setData("streamId not found");
+				resultHolder.invokeResult(msg);
+				redisCatchStorage.stopPlay(streamInfo);
+			}
+
+			RequestMessage msg = new RequestMessage();
+			msg.setId(DeferredResultHolder.CALLBACK_CMD_STOP + uuid);
+			Response response = event.getResponse();
+			msg.setData(String.format("success"));
+			resultHolder.invokeResult(msg);
+		});
+
+
 
 		if (streamId != null) {
 			JSONObject json = new JSONObject();
 			json.put("streamId", streamId);
-			return new ResponseEntity<String>(json.toString(), HttpStatus.OK);
+			RequestMessage msg = new RequestMessage();
+			msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
+			msg.setData(json.toString());
+			resultHolder.invokeResult(msg);
 		} else {
-			logger.warn("璁惧棰勮鍋滄API璋冪敤澶辫触锛�");
-			return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR);
+			logger.warn("璁惧棰勮/鍥炴斁鍋滄API璋冪敤澶辫触锛�");
+			RequestMessage msg = new RequestMessage();
+			msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
+			msg.setData("streamId null");
+			resultHolder.invokeResult(msg);
 		}
+
+		// 瓒呮椂澶勭悊
+		result.onTimeout(()->{
+			logger.warn(String.format("璁惧棰勮/鍥炴斁鍋滄瓒呮椂锛宻treamId锛�%s ", streamId));
+			RequestMessage msg = new RequestMessage();
+			msg.setId(DeferredResultHolder.CALLBACK_CMD_STOP + uuid);
+			msg.setData("Timeout");
+			resultHolder.invokeResult(msg);
+		});
+		return result;
 	}
 
 	/**
@@ -145,7 +183,7 @@
 	 */
 	@PostMapping("/play/{streamId}/convert")
 	public ResponseEntity<String> playConvert(@PathVariable String streamId) {
-		StreamInfo streamInfo = storager.queryPlayByStreamId(streamId);
+		StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId);
 		if (streamInfo == null) {
 			logger.warn("瑙嗛杞爜API璋冪敤澶辫触锛�, 瑙嗛娴佸凡缁忓仠姝�!");
 			return new ResponseEntity<String>("鏈壘鍒拌棰戞祦淇℃伅, 瑙嗛娴佸彲鑳藉凡缁忓仠姝�", HttpStatus.OK);
@@ -155,7 +193,7 @@
 			logger.warn("瑙嗛杞爜API璋冪敤澶辫触锛�, 瑙嗛娴佸凡鍋滄鎺ㄦ祦!");
 			return new ResponseEntity<String>("鎺ㄦ祦淇℃伅鍦ㄦ祦濯掍綋涓笉瀛樺湪, 瑙嗛娴佸彲鑳藉凡鍋滄鎺ㄦ祦", HttpStatus.OK);
 		} else {
-			MediaServerConfig mediaInfo = storager.getMediaInfo();
+			MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
 			String dstUrl = String.format("rtmp://%s:%s/convert/%s", "127.0.0.1", mediaInfo.getRtmpPort(),
 					streamId );
 			String srcUrl = String.format("rtsp://%s:%s/rtp/%s", "127.0.0.1", mediaInfo.getRtspPort(), streamId);
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java
index 2800882..6ce0868 100644
--- a/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java
@@ -6,6 +6,7 @@
 import com.genersoft.iot.vmp.conf.MediaServerConfig;
 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
+import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
 import com.genersoft.iot.vmp.vmanager.play.PlayController;
 import com.genersoft.iot.vmp.vmanager.service.IPlayService;
@@ -25,6 +26,9 @@
     private IVideoManagerStorager storager;
 
     @Autowired
+    private IRedisCatchStorage redisCatchStorage;
+
+    @Autowired
     private DeferredResultHolder resultHolder;
 
     @Override
@@ -33,7 +37,7 @@
         msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
         StreamInfo streamInfo = onPublishHandler(resonse, deviceId, channelId, uuid);
         if (streamInfo != null) {
-            storager.startPlay(streamInfo);
+            redisCatchStorage.startPlay(streamInfo);
             msg.setData(JSON.toJSONString(streamInfo));
             resultHolder.invokeResult(msg);
         } else {
@@ -49,7 +53,7 @@
         msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
         StreamInfo streamInfo = onPublishHandler(resonse, deviceId, channelId, uuid);
         if (streamInfo != null) {
-            storager.startPlayback(streamInfo);
+            redisCatchStorage.startPlayback(streamInfo);
             msg.setData(JSON.toJSONString(streamInfo));
             resultHolder.invokeResult(msg);
         } else {
@@ -65,7 +69,7 @@
         streamInfo.setStreamId(streamId);
         streamInfo.setDeviceID(deviceId);
         streamInfo.setCahnnelId(channelId);
-        MediaServerConfig mediaServerConfig = storager.getMediaInfo();
+        MediaServerConfig mediaServerConfig = redisCatchStorage.getMediaInfo();
 
         streamInfo.setFlv(String.format("http://%s:%s/rtp/%s.flv", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
         streamInfo.setWs_flv(String.format("ws://%s:%s/rtp/%s.flv", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
diff --git a/src/main/java/com/genersoft/iot/vmp/web/ApiDeviceController.java b/src/main/java/com/genersoft/iot/vmp/web/ApiDeviceController.java
index fdb6778..def98d8 100644
--- a/src/main/java/com/genersoft/iot/vmp/web/ApiDeviceController.java
+++ b/src/main/java/com/genersoft/iot/vmp/web/ApiDeviceController.java
@@ -65,7 +65,7 @@
         JSONObject result = new JSONObject();
         List<Device> devices;
         if (start == null || limit ==null) {
-            devices = storager.queryVideoDeviceList(null);
+            devices = storager.queryVideoDeviceList();
             result.put("DeviceCount", devices.size());
         }else {
             PageResult<Device> deviceList = storager.queryVideoDeviceList(null, start/limit, limit);
diff --git a/src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java b/src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java
index 6ef3a5f..5ce51e1 100644
--- a/src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java
+++ b/src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java
@@ -8,6 +8,7 @@
 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.storager.IRedisCatchStorage;
 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
 import com.genersoft.iot.vmp.vmanager.play.PlayController;
 import org.slf4j.Logger;
@@ -34,6 +35,9 @@
 
     @Autowired
     private IVideoManagerStorager storager;
+
+    @Autowired
+    private IRedisCatchStorage redisCatchStorage;
 
     private boolean closeWaitRTPInfo = false;
 
@@ -158,14 +162,14 @@
 
     ){
 
-        StreamInfo streamInfo = storager.queryPlayByDevice(serial, code);
+        StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(serial, code);
         if (streamInfo == null) {
             JSONObject result = new JSONObject();
             result.put("error","鏈壘鍒版祦淇℃伅");
             return result;
         }
         cmder.streamByeCmd(streamInfo.getStreamId());
-        storager.stopPlay(streamInfo);
+        redisCatchStorage.stopPlay(streamInfo);
         return null;
     }
 
diff --git a/src/main/resources/wvp.sqlite b/src/main/resources/wvp.sqlite
new file mode 100644
index 0000000..e781bbc
--- /dev/null
+++ b/src/main/resources/wvp.sqlite
Binary files differ
diff --git a/web_src/src/components/channelList.vue b/web_src/src/components/channelList.vue
index 738012d..b46f1d9 100644
--- a/web_src/src/components/channelList.vue
+++ b/web_src/src/components/channelList.vue
@@ -104,7 +104,7 @@
 
     mounted() {
         this.initData();
-        this.updateLooper = setInterval(this.initData, 10000);
+        this.updateLooper = setInterval(this.initData, 1000);
     },
     destroyed() {
         this.$destroy('videojs');

--
Gitblit v1.8.0