From da14c7f24c61cf9027a02d8e566ab89116136f19 Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: 星期五, 25 九月 2020 17:22:22 +0800
Subject: [PATCH] 拆分redis中device与channel的存储方式 支持分页 接口直接返回播放地址

---
 src/main/java/com/genersoft/iot/vmp/media/zlm/SolrProxyServletConfiguration.java                |   43 +
 src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java                                    |   26 
 src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java                           |    9 
 src/main/java/com/genersoft/iot/vmp/conf/MediaServerConfig.java                                 |  667 +++++++++++++++++++++++++
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java                 |   36 +
 src/main/java/com/genersoft/iot/vmp/web/AuthController.java                                     |   30 +
 src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java                                      |   59 ++
 src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java                                  |  116 ++++
 pom.xml                                                                                         |   11 
 src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java           |  182 ++++++
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java                     |    3 
 src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java                           |   10 
 src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java                         |   97 +++
 src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java             |   68 ++
 src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java                             |   28 +
 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java                          |   15 
 src/main/java/com/genersoft/iot/vmp/common/PageResult.java                                      |   44 +
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java |    2 
 src/main/java/com/genersoft/iot/vmp/vmanager/device/DeviceController.java                       |   24 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java  |   21 
 src/main/resources/application.yml                                                              |   32 
 21 files changed, 1,445 insertions(+), 78 deletions(-)

diff --git a/pom.xml b/pom.xml
index ec4e9c3..528f765 100644
--- a/pom.xml
+++ b/pom.xml
@@ -143,6 +143,17 @@
 			<artifactId>jedis</artifactId>
 			<version>2.9.0</version>
 		</dependency>
+
+		<dependency>
+			<groupId>org.mitre.dsmiley.httpproxy</groupId>
+			<artifactId>smiley-http-proxy-servlet</artifactId>
+			<version>1.7</version>
+		</dependency>
+		<dependency>
+			<groupId>com.google.guava</groupId>
+			<artifactId>guava</artifactId>
+			<version>18.0</version>
+		</dependency>
 		
 	</dependencies>
 	
diff --git a/src/main/java/com/genersoft/iot/vmp/common/PageResult.java b/src/main/java/com/genersoft/iot/vmp/common/PageResult.java
new file mode 100644
index 0000000..9a42086
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/common/PageResult.java
@@ -0,0 +1,44 @@
+package com.genersoft.iot.vmp.common;
+
+import java.util.List;
+
+public class PageResult<T> {
+
+    private int page;
+    private int count;
+    private int total;
+
+    private List<T> data;
+
+    public List<T> getData() {
+        return data;
+    }
+
+    public void setData(List<T> data) {
+        this.data = data;
+    }
+
+    public int getPage() {
+        return page;
+    }
+
+    public void setPage(int page) {
+        this.page = page;
+    }
+
+    public int getCount() {
+        return count;
+    }
+
+    public void setCount(int count) {
+        this.count = count;
+    }
+
+    public int getTotal() {
+        return total;
+    }
+
+    public void setTotal(int total) {
+        this.total = total;
+    }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java
new file mode 100644
index 0000000..6e876be
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java
@@ -0,0 +1,59 @@
+package com.genersoft.iot.vmp.common;
+
+public class StreamInfo {
+
+    private String ssrc;
+    private String flv;
+    private String WS_FLV;
+    private String RTMP;
+    private String HLS;
+    private String RTSP;
+
+    public String getSsrc() {
+        return ssrc;
+    }
+
+    public void setSsrc(String ssrc) {
+        this.ssrc = ssrc;
+    }
+
+    public String getFlv() {
+        return flv;
+    }
+
+    public void setFlv(String flv) {
+        this.flv = flv;
+    }
+
+    public String getWS_FLV() {
+        return WS_FLV;
+    }
+
+    public void setWS_FLV(String WS_FLV) {
+        this.WS_FLV = WS_FLV;
+    }
+
+    public String getRTMP() {
+        return RTMP;
+    }
+
+    public void setRTMP(String RTMP) {
+        this.RTMP = RTMP;
+    }
+
+    public String getHLS() {
+        return HLS;
+    }
+
+    public void setHLS(String HLS) {
+        this.HLS = HLS;
+    }
+
+    public String getRTSP() {
+        return RTSP;
+    }
+
+    public void setRTSP(String RTSP) {
+        this.RTSP = RTSP;
+    }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
index 802309d..98592bd 100644
--- a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
+++ b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
@@ -8,10 +8,16 @@
  */
 public class VideoManagerConstants {
 	
-	public static final String CACHEKEY_PREFIX = "VMP_deviceId_";
+	public static final String MEDIA_SERVER_PREFIX = "VMP_media_server";
+
+	public static final String DEVICE_PREFIX = "VMP_device_";
+
+	public static final String CACHEKEY_PREFIX = "VMP_channel_";
 
 	public static final String KEEPLIVEKEY_PREFIX = "VMP_keeplive_";
-	
+
+	public static final String PLAYER_PREFIX = "VMP_player_";
+
 	public static final String EVENT_ONLINE_REGISTER = "1";
 	
 	public static final String EVENT_ONLINE_KEEPLIVE = "2";
diff --git a/src/main/java/com/genersoft/iot/vmp/conf/MediaServerConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/MediaServerConfig.java
new file mode 100644
index 0000000..6b04f13
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/conf/MediaServerConfig.java
@@ -0,0 +1,667 @@
+package com.genersoft.iot.vmp.conf;
+
+import com.alibaba.fastjson.annotation.JSONField;
+
+public class MediaServerConfig {
+
+    @JSONField(name = "api.apiDebug")
+    private String apiDebug;
+
+    @JSONField(name = "api.secret")
+    private String apiSecret;
+
+    @JSONField(name = "ffmpeg.bin")
+    private String ffmpegBin;
+
+    @JSONField(name = "ffmpeg.cmd")
+    private String ffmpegCmd;
+
+    @JSONField(name = "ffmpeg.log")
+    private String ffmpegLog;
+
+    @JSONField(name = "general.enableVhost")
+    private String generalEnableVhost;
+
+    @JSONField(name = "general.flowThreshold")
+    private String generalFlowThreshold;
+
+    @JSONField(name = "general.maxStreamWaitMS")
+    private String generalMaxStreamWaitMS;
+
+    @JSONField(name = "general.streamNoneReaderDelayMS")
+    private String generalStreamNoneReaderDelayMS;
+
+    @JSONField(name = "hls.fileBufSize")
+    private String hlsFileBufSize;
+
+    @JSONField(name = "hls.filePath")
+    private String hlsFilePath;
+
+    @JSONField(name = "hls.segDur")
+    private String hlsSegDur;
+
+    @JSONField(name = "hls.segNum")
+    private String hlsSegNum;
+
+    @JSONField(name = "hook.access_file_except_hls")
+    private String hookAccessFileExceptHLS;
+
+    @JSONField(name = "hook.admin_params")
+    private String hookAdminParams;
+
+    @JSONField(name = "hook.enable")
+    private String hookEnable;
+
+    @JSONField(name = "hook.on_flow_report")
+    private String hookOnFlowReport;
+
+    @JSONField(name = "hook.on_http_access")
+    private String hookOnHttpAccess;
+
+    @JSONField(name = "hook.on_play")
+    private String hookOnPlay;
+
+    @JSONField(name = "hook.on_publish")
+    private String hookOnPublish;
+
+    @JSONField(name = "hook.on_record_mp4")
+    private String hookOnRecordMp4;
+
+    @JSONField(name = "hook.on_rtsp_auth")
+    private String hookOnRtspAuth;
+
+    @JSONField(name = "hook.on_rtsp_realm")
+    private String hookOnRtspRealm;
+
+    @JSONField(name = "hook.on_shell_login")
+    private String hookOnShellLogin;
+
+    @JSONField(name = "hook.on_stream_changed")
+    private String hookOnStreamChanged;
+
+    @JSONField(name = "hook.on_stream_none_reader")
+    private String hookOnStreamNoneReader;
+
+    @JSONField(name = "hook.on_stream_not_found")
+    private String hookOnStreamNotFound;
+
+    @JSONField(name = "hook.timeoutSec")
+    private String hookTimeoutSec;
+
+    @JSONField(name = "http.charSet")
+    private String httpCharSet;
+
+    @JSONField(name = "http.keepAliveSecond")
+    private String httpKeepAliveSecond;
+
+    @JSONField(name = "http.maxReqCount")
+    private String httpMaxReqCount;
+
+    @JSONField(name = "http.maxReqSize")
+    private String httpMaxReqSize;
+
+    @JSONField(name = "http.notFound")
+    private String httpNotFound;
+
+    @JSONField(name = "http.port")
+    private String httpPort;
+
+    @JSONField(name = "http.rootPath")
+    private String httpRootPath;
+
+    @JSONField(name = "http.sendBufSize")
+    private String httpSendBufSize;
+
+    @JSONField(name = "http.sslport")
+    private String httpSSLport;
+
+    @JSONField(name = "multicast.addrMax")
+    private String multicastAddrMax;
+
+    @JSONField(name = "multicast.addrMin")
+    private String multicastAddrMin;
+
+    @JSONField(name = "multicast.udpTTL")
+    private String multicastUdpTTL;
+
+    @JSONField(name = "record.appName")
+    private String recordAppName;
+
+    @JSONField(name = "record.filePath")
+    private String recordFilePath;
+
+    @JSONField(name = "record.fileSecond")
+    private String recordFileSecond;
+
+    @JSONField(name = "record.sampleMS")
+    private String recordFileSampleMS;
+
+    @JSONField(name = "rtmp.handshakeSecond")
+    private String rtmpHandshakeSecond;
+
+    @JSONField(name = "rtmp.keepAliveSecond")
+    private String rtmpKeepAliveSecond;
+
+    @JSONField(name = "rtmp.modifyStamp")
+    private String rtmpModifyStamp;
+
+    @JSONField(name = "rtmp.port")
+    private String rtmpPort;
+
+    @JSONField(name = "rtp.audioMtuSize")
+    private String rtpAudioMtuSize;
+
+    @JSONField(name = "rtp.clearCount")
+    private String rtpClearCount;
+
+    @JSONField(name = "rtp.cycleMS")
+    private String rtpCycleMS;
+
+    @JSONField(name = "rtp.maxRtpCount")
+    private String rtpMaxRtpCount;
+
+    @JSONField(name = "rtp.videoMtuSize")
+    private String rtpVideoMtuSize;
+
+    @JSONField(name = "rtsp.authBasic")
+    private String rtspAuthBasic;
+
+    @JSONField(name = "rtsp.handshakeSecond")
+    private String rtspHandshakeSecond;
+
+    @JSONField(name = "rtsp.keepAliveSecond")
+    private String rtspKeepAliveSecond;
+
+    @JSONField(name = "rtsp.port")
+    private String rtspPort;
+
+    @JSONField(name = "rtsp.sslport")
+    private String rtspSSlport;
+
+    @JSONField(name = "shell.maxReqSize")
+    private String shellMaxReqSize;
+
+    @JSONField(name = "shell.shell")
+    private String shellPhell;
+
+
+    public String getApiDebug() {
+        return apiDebug;
+    }
+
+    public void setApiDebug(String apiDebug) {
+        this.apiDebug = apiDebug;
+    }
+
+    public String getApiSecret() {
+        return apiSecret;
+    }
+
+    public void setApiSecret(String apiSecret) {
+        this.apiSecret = apiSecret;
+    }
+
+    public String getFfmpegBin() {
+        return ffmpegBin;
+    }
+
+    public void setFfmpegBin(String ffmpegBin) {
+        this.ffmpegBin = ffmpegBin;
+    }
+
+    public String getFfmpegCmd() {
+        return ffmpegCmd;
+    }
+
+    public void setFfmpegCmd(String ffmpegCmd) {
+        this.ffmpegCmd = ffmpegCmd;
+    }
+
+    public String getFfmpegLog() {
+        return ffmpegLog;
+    }
+
+    public void setFfmpegLog(String ffmpegLog) {
+        this.ffmpegLog = ffmpegLog;
+    }
+
+    public String getGeneralEnableVhost() {
+        return generalEnableVhost;
+    }
+
+    public void setGeneralEnableVhost(String generalEnableVhost) {
+        this.generalEnableVhost = generalEnableVhost;
+    }
+
+    public String getGeneralFlowThreshold() {
+        return generalFlowThreshold;
+    }
+
+    public void setGeneralFlowThreshold(String generalFlowThreshold) {
+        this.generalFlowThreshold = generalFlowThreshold;
+    }
+
+    public String getGeneralMaxStreamWaitMS() {
+        return generalMaxStreamWaitMS;
+    }
+
+    public void setGeneralMaxStreamWaitMS(String generalMaxStreamWaitMS) {
+        this.generalMaxStreamWaitMS = generalMaxStreamWaitMS;
+    }
+
+    public String getGeneralStreamNoneReaderDelayMS() {
+        return generalStreamNoneReaderDelayMS;
+    }
+
+    public void setGeneralStreamNoneReaderDelayMS(String generalStreamNoneReaderDelayMS) {
+        this.generalStreamNoneReaderDelayMS = generalStreamNoneReaderDelayMS;
+    }
+
+    public String getHlsFileBufSize() {
+        return hlsFileBufSize;
+    }
+
+    public void setHlsFileBufSize(String hlsFileBufSize) {
+        this.hlsFileBufSize = hlsFileBufSize;
+    }
+
+    public String getHlsFilePath() {
+        return hlsFilePath;
+    }
+
+    public void setHlsFilePath(String hlsFilePath) {
+        this.hlsFilePath = hlsFilePath;
+    }
+
+    public String getHlsSegDur() {
+        return hlsSegDur;
+    }
+
+    public void setHlsSegDur(String hlsSegDur) {
+        this.hlsSegDur = hlsSegDur;
+    }
+
+    public String getHlsSegNum() {
+        return hlsSegNum;
+    }
+
+    public void setHlsSegNum(String hlsSegNum) {
+        this.hlsSegNum = hlsSegNum;
+    }
+
+    public String getHookAccessFileExceptHLS() {
+        return hookAccessFileExceptHLS;
+    }
+
+    public void setHookAccessFileExceptHLS(String hookAccessFileExceptHLS) {
+        this.hookAccessFileExceptHLS = hookAccessFileExceptHLS;
+    }
+
+    public String getHookAdminParams() {
+        return hookAdminParams;
+    }
+
+    public void setHookAdminParams(String hookAdminParams) {
+        this.hookAdminParams = hookAdminParams;
+    }
+
+    public String getHookEnable() {
+        return hookEnable;
+    }
+
+    public void setHookEnable(String hookEnable) {
+        this.hookEnable = hookEnable;
+    }
+
+    public String getHookOnFlowReport() {
+        return hookOnFlowReport;
+    }
+
+    public void setHookOnFlowReport(String hookOnFlowReport) {
+        this.hookOnFlowReport = hookOnFlowReport;
+    }
+
+    public String getHookOnHttpAccess() {
+        return hookOnHttpAccess;
+    }
+
+    public void setHookOnHttpAccess(String hookOnHttpAccess) {
+        this.hookOnHttpAccess = hookOnHttpAccess;
+    }
+
+    public String getHookOnPlay() {
+        return hookOnPlay;
+    }
+
+    public void setHookOnPlay(String hookOnPlay) {
+        this.hookOnPlay = hookOnPlay;
+    }
+
+    public String getHookOnPublish() {
+        return hookOnPublish;
+    }
+
+    public void setHookOnPublish(String hookOnPublish) {
+        this.hookOnPublish = hookOnPublish;
+    }
+
+    public String getHookOnRecordMp4() {
+        return hookOnRecordMp4;
+    }
+
+    public void setHookOnRecordMp4(String hookOnRecordMp4) {
+        this.hookOnRecordMp4 = hookOnRecordMp4;
+    }
+
+    public String getHookOnRtspAuth() {
+        return hookOnRtspAuth;
+    }
+
+    public void setHookOnRtspAuth(String hookOnRtspAuth) {
+        this.hookOnRtspAuth = hookOnRtspAuth;
+    }
+
+    public String getHookOnRtspRealm() {
+        return hookOnRtspRealm;
+    }
+
+    public void setHookOnRtspRealm(String hookOnRtspRealm) {
+        this.hookOnRtspRealm = hookOnRtspRealm;
+    }
+
+    public String getHookOnShellLogin() {
+        return hookOnShellLogin;
+    }
+
+    public void setHookOnShellLogin(String hookOnShellLogin) {
+        this.hookOnShellLogin = hookOnShellLogin;
+    }
+
+    public String getHookOnStreamChanged() {
+        return hookOnStreamChanged;
+    }
+
+    public void setHookOnStreamChanged(String hookOnStreamChanged) {
+        this.hookOnStreamChanged = hookOnStreamChanged;
+    }
+
+    public String getHookOnStreamNoneReader() {
+        return hookOnStreamNoneReader;
+    }
+
+    public void setHookOnStreamNoneReader(String hookOnStreamNoneReader) {
+        this.hookOnStreamNoneReader = hookOnStreamNoneReader;
+    }
+
+    public String getHookOnStreamNotFound() {
+        return hookOnStreamNotFound;
+    }
+
+    public void setHookOnStreamNotFound(String hookOnStreamNotFound) {
+        this.hookOnStreamNotFound = hookOnStreamNotFound;
+    }
+
+    public String getHookTimeoutSec() {
+        return hookTimeoutSec;
+    }
+
+    public void setHookTimeoutSec(String hookTimeoutSec) {
+        this.hookTimeoutSec = hookTimeoutSec;
+    }
+
+    public String getHttpCharSet() {
+        return httpCharSet;
+    }
+
+    public void setHttpCharSet(String httpCharSet) {
+        this.httpCharSet = httpCharSet;
+    }
+
+    public String getHttpKeepAliveSecond() {
+        return httpKeepAliveSecond;
+    }
+
+    public void setHttpKeepAliveSecond(String httpKeepAliveSecond) {
+        this.httpKeepAliveSecond = httpKeepAliveSecond;
+    }
+
+    public String getHttpMaxReqCount() {
+        return httpMaxReqCount;
+    }
+
+    public void setHttpMaxReqCount(String httpMaxReqCount) {
+        this.httpMaxReqCount = httpMaxReqCount;
+    }
+
+    public String getHttpMaxReqSize() {
+        return httpMaxReqSize;
+    }
+
+    public void setHttpMaxReqSize(String httpMaxReqSize) {
+        this.httpMaxReqSize = httpMaxReqSize;
+    }
+
+    public String getHttpNotFound() {
+        return httpNotFound;
+    }
+
+    public void setHttpNotFound(String httpNotFound) {
+        this.httpNotFound = httpNotFound;
+    }
+
+    public String getHttpPort() {
+        return httpPort;
+    }
+
+    public void setHttpPort(String httpPort) {
+        this.httpPort = httpPort;
+    }
+
+    public String getHttpRootPath() {
+        return httpRootPath;
+    }
+
+    public void setHttpRootPath(String httpRootPath) {
+        this.httpRootPath = httpRootPath;
+    }
+
+    public String getHttpSendBufSize() {
+        return httpSendBufSize;
+    }
+
+    public void setHttpSendBufSize(String httpSendBufSize) {
+        this.httpSendBufSize = httpSendBufSize;
+    }
+
+    public String getHttpSSLport() {
+        return httpSSLport;
+    }
+
+    public void setHttpSSLport(String httpSSLport) {
+        this.httpSSLport = httpSSLport;
+    }
+
+    public String getMulticastAddrMax() {
+        return multicastAddrMax;
+    }
+
+    public void setMulticastAddrMax(String multicastAddrMax) {
+        this.multicastAddrMax = multicastAddrMax;
+    }
+
+    public String getMulticastAddrMin() {
+        return multicastAddrMin;
+    }
+
+    public void setMulticastAddrMin(String multicastAddrMin) {
+        this.multicastAddrMin = multicastAddrMin;
+    }
+
+    public String getMulticastUdpTTL() {
+        return multicastUdpTTL;
+    }
+
+    public void setMulticastUdpTTL(String multicastUdpTTL) {
+        this.multicastUdpTTL = multicastUdpTTL;
+    }
+
+    public String getRecordAppName() {
+        return recordAppName;
+    }
+
+    public void setRecordAppName(String recordAppName) {
+        this.recordAppName = recordAppName;
+    }
+
+    public String getRecordFilePath() {
+        return recordFilePath;
+    }
+
+    public void setRecordFilePath(String recordFilePath) {
+        this.recordFilePath = recordFilePath;
+    }
+
+    public String getRecordFileSecond() {
+        return recordFileSecond;
+    }
+
+    public void setRecordFileSecond(String recordFileSecond) {
+        this.recordFileSecond = recordFileSecond;
+    }
+
+    public String getRecordFileSampleMS() {
+        return recordFileSampleMS;
+    }
+
+    public void setRecordFileSampleMS(String recordFileSampleMS) {
+        this.recordFileSampleMS = recordFileSampleMS;
+    }
+
+    public String getRtmpHandshakeSecond() {
+        return rtmpHandshakeSecond;
+    }
+
+    public void setRtmpHandshakeSecond(String rtmpHandshakeSecond) {
+        this.rtmpHandshakeSecond = rtmpHandshakeSecond;
+    }
+
+    public String getRtmpKeepAliveSecond() {
+        return rtmpKeepAliveSecond;
+    }
+
+    public void setRtmpKeepAliveSecond(String rtmpKeepAliveSecond) {
+        this.rtmpKeepAliveSecond = rtmpKeepAliveSecond;
+    }
+
+    public String getRtmpModifyStamp() {
+        return rtmpModifyStamp;
+    }
+
+    public void setRtmpModifyStamp(String rtmpModifyStamp) {
+        this.rtmpModifyStamp = rtmpModifyStamp;
+    }
+
+    public String getRtmpPort() {
+        return rtmpPort;
+    }
+
+    public void setRtmpPort(String rtmpPort) {
+        this.rtmpPort = rtmpPort;
+    }
+
+    public String getRtpAudioMtuSize() {
+        return rtpAudioMtuSize;
+    }
+
+    public void setRtpAudioMtuSize(String rtpAudioMtuSize) {
+        this.rtpAudioMtuSize = rtpAudioMtuSize;
+    }
+
+    public String getRtpClearCount() {
+        return rtpClearCount;
+    }
+
+    public void setRtpClearCount(String rtpClearCount) {
+        this.rtpClearCount = rtpClearCount;
+    }
+
+    public String getRtpCycleMS() {
+        return rtpCycleMS;
+    }
+
+    public void setRtpCycleMS(String rtpCycleMS) {
+        this.rtpCycleMS = rtpCycleMS;
+    }
+
+    public String getRtpMaxRtpCount() {
+        return rtpMaxRtpCount;
+    }
+
+    public void setRtpMaxRtpCount(String rtpMaxRtpCount) {
+        this.rtpMaxRtpCount = rtpMaxRtpCount;
+    }
+
+    public String getRtpVideoMtuSize() {
+        return rtpVideoMtuSize;
+    }
+
+    public void setRtpVideoMtuSize(String rtpVideoMtuSize) {
+        this.rtpVideoMtuSize = rtpVideoMtuSize;
+    }
+
+    public String getRtspAuthBasic() {
+        return rtspAuthBasic;
+    }
+
+    public void setRtspAuthBasic(String rtspAuthBasic) {
+        this.rtspAuthBasic = rtspAuthBasic;
+    }
+
+    public String getRtspHandshakeSecond() {
+        return rtspHandshakeSecond;
+    }
+
+    public void setRtspHandshakeSecond(String rtspHandshakeSecond) {
+        this.rtspHandshakeSecond = rtspHandshakeSecond;
+    }
+
+    public String getRtspKeepAliveSecond() {
+        return rtspKeepAliveSecond;
+    }
+
+    public void setRtspKeepAliveSecond(String rtspKeepAliveSecond) {
+        this.rtspKeepAliveSecond = rtspKeepAliveSecond;
+    }
+
+    public String getRtspPort() {
+        return rtspPort;
+    }
+
+    public void setRtspPort(String rtspPort) {
+        this.rtspPort = rtspPort;
+    }
+
+    public String getRtspSSlport() {
+        return rtspSSlport;
+    }
+
+    public void setRtspSSlport(String rtspSSlport) {
+        this.rtspSSlport = rtspSSlport;
+    }
+
+    public String getShellMaxReqSize() {
+        return shellMaxReqSize;
+    }
+
+    public void setShellMaxReqSize(String shellMaxReqSize) {
+        this.shellMaxReqSize = shellMaxReqSize;
+    }
+
+    public String getShellPhell() {
+        return shellPhell;
+    }
+
+    public void setShellPhell(String shellPhell) {
+        this.shellPhell = shellPhell;
+    }
+}
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 74f86a2..8a88497 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
@@ -49,7 +49,9 @@
 	/**
 	 * 閫氶亾鍒楄〃
 	 */
-	private Map<String,DeviceChannel> channelMap;
+//	private Map<String,DeviceChannel> channelMap;
+
+	private int channelCount;
 
 
 	public String getDeviceId() {
@@ -84,13 +86,13 @@
 		this.host = host;
 	}
 
-	public Map<String, DeviceChannel> getChannelMap() {
-		return channelMap;
-	}
-
-	public void setChannelMap(Map<String, DeviceChannel> channelMap) {
-		this.channelMap = channelMap;
-	}
+//	public Map<String, DeviceChannel> getChannelMap() {
+//		return channelMap;
+//	}
+//
+//	public void setChannelMap(Map<String, DeviceChannel> channelMap) {
+//		this.channelMap = channelMap;
+//	}
 
 	public String getManufacturer() {
 		return manufacturer;
@@ -123,4 +125,12 @@
 	public void setOnline(int online) {
 		this.online = online;
 	}
+
+	public int getChannelCount() {
+		return channelCount;
+	}
+
+	public void setChannelCount(int channelCount) {
+		this.channelCount = channelCount;
+	}
 }
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 1bccad8..5c3989a 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
@@ -100,7 +100,12 @@
 	/**
 	 * 瀵嗙爜
 	 */
-	private String password;	 
+	private String password;
+
+	/**
+	 * 浜戝彴鎺у埗
+	 */
+	private int PTZType;
 	
 	/**
 	 * 鍦ㄧ嚎/绂荤嚎
@@ -122,6 +127,11 @@
 	 * 绾害
 	 */
 	private double latitude;
+
+	/**
+	 * 娴佸敮涓�缂栧彿锛屽瓨鍦ㄨ〃绀烘鍦ㄧ洿鎾�
+	 */
+	private String  ssrc;
 
 	public String getChannelId() {
 		return channelId;
@@ -306,4 +316,20 @@
 	public void setLatitude(double latitude) {
 		this.latitude = latitude;
 	}
+
+	public int getPTZType() {
+		return PTZType;
+	}
+
+	public void setPTZType(int PTZType) {
+		this.PTZType = PTZType;
+	}
+
+	public String getSsrc() {
+		return ssrc;
+	}
+
+	public void setSsrc(String ssrc) {
+		this.ssrc = ssrc;
+	}
 }
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 db93230..0fdc897 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
@@ -1,5 +1,6 @@
 package com.genersoft.iot.vmp.gb28181.transmit.cmd;
 
+import com.genersoft.iot.vmp.common.StreamInfo;
 import com.genersoft.iot.vmp.gb28181.bean.Device;
 
 /**    
@@ -69,7 +70,7 @@
 	 * @param device  瑙嗛璁惧
 	 * @param channelId  棰勮閫氶亾
 	 */
-	public String playStreamCmd(Device device,String channelId);
+	public StreamInfo playStreamCmd(Device device, String channelId);
 	
 	/**
 	 * 璇锋眰鍥炴斁瑙嗛娴�
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 aaf347d..104fab0 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
@@ -15,8 +15,14 @@
 import javax.sip.header.ViaHeader;
 import javax.sip.message.Request;
 
+import com.alibaba.fastjson.JSONObject;
+import com.genersoft.iot.vmp.common.StreamInfo;
+import com.genersoft.iot.vmp.conf.MediaServerConfig;
+import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
+import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
 import com.genersoft.iot.vmp.conf.SipConfig;
@@ -42,6 +48,9 @@
 	
 	@Autowired
 	private VideoStreamSessionManager streamSession;
+
+	@Autowired
+	private IVideoManagerStorager storager;
 	
 	@Autowired
 	@Qualifier(value="tcpSipProvider")
@@ -50,6 +59,9 @@
 	@Autowired
 	@Qualifier(value="udpSipProvider")
 	private SipProvider udpSipProvider;
+
+	@Value("${media.ip}")
+	private String mediaIp;
 	
 	/**
 	 * 浜戝彴鏂瑰悜鏀炬帶鍒讹紝浣跨敤閰嶇疆鏂囦欢涓殑榛樿闀滃ご绉诲姩閫熷害
@@ -58,7 +70,6 @@
 	 * @param channelId  棰勮閫氶亾
 	 * @param leftRight  闀滃ご宸︾Щ鍙崇Щ 0:鍋滄 1:宸︾Щ 2:鍙崇Щ
      * @param upDown     闀滃ご涓婄Щ涓嬬Щ 0:鍋滄 1:涓婄Щ 2:涓嬬Щ
-     * @param moveSpeed  闀滃ご绉诲姩閫熷害
 	 */
 	@Override
 	public boolean ptzdirectCmd(Device device, String channelId, int leftRight, int upDown) {
@@ -191,7 +202,7 @@
 	 * @param channelId  棰勮閫氶亾
 	 */  
 	@Override
-	public String playStreamCmd(Device device, String channelId) {
+	public StreamInfo playStreamCmd(Device device, String channelId) {
 		try {
 			
 			String ssrc = streamSession.createPlaySsrc();
@@ -223,7 +234,24 @@
 	
 	        ClientTransaction transaction = transmitRequest(device, request);
 	        streamSession.put(ssrc, transaction);
-			return ssrc;
+			DeviceChannel deviceChannel = storager.queryChannel(device.getDeviceId(), channelId);
+			if (deviceChannel != null) {
+				deviceChannel.setSsrc(ssrc);
+				storager.updateChannel(device.getDeviceId(), deviceChannel);
+			}
+			MediaServerConfig mediaInfo = storager.getMediaInfo();
+			StreamInfo streamInfo = new StreamInfo();
+			streamInfo.setSsrc(ssrc);
+//			String streamId = Integer.toHexString(Integer.parseInt(streamInfo.getSsrc()));
+			String streamId = String.format("%08x", Integer.parseInt(streamInfo.getSsrc())).toUpperCase(); // ZLM 瑕佹眰澶у啓涓旈浣嶈ˉ闆�
+			streamInfo.setFlv(String.format("http://%s:%s/rtp/%s.flv", mediaIp, mediaInfo.getHttpPort(), streamId));
+			streamInfo.setWS_FLV(String.format("ws://%s:%s/rtp/%s.flv", mediaIp, mediaInfo.getHttpPort(), streamId));
+			streamInfo.setRTMP(String.format("rtmp://%s:%s/rtp/%s", mediaIp, mediaInfo.getRtmpPort(), streamId));
+			streamInfo.setHLS(String.format("http://%s:%s/rtp/%s/hls.m3u8", mediaIp, mediaInfo.getHttpPort(), streamId));
+			streamInfo.setRTSP(String.format("rtsp://%s:%s/rtp/%s", mediaIp, mediaInfo.getRtspPort(), streamId));
+
+			storager.startPlay(device.getDeviceId(), channelId, streamInfo);
+			return streamInfo;
 		} catch ( SipException | ParseException | InvalidArgumentException e) {
 			e.printStackTrace();
 			return null;
@@ -281,8 +309,6 @@
 	/**
 	 * 瑙嗛娴佸仠姝�
 	 * 
-	 * @param device  瑙嗛璁惧
-	 * @param channelId  棰勮閫氶亾
 	 */
 	@Override
 	public void streamByeCmd(String ssrc) {
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 7038590..e9f5906 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
@@ -76,8 +76,6 @@
 	 * 澶勭悊MESSAGE璇锋眰
 	 *  
 	 * @param evt
-	 * @param layer
-	 * @param transaction  
 	 */  
 	@Override
 	public void process(RequestEvent evt) {
@@ -127,7 +125,7 @@
 			device.setManufacturer(XmlUtil.getText(rootElement,"Manufacturer"));
 			device.setModel(XmlUtil.getText(rootElement,"Model"));
 			device.setFirmware(XmlUtil.getText(rootElement,"Firmware"));
-			storager.update(device);
+			storager.updateDevice(device);
 			
 			RequestMessage msg = new RequestMessage();
 			msg.setDeviceId(deviceId);
@@ -158,11 +156,6 @@
 				if (device == null) {
 					return;
 				}
-				Map<String, DeviceChannel> channelMap = device.getChannelMap();
-				if (channelMap == null) {
-					channelMap = new HashMap<String, DeviceChannel>(5);
-					device.setChannelMap(channelMap);
-				}
 				// 閬嶅巻DeviceList
 				while (deviceListIterator.hasNext()) {
 					Element itemDevice = deviceListIterator.next();
@@ -175,7 +168,7 @@
 					String channelName = channdelNameElement != null ? channdelNameElement.getText().toString() : "";
 					Element statusElement = itemDevice.element("Status");
 					String status = statusElement != null ? statusElement.getText().toString() : "ON";
-					DeviceChannel deviceChannel = channelMap.containsKey(channelDeviceId) ? channelMap.get(channelDeviceId) : new DeviceChannel();
+					DeviceChannel deviceChannel = new DeviceChannel();
 					deviceChannel.setName(channelName);
 					deviceChannel.setChannelId(channelDeviceId);
 					if(status.equals("ON")) {
@@ -205,10 +198,12 @@
 					deviceChannel.setPassword(XmlUtil.getText(itemDevice,"Password"));
 					deviceChannel.setLongitude(itemDevice.element("Longitude") == null? 0.00:Double.parseDouble(XmlUtil.getText(itemDevice,"Longitude")));
 					deviceChannel.setLatitude(itemDevice.element("Latitude") == null? 0.00:Double.parseDouble(XmlUtil.getText(itemDevice,"Latitude")));
-					channelMap.put(channelDeviceId, deviceChannel);
+					deviceChannel.setPTZType(itemDevice.element("PTZType") == null? 0:Integer.parseInt(XmlUtil.getText(itemDevice,"PTZType")));
+					storager.updateChannel(device.getDeviceId(), deviceChannel);
 				}
 				// 鏇存柊
-				storager.update(device);
+				storager.updateDevice(device);
+
 				RequestMessage msg = new RequestMessage();
 				msg.setDeviceId(deviceId);
 				msg.setType(DeferredResultHolder.CALLBACK_CMD_CATALOG);
@@ -232,13 +227,15 @@
 			
 			Device device = storager.queryVideoDevice(deviceId);
 			if (device == null) {
+				// TODO 涔熷彲鑳芥槸閫氶亾
+//				storager.queryChannel(deviceId)
 				return;
 			}
 			device.setName(XmlUtil.getText(rootElement,"DeviceName"));
 			device.setManufacturer(XmlUtil.getText(rootElement,"Manufacturer"));
 			device.setModel(XmlUtil.getText(rootElement,"Model"));
 			device.setFirmware(XmlUtil.getText(rootElement,"Firmware"));
-			storager.update(device);
+			storager.updateDevice(device);
 			cmder.catalogQuery(device);
 		} catch (DocumentException e) {
 			e.printStackTrace();
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 a90429a..6217024 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
@@ -138,7 +138,7 @@
 			// 涓嬪彂catelog鏌ヨ鐩綍
 			if (registerFlag == 1 && device != null) {
 				System.out.println("娉ㄥ唽鎴愬姛! deviceId:" + device.getDeviceId());
-				storager.update(device);
+				storager.updateDevice(device);
 				publisher.onlineEventPublish(device.getDeviceId(), VideoManagerConstants.EVENT_ONLINE_REGISTER);
 				handler.onRegister(device);
 			} else if (registerFlag == 2) {
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/SolrProxyServletConfiguration.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/SolrProxyServletConfiguration.java
new file mode 100644
index 0000000..9a22a18
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/SolrProxyServletConfiguration.java
@@ -0,0 +1,43 @@
+package com.genersoft.iot.vmp.media.zlm;
+
+import com.google.common.collect.ImmutableMap;
+import org.mitre.dsmiley.httpproxy.ProxyServlet;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.web.servlet.ServletRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.servlet.Servlet;
+import java.util.Map;
+
+/**
+ * 瀵规煡璇㈡祦濯掍綋淇℃伅鐨勮姹傝繘琛屽弽鍚戜唬鐞�
+ */
+@Configuration
+public class SolrProxyServletConfiguration {
+
+    // 璇诲彇閰嶇疆鏂囦欢涓矾鐢辫缃�
+    @Value("${proxy.servlet_url}")
+    private String servlet_url;
+    // 璇诲彇閰嶇疆涓唬鐞嗙洰鏍囧湴鍧�
+    @Value("${proxy.target_url}")
+    private String target_url;
+
+
+
+    @Bean
+    public Servlet createProxyServlet(){
+        // 鍒涘缓鏂扮殑ProxyServlet
+        return new ProxyServlet();
+    }
+    @Bean
+    public ServletRegistrationBean proxyServletRegistration(){
+        ServletRegistrationBean registrationBean = new ServletRegistrationBean(createProxyServlet(), servlet_url);
+        //璁剧疆缃戝潃浠ュ強鍙傛暟
+        Map<String, String> params = ImmutableMap.of(
+                "targetUri", target_url,
+                "log", "true");
+        registrationBean.setInitParameters(params);
+        return registrationBean;
+    }
+}
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 ae67020..2f5766a 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
@@ -1,7 +1,13 @@
 package com.genersoft.iot.vmp.media.zlm;
 
 import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.genersoft.iot.vmp.conf.MediaServerConfig;
+import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -29,6 +35,9 @@
 	
 	@Autowired
 	private SIPCommander cmder;
+
+	@Autowired
+	private IVideoManagerStorager storager;
 	
 	/**
 	 * 娴侀噺缁熻浜嬩欢锛屾挱鏀惧櫒鎴栨帹娴佸櫒鏂紑鏃跺苟涓旇�楃敤娴侀噺瓒呰繃鐗瑰畾闃堝�兼椂浼氳Е鍙戞浜嬩欢锛岄槇鍊奸�氳繃閰嶇疆鏂囦欢general.flowThreshold閰嶇疆锛涙浜嬩欢瀵瑰洖澶嶄笉鏁忔劅銆�
@@ -263,6 +272,12 @@
 		if (logger.isDebugEnabled()) {
 			logger.debug("ZLM HOOK on_server_started API璋冪敤锛屽弬鏁帮細" + json.toString());
 		}
+
+//		String data = json.getString("data");
+//		List<MediaServerConfig> mediaServerConfigs = JSON.parseArray(JSON.toJSONString(json), MediaServerConfig.class);
+//		MediaServerConfig mediaServerConfig = mediaServerConfigs.get(0);
+		MediaServerConfig mediaServerConfig = JSON.toJavaObject(json, MediaServerConfig.class);
+		storager.updateMediaInfo(mediaServerConfig);
 		// TODO Auto-generated method stub
 		
 		JSONObject ret = new JSONObject();
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 47aa362..0993c11 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
@@ -2,7 +2,12 @@
 
 import java.util.List;
 
+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.Device;
+import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
 
 /**    
  * @Description:瑙嗛璁惧鏁版嵁瀛樺偍鎺ュ彛
@@ -10,7 +15,20 @@
  * @date:   2020骞�5鏈�6鏃� 涓嬪崍2:14:31     
  */
 public interface IVideoManagerStorager {
-	
+
+	/**
+	 * 鏇存柊娴佸獟浣撲俊鎭�
+	 * @param mediaServerConfig
+	 * @return
+	 */
+	public boolean updateMediaInfo(MediaServerConfig mediaServerConfig);
+
+	/**
+	 * 鑾峰彇娴佸獟浣撲俊鎭�
+	 * @return
+	 */
+	public MediaServerConfig getMediaInfo();
+
 	/**   
 	 * 鏍规嵁璁惧ID鍒ゆ柇璁惧鏄惁瀛樺湪
 	 * 
@@ -33,7 +51,15 @@
 	 * @param device 璁惧瀵硅薄
 	 * @return true锛氬垱寤烘垚鍔�  false锛氬垱寤哄け璐�
 	 */
-	public boolean update(Device device);
+	public boolean updateDevice(Device device);
+
+	/**
+	 * 娣诲姞璁惧閫氶亾
+	 *
+	 * @param deviceId 璁惧id
+	 * @param channel 閫氶亾
+	 */
+	public void updateChannel(String deviceId, DeviceChannel channel);
 	
 	/**   
 	 * 鑾峰彇璁惧
@@ -42,15 +68,47 @@
 	 * @return DShadow 璁惧瀵硅薄
 	 */
 	public Device queryVideoDevice(String deviceId);
-	
+
+	/**
+	 * 鑾峰彇鏌愪釜璁惧鐨勯�氶亾鍒楄〃
+	 *
+	 * @param deviceId 璁惧ID
+	 * @param page 鍒嗛〉 褰撳墠椤�
+	 * @param count 姣忛〉鏁伴噺
+	 * @return
+	 */
+	public PageResult queryChannelsByDeviceId(String deviceId, int page, int count);
+
+	/**
+	 * 鑾峰彇鏌愪釜璁惧鐨勯�氶亾鍒楄〃
+	 *
+	 * @param deviceId 璁惧ID
+	 * @return
+	 */
+	public List<DeviceChannel> queryChannelsByDeviceId(String deviceId);
+	/**
+	 * 鑾峰彇鏌愪釜璁惧鐨勯�氶亾
+	 * @param deviceId 璁惧ID
+	 * @param channelId 閫氶亾ID
+	 */
+	public DeviceChannel queryChannel(String deviceId, String channelId);
+
 	/**   
 	 * 鑾峰彇澶氫釜璁惧
 	 * 
 	 * @param deviceIds 璁惧ID鏁扮粍
 	 * @return List<Device> 璁惧瀵硅薄鏁扮粍
 	 */
+	public PageResult<Device> queryVideoDeviceList(String[] deviceIds, int page, int count);
+
+	/**
+	 * 鑾峰彇澶氫釜璁惧
+	 *
+	 * @param deviceIds 璁惧ID鏁扮粍
+	 * @return List<Device> 璁惧瀵硅薄鏁扮粍
+	 */
 	public List<Device> queryVideoDeviceList(String[] deviceIds);
-	
+
 	/**   
 	 * 鍒犻櫎璁惧
 	 * 
@@ -74,4 +132,35 @@
 	 * @return true锛氭洿鏂版垚鍔�  false锛氭洿鏂板け璐�
 	 */
 	public boolean outline(String deviceId);
+
+	/**
+	 * 寮�濮嬫挱鏀炬椂灏嗘祦瀛樺叆
+	 *
+	 * @param deviceId 璁惧ID
+	 * @param channelId 閫氶亾ID
+	 * @param stream 娴佷俊鎭�
+	 * @return
+	 */
+	public boolean startPlay(String deviceId, String channelId, StreamInfo stream);
+
+	/**
+	 * 鍋滄鎾斁鏃跺垹闄�
+	 *
+	 * @param deviceId 璁惧ID
+	 * @param channelId 閫氶亾ID
+	 * @return
+	 */
+	public boolean stopPlay(String deviceId, String channelId);
+
+	/**
+	 * 鏌ユ壘瑙嗛娴�
+	 *
+	 * @param deviceId 璁惧ID
+	 * @param channelId 閫氶亾ID
+	 * @return
+	 */
+	public StreamInfo queryPlay(String deviceId, String channelId);
+
+
+
 }
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
index 59ecba0..b4e2ff9 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java
@@ -2,6 +2,10 @@
 
 import java.util.List;
 
+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;
 
@@ -17,7 +21,17 @@
 @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
@@ -40,18 +54,17 @@
 		// TODO Auto-generated method stub
 		return false;
 	}
-	
-	/**   
-	 * 瑙嗛璁惧鏇存柊
-	 * 
-	 * @param device 璁惧瀵硅薄
-	 * @return true锛氭洿鏂版垚鍔�  false锛氭洿鏂板け璐�
-	 */  
+
 	@Override
-	public boolean update(Device device) {
-		// TODO Auto-generated method stub
+	public boolean updateDevice(Device device) {
 		return false;
 	}
+
+	@Override
+	public void updateChannel(String deviceId, DeviceChannel channel) {
+
+	}
+
 
 	/**   
 	 * 鑾峰彇璁惧
@@ -62,6 +75,26 @@
 	@Override
 	public Device queryVideoDevice(String deviceId) {
 		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public PageResult queryChannelsByDeviceId(String deviceId, 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;
 	}
 
@@ -113,4 +146,19 @@
 		return false;
 	}
 
+	@Override
+	public boolean startPlay(String deviceId, String channelId, StreamInfo stream) {
+		return false;
+	}
+
+	@Override
+	public boolean stopPlay(String deviceId, String channelId) {
+		return false;
+	}
+
+	@Override
+	public StreamInfo queryPlay(String deviceId, String channelId) {
+		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
index d6e4603..8ea9f7e 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java
@@ -3,6 +3,12 @@
 import java.util.ArrayList;
 import java.util.List;
 
+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;
 
@@ -21,7 +27,8 @@
 
 	@Autowired
     private RedisUtil redis;
-	
+
+
 	/**   
 	 * 鏍规嵁璁惧ID鍒ゆ柇璁惧鏄惁瀛樺湪
 	 * 
@@ -30,7 +37,7 @@
 	 */ 
 	@Override
 	public boolean exists(String deviceId) {
-		return redis.hasKey(VideoManagerConstants.CACHEKEY_PREFIX+deviceId);
+		return redis.hasKey(VideoManagerConstants.DEVICE_PREFIX+deviceId);
 	}
 
 	/**   
@@ -41,9 +48,11 @@
 	 */ 
 	@Override
 	public boolean create(Device device) {
-		return redis.set(VideoManagerConstants.CACHEKEY_PREFIX+device.getDeviceId(), device);
+		return redis.set(VideoManagerConstants.DEVICE_PREFIX+device.getDeviceId(), device);
 	}
-	
+
+
+
 	/**   
 	 * 瑙嗛璁惧鏇存柊
 	 * 
@@ -51,8 +60,26 @@
 	 * @return true锛氭洿鏂版垚鍔�  false锛氭洿鏂板け璐�
 	 */  
 	@Override
-	public boolean update(Device device) {
-		return redis.set(VideoManagerConstants.CACHEKEY_PREFIX+device.getDeviceId(), device);
+	public boolean updateDevice(Device device) {
+		List<Object> deviceChannelList = redis.keys(VideoManagerConstants.CACHEKEY_PREFIX + device.getDeviceId() + "_" + "*");
+		// 鏇存柊device涓殑閫氶亾鏁伴噺
+		device.setChannelCount(deviceChannelList.size());
+		// 瀛樺偍device
+		return redis.set(VideoManagerConstants.DEVICE_PREFIX+device.getDeviceId(), device);
+
+
+	}
+
+	@Override
+	public void updateChannel(String deviceId, DeviceChannel channel) {
+		// 瀛樺偍閫氶亾
+		redis.set(VideoManagerConstants.CACHEKEY_PREFIX+deviceId + "_" + channel.getChannelId(),
+				channel);
+		List<Object> deviceChannelList = redis.keys(VideoManagerConstants.CACHEKEY_PREFIX + deviceId + "_" + "*");
+		// 鏇存柊device涓殑閫氶亾鏁伴噺
+		Device device = (Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceId);
+		device.setChannelCount(deviceChannelList.size());
+		redis.set(VideoManagerConstants.DEVICE_PREFIX+device.getDeviceId(), device);
 	}
 
 	/**   
@@ -63,26 +90,94 @@
 	 */  
 	@Override
 	public Device queryVideoDevice(String deviceId) {
-		return (Device)redis.get(VideoManagerConstants.CACHEKEY_PREFIX+deviceId);
+		return (Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceId);
 	}
 
-	/**   
+	@Override
+	public PageResult queryChannelsByDeviceId(String deviceId, int page, int count) {
+		List<DeviceChannel> result = new ArrayList<>();
+		PageResult pageResult = new PageResult<DeviceChannel>();
+		List<Object> deviceChannelList = redis.keys(VideoManagerConstants.CACHEKEY_PREFIX + deviceId + "_" + "*");
+		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++) {
+				result.add((DeviceChannel)redis.get((String)deviceChannelList.get(i)));
+			}
+			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 + "_" + "*");
+		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 DeviceChannel queryChannel(String deviceId, String channelId) {
+		return (DeviceChannel)redis.get(VideoManagerConstants.CACHEKEY_PREFIX + deviceId + "_" + channelId);
+	}
+
+
+	/**
 	 * 鑾峰彇澶氫釜璁惧
 	 * 
 	 * @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);
+
+		if (deviceIds == null || deviceIds.length == 0) {
+
+			List<Object> deviceIdList = redis.keys(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)));
+			}
+		} else {
+			for (int i = 0; i < deviceIds.length; i++) {
+				devices.add((Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceIds[i]));
+			}
+		}
+		pageResult.setData(devices);
+		return pageResult;
+	}
+
+	/**
+	 * 鑾峰彇澶氫釜璁惧
+	 *
+	 * @param deviceIds 璁惧ID鏁扮粍
+	 * @return List<Device> 璁惧瀵硅薄鏁扮粍
+	 */
+	@Override
 	public List<Device> queryVideoDeviceList(String[] deviceIds) {
 		List<Device> devices = new ArrayList<>();
+
 		if (deviceIds == null || deviceIds.length == 0) {
-			List<Object> deviceIdList = redis.keys(VideoManagerConstants.CACHEKEY_PREFIX+"*");
+			List<Object> deviceIdList = redis.keys(VideoManagerConstants.DEVICE_PREFIX+"*");
 			for (int i = 0; i < deviceIdList.size(); i++) {
 				devices.add((Device)redis.get((String)deviceIdList.get(i)));
 			}
 		} else {
 			for (int i = 0; i < deviceIds.length; i++) {
-				devices.add((Device)redis.get(VideoManagerConstants.CACHEKEY_PREFIX+deviceIds[i]));
+				devices.add((Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceIds[i]));
 			}
 		}
 		return devices;
@@ -96,7 +191,7 @@
 	 */  
 	@Override
 	public boolean delete(String deviceId) {
-		return redis.del(VideoManagerConstants.CACHEKEY_PREFIX+deviceId);
+		return redis.del(VideoManagerConstants.DEVICE_PREFIX+deviceId);
 	}
 
 	/**   
@@ -107,9 +202,9 @@
 	 */ 
 	@Override
 	public boolean online(String deviceId) {
-		Device device = (Device)redis.get(VideoManagerConstants.CACHEKEY_PREFIX+deviceId);
+		Device device = (Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceId);
 		device.setOnline(1);
-		return redis.set(VideoManagerConstants.CACHEKEY_PREFIX+device.getDeviceId(), device);
+		return redis.set(VideoManagerConstants.DEVICE_PREFIX+device.getDeviceId(), device);
 	}
 
 	/**   
@@ -120,9 +215,64 @@
 	 */ 
 	@Override
 	public boolean outline(String deviceId) {
-		Device device = (Device)redis.get(VideoManagerConstants.CACHEKEY_PREFIX+deviceId);
+		Device device = (Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceId);
+		if (device == null) return false;
 		device.setOnline(0);
-		return redis.set(VideoManagerConstants.CACHEKEY_PREFIX+device.getDeviceId(), device);
+		return redis.set(VideoManagerConstants.DEVICE_PREFIX+device.getDeviceId(), device);
 	}
-	
+
+	/**
+	 * 寮�濮嬫挱鏀炬椂灏嗘祦瀛樺叆redis
+	 *
+	 * @param deviceId 璁惧ID
+	 * @param channelId 閫氶亾ID
+	 * @return
+	 */
+	@Override
+	public boolean startPlay(String deviceId, String channelId, StreamInfo stream) {
+		return redis.set(String.format("%S_%s_%s", VideoManagerConstants.PLAYER_PREFIX, deviceId, channelId),
+				stream);
+	}
+
+	/**
+	 * 鍋滄鎾斁鏃朵粠redis鍒犻櫎
+	 *
+	 * @param deviceId 璁惧ID
+	 * @param channelId 閫氶亾ID
+	 * @return
+	 */
+	@Override
+	public boolean stopPlay(String deviceId, String channelId) {
+		return redis.del(String.format("%S_%s_%s", VideoManagerConstants.PLAYER_PREFIX, deviceId, channelId));
+	}
+
+	/**
+	 * 鏌ヨ鎾斁鍒楄〃
+	 * @param deviceId 璁惧ID
+	 * @param channelId 閫氶亾ID
+	 * @return
+	 */
+	@Override
+	public StreamInfo queryPlay(String deviceId, String channelId) {
+		return (StreamInfo)redis.get(String.format("%S_%s_%s", VideoManagerConstants.PLAYER_PREFIX, deviceId, channelId));
+	}
+
+	/**
+	 * 鏇存柊娴佸獟浣撲俊鎭�
+	 * @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);
+	}
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java b/src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java
index f1d1673..463d942 100644
--- a/src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java
+++ b/src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java
@@ -8,6 +8,7 @@
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ZSetOperations;
 import org.springframework.stereotype.Component;
 import org.springframework.util.CollectionUtils;
 
@@ -389,6 +390,121 @@
             return 0;
         }
     }
+//    ============================== ZSet ==============================
+
+    /**
+     * 娣诲姞涓�涓厓绱�, zset涓巗et鏈�澶х殑鍖哄埆灏辨槸姣忎釜鍏冪礌閮芥湁涓�涓猻core锛屽洜姝ゆ湁涓帓搴忕殑杈呭姪鍔熻兘;  zadd
+     *
+     * @param key
+     * @param value
+     * @param score
+     */
+    public void zAdd(String key, String value, double score) {
+        redisTemplate.opsForZSet().add(key, value, score);
+    }
+
+    /**
+     * 鍒犻櫎鍏冪礌 zrem
+     *
+     * @param key
+     * @param value
+     */
+    public void zRemove(String key, String value) {
+        redisTemplate.opsForZSet().remove(key, value);
+    }
+
+    /**
+     * score鐨勫鍔爋r鍑忓皯 zincrby
+     *
+     * @param key
+     * @param value
+     * @param score
+     */
+    public Double zIncrScore(String key, String value, double score) {
+        return redisTemplate.opsForZSet().incrementScore(key, value, score);
+    }
+
+    /**
+     * 鏌ヨvalue瀵瑰簲鐨剆core   zscore
+     *
+     * @param key
+     * @param value
+     * @return
+     */
+    public Double zScore(String key, String value) {
+        return redisTemplate.opsForZSet().score(key, value);
+    }
+
+    /**
+     * 鍒ゆ柇value鍦▃set涓殑鎺掑悕  zrank
+     *
+     * @param key
+     * @param value
+     * @return
+     */
+    public Long zRank(String key, String value) {
+        return redisTemplate.opsForZSet().rank(key, value);
+    }
+
+    /**
+     * 杩斿洖闆嗗悎鐨勯暱搴�
+     *
+     * @param key
+     * @return
+     */
+    public Long zSize(String key) {
+        return redisTemplate.opsForZSet().zCard(key);
+    }
+
+    /**
+     * 鏌ヨ闆嗗悎涓寚瀹氶『搴忕殑鍊硷紝 0 -1 琛ㄧず鑾峰彇鍏ㄩ儴鐨勯泦鍚堝唴瀹�  zrange
+     *
+     * 杩斿洖鏈夊簭鐨勯泦鍚堬紝score灏忕殑鍦ㄥ墠闈�
+     *
+     * @param key
+     * @param start
+     * @param end
+     * @return
+     */
+    public Set<String> ZRange(String key, int start, int end) {
+        return redisTemplate.opsForZSet().range(key, start, end);
+    }
+    /**
+     * 鏌ヨ闆嗗悎涓寚瀹氶『搴忕殑鍊煎拰score锛�0, -1 琛ㄧず鑾峰彇鍏ㄩ儴鐨勯泦鍚堝唴瀹�
+     *
+     * @param key
+     * @param start
+     * @param end
+     * @return
+     */
+    public Set<ZSetOperations.TypedTuple<String>> zRangeWithScore(String key, int start, int end) {
+        return redisTemplate.opsForZSet().rangeWithScores(key, start, end);
+    }
+    /**
+     * 鏌ヨ闆嗗悎涓寚瀹氶『搴忕殑鍊�  zrevrange
+     *
+     * 杩斿洖鏈夊簭鐨勯泦鍚堜腑锛宻core澶х殑鍦ㄥ墠闈�
+     *
+     * @param key
+     * @param start
+     * @param end
+     * @return
+     */
+    public Set<String> zRevRange(String key, int start, int end) {
+        return redisTemplate.opsForZSet().reverseRange(key, start, end);
+    }
+    /**
+     * 鏍规嵁score鐨勫�硷紝鏉ヨ幏鍙栨弧瓒虫潯浠剁殑闆嗗悎  zrangebyscore
+     *
+     * @param key
+     * @param min
+     * @param max
+     * @return
+     */
+    public Set<String> zSortRange(String key, int min, int max) {
+        return redisTemplate.opsForZSet().rangeByScore(key, min, max);
+    }
+
 
 //    ============================== List ==============================
 
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/device/DeviceController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/device/DeviceController.java
index 6368f82..9b229ac 100644
--- a/src/main/java/com/genersoft/iot/vmp/vmanager/device/DeviceController.java
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/device/DeviceController.java
@@ -2,6 +2,8 @@
 
 import java.util.List;
 
+import com.genersoft.iot.vmp.common.PageResult;
+import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -53,14 +55,30 @@
 	}
 	
 	@GetMapping("/devices")
-	public ResponseEntity<List<Device>> devices(){
+	public PageResult<Device> devices(int page, int count){
 		
 		if (logger.isDebugEnabled()) {
 			logger.debug("鏌ヨ鎵�鏈夎棰戣澶嘇PI璋冪敤");
 		}
 		
-		List<Device> deviceList = storager.queryVideoDeviceList(null);
-		return new ResponseEntity<>(deviceList,HttpStatus.OK);
+		return storager.queryVideoDeviceList(null, page, count);
+	}
+
+	/**
+	 * 鍒嗛〉鏌ヨ閫氶亾鏁�
+	 * @param deviceId 璁惧id
+	 * @param page 褰撳墠椤�
+	 * @param count 姣忛〉鏉℃暟
+	 * @return 閫氶亾鍒楄〃
+	 */
+	@GetMapping("devices/{deviceId}/channels")
+	public ResponseEntity<PageResult> channels(@PathVariable String deviceId, int page, int count){
+
+		if (logger.isDebugEnabled()) {
+			logger.debug("鏌ヨ鎵�鏈夎棰戣澶嘇PI璋冪敤");
+		}
+		PageResult pageResult = storager.queryChannelsByDeviceId(deviceId, page, count);
+		return new ResponseEntity<>(pageResult,HttpStatus.OK);
 	}
 	
 	@PostMapping("/devices/{deviceId}/sync")
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 c0d2233..0c4ab63 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
@@ -1,5 +1,6 @@
 package com.genersoft.iot.vmp.vmanager.play;
 
+import com.genersoft.iot.vmp.common.StreamInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -34,16 +35,16 @@
 	public ResponseEntity<String> play(@PathVariable String deviceId,@PathVariable String channelId){
 		
 		Device device = storager.queryVideoDevice(deviceId);
-		String ssrc = cmder.playStreamCmd(device, channelId);
+		StreamInfo streamInfo = cmder.playStreamCmd(device, channelId);
 		
 		if (logger.isDebugEnabled()) {
 			logger.debug(String.format("璁惧棰勮 API璋冪敤锛宒eviceId锛�%s 锛宑hannelId锛�%s",deviceId, channelId));
-			logger.debug("璁惧棰勮 API璋冪敤锛宻src锛�"+ssrc+",ZLMedia streamId:"+Integer.toHexString(Integer.parseInt(ssrc)));
+			logger.debug("璁惧棰勮 API璋冪敤锛宻src锛�"+streamInfo.getSsrc()+",ZLMedia streamId:"+Integer.toHexString(Integer.parseInt(streamInfo.getSsrc())));
 		}
 		
-		if(ssrc!=null) {
+		if(streamInfo!=null) {
 			JSONObject json = new JSONObject();
-			json.put("ssrc", ssrc);
+			json.put("ssrc", streamInfo.getSsrc());
 			return new ResponseEntity<String>(json.toString(),HttpStatus.OK);
 		} else {
 			logger.warn("璁惧棰勮API璋冪敤澶辫触锛�");
diff --git a/src/main/java/com/genersoft/iot/vmp/web/AuthController.java b/src/main/java/com/genersoft/iot/vmp/web/AuthController.java
new file mode 100644
index 0000000..50e4da1
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/web/AuthController.java
@@ -0,0 +1,30 @@
+package com.genersoft.iot.vmp.web;
+
+import com.genersoft.iot.vmp.gb28181.bean.Device;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+
+@CrossOrigin
+@RestController
+@RequestMapping(value = "/auth")
+public class AuthController {
+
+    @Value("${auth.username}")
+    private String username;
+
+    @Value("${auth.password}")
+    private String password;
+
+    @RequestMapping("/login")
+    public Object devices(String username, String password){
+        if (!StringUtils.isEmpty(username) && username.equals(username)
+                && !StringUtils.isEmpty(password) && password.equals(password)) {
+            return "success";
+        }else {
+            return "fait";
+        }
+    }
+}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 7e6bc40..2784ace 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -7,27 +7,26 @@
         communicate: http
     redis: 
         # Redis鏈嶅姟鍣↖P
-        #host: 10.24.20.63
-        host: 127.0.0.1
+        host: 192.168.1.141
         #绔彛鍙�
         port: 6379
-        datebase: 0
+        database: 6
         #璁块棶瀵嗙爜,鑻ヤ綘鐨剅edis鏈嶅姟鍣ㄦ病鏈夎缃瘑鐮侊紝灏变笉闇�瑕佺敤瀵嗙爜鍘昏繛鎺�
-        password:
+        password: 4767cb971b40a1300fa09b7f87b09d1c
         #瓒呮椂鏃堕棿
         timeout: 10000
     datasource: 
         name: eiot
-        url: jdbc:mysql://10.24.20.63:3306/eiot?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true
+        url: jdbc:mysql://192.168.1.141:3306/eiot?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true
         username: root
-        password: 123456
+        password: root
         type: com.alibaba.druid.pool.DruidDataSource
         driver-class-name: com.mysql.jdbc.Driver
 server:
-    port: 8080
+    port: 18080
 sip:
 #   ip: 10.200.64.63
-    ip: 192.168.0.102
+    ip: 192.168.1.20
     port: 5060
     # 鏍规嵁鍥芥爣6.1.2涓瀹氾紝domain瀹滈噰鐢↖D缁熶竴缂栫爜鐨勫墠鍗佷綅缂栫爜銆傚浗鏍囬檮褰旸涓畾涔夊墠8浣嶄负涓績缂栫爜锛堢敱鐪佺骇銆佸競绾с�佸尯绾с�佸熀灞傜紪鍙风粍鎴愶紝鍙傜収GB/T 2260-2007锛�
     # 鍚庝袱浣嶄负琛屼笟缂栫爜锛屽畾涔夊弬鐓ч檮褰旸.3
@@ -35,8 +34,19 @@
     domain: 3701020049
     id: 37010200492000000001
     # 榛樿璁惧璁よ瘉瀵嗙爜锛屽悗缁墿灞曚娇鐢ㄨ澶囧崟鐙瘑鐮�
-    password: admin123
+    password: 12345678
 media:
 #   ip: 10.200.64.88
-    ip: 192.168.0.102
-    port: 10000
\ No newline at end of file
+    ip: 192.168.1.20
+    port: 10000
+
+# 鑷畾涔変唬鐞嗙浉鍏抽厤缃�
+# 浠g悊鐨勬湰鍦拌矾鐢�
+proxy:
+     servlet_url: /media/*
+        # 瑕佷唬鐞嗙殑鍦板潃
+     target_url: http://127.0.0.1:10080
+
+auth: #32浣嶅皬鍐檓d5鍔犲瘑锛堥粯璁ゅ瘑鐮佷负admin锛�
+    username: admin
+    password: 21232f297a57a5a743894a0e4a801fc3
\ No newline at end of file

--
Gitblit v1.8.0