Przeglądaj źródła

招商大屏3*3定制

zhangqiankun 3 lat temu
rodzic
commit
a451f11bd8

+ 62 - 1
src/main/java/com/persagy/cameractl/controller/HelloController.java

@@ -3,11 +3,20 @@ package com.persagy.cameractl.controller;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -15,6 +24,9 @@ import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.bind.annotation.RestController;
 
+import com.alibaba.fastjson.JSONObject;
+import com.persagy.cameractl.cache.SceneConfigCache;
+import com.persagy.cameractl.model.NvrSceneRelation;
 import com.persagy.cameractl.model.SceneConfig;
 import com.persagy.cameractl.service.PtzMain;
 import com.persagy.cameractl.service.windows.Nvr9CameraExecuteApi;
@@ -98,7 +110,56 @@ public class HelloController {
 		}
 	}
 	
-    /*
+	/**
+	 * 获取场景
+	 * 
+	 * @param request
+	 * @return
+	 * @date 2021年11月4日 下午12:11:52
+	 */
+    @GetMapping(value = "/config/{oper}")
+    public Map<String, Object> scene(@PathVariable("oper") String oper) {
+    	Map<String, Object> result = new HashMap<String, Object>();
+    	result.put(ResultTools.key_result, ResultTools.result_success);
+    	
+    	List<Object> dataList = new ArrayList<Object>();
+    	
+    	Map<String, NvrSceneRelation> sceneConfig = SceneConfigCache.SCENE_CONFIG;
+    	Set<Entry<String,NvrSceneRelation>> entrySet = sceneConfig.entrySet();
+    	Iterator<Entry<String, NvrSceneRelation>> iterator = entrySet.iterator();
+    	
+    	switch (oper) {
+		case "scene":
+			Set<String> temp = new HashSet<String>();
+			while (iterator.hasNext()) {
+				Entry<String, NvrSceneRelation> next = iterator.next();
+				NvrSceneRelation sceneRelation = next.getValue();
+				
+				String key = sceneRelation.getGroup() + "_" + sceneRelation.getScene();
+				if (!temp.contains(key)) {
+					JSONObject jsonObject = new JSONObject();
+					jsonObject.put("group", sceneRelation.getGroup());
+					jsonObject.put("scene", sceneRelation.getScene());
+					dataList.add(jsonObject);
+					temp.add(key);
+				}
+			}
+			break;
+		case "json":
+	    	while (iterator.hasNext()) {
+				Entry<String, NvrSceneRelation> next = iterator.next();
+				dataList.add(next.getValue());
+			}
+			break;
+		default:
+			break;
+		}
+    	
+    	result.put(ResultTools.key_data, dataList);
+    	return result;
+    }
+	
+    /**
      * 调用软件平台接口,根据摄像头监控点位获取预览流url、回放流url、云台控制
      * operType: preview 预览	playback 回放	control 云台控制	other 支持传入接口名称和参数,方便调试	tvwall 获取视频墙列表
      * 		tvwalllayout 获取某个视频墙的布局	toup 投屏,即上墙操作	exittoup 退出投屏

+ 2 - 1
src/main/java/com/persagy/cameractl/model/Channel.java

@@ -45,6 +45,7 @@ public class Channel {
 	/** 摄像头信息集合 */
 	private List<Camera> cameras;
 	
-	
+	/** 单摄像头信息 */
+	private Camera camera;
 	
 }

+ 3 - 0
src/main/java/com/persagy/cameractl/model/SceneConfig.java

@@ -28,6 +28,9 @@ public class SceneConfig {
 	/** 通道集合 */
 	private List<Channel> channels;
 	
+	/** 摄像头集合 */
+	private List<Channel> cameras;
+	
 	private NvrSceneRelation nvrSceneRelation;
 	
 }

+ 6 - 1
src/main/java/com/persagy/cameractl/service/socket/TclSocketClient.java

@@ -35,7 +35,8 @@ public class TclSocketClient {
 		BS.group(GROUP).channel(NioSocketChannel.class);
 	}
 	
-	public static void connectAndSend(String host, int port, String command) {
+	public static boolean connectAndSend(String host, int port, String command) {
+		boolean result = false;
 		ChannelFuture cf = null;
 		try {
 			BS.remoteAddress(new InetSocketAddress(host, port)) // 绑定连接端口和host信息
@@ -51,6 +52,8 @@ public class TclSocketClient {
 
 			cf = BS.connect().sync(); // 异步连接服务器
 			log.info("服务端连接成功...");
+			
+			result = true;
 		} catch (Exception e) {
 			log.error("与服务端建立连接失败", e);
 		} finally {
@@ -63,6 +66,8 @@ public class TclSocketClient {
 				}
 			}
 		}
+		
+		return result;
 	}
 
 	public static void main(String[] args) throws Exception {

+ 82 - 95
src/main/java/com/persagy/cameractl/service/windows/Nvr9CameraExecuteApi.java

@@ -27,12 +27,12 @@ import com.persagy.vsknet.tmp.SERVER_URI;
 import com.sun.jna.platform.win32.WinDef;
 import com.sun.jna.platform.win32.WinDef.UINT;
 
-import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.util.BooleanUtil;
 import cn.hutool.core.util.StrUtil;
 import lombok.extern.slf4j.Slf4j;
 
 /**
+ * 定制 3*4布局
  * 
  * @version 1.0.0
  * @company persagy 
@@ -57,9 +57,9 @@ public class Nvr9CameraExecuteApi {
 			return this.executeErr(false, null, "非法场景参数");
 		}
 		
-		TclSocketClient.connectAndSend(NVR9Config.tclIp, NVR9Config.tclPort, 
+		boolean send = TclSocketClient.connectAndSend(NVR9Config.tclIp, NVR9Config.tclPort, 
 				StrUtil.format(TclSocketClient.COMMAND, sceneConfig.getGroup(), sceneConfig.getScene()));
-		return this.executeSuccess(false, "场景已切换");
+		return send ? OtherTools.executeSuccess("场景已切换") : OtherTools.executeErr("场景切换失败");
 	}
 	
 	/**
@@ -70,8 +70,8 @@ public class Nvr9CameraExecuteApi {
 	 * @date 2021年10月27日 下午6:01:31
 	 */
 	public ResultClass lunx(SceneConfig sceneConfig) {
-		List<Channel> channels = sceneConfig.getChannels();
-		for (Channel channel : channels) {
+		List<Channel> cameras = sceneConfig.getCameras();
+		for (Channel channel : cameras) {
 			int windowId = channel.getWindowId();
 			byte nweek = channel.getNweek();
 			int ntimeindex = channel.getNtimeindex();
@@ -89,45 +89,38 @@ public class Nvr9CameraExecuteApi {
 			DecCircleStrateryEx decStratery = new DecCircleStrateryEx();
 			if (nweek == 7) {
 				for (int i = 0; i < nweek; i++) {
-					if (CollectionUtil.isEmpty(channels)) {
-						continue;
-					}
-					
-					List<Camera> cameras = channel.getCameras();
-					for (int j = 0; j < cameras.size(); j++) {
-						Camera camera = cameras.get(j);
-						int wChanUsed = camera.getWChanUsed();
-						byte streamType = camera.getStreamType();
+					Camera camera = channel.getCamera();
+					int wChanUsed = camera.getWChanUsed();
+					byte streamType = camera.getStreamType();
 
-						// 用户
-						decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].Ipclogin.username = camera.getUsername().getBytes();
-						decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].Ipclogin.password = camera.getPassword().getBytes();
-						
-						// 通道
-						decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.ip = camera.getIp().getBytes();
-						decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.port = camera.getPort();
-						decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.wChanUsed = wChanUsed;
-						if (streamType == 0) {
-							decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.mediaStream.stream_uri = camera.getStreamUri().getBytes();
-							decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.mediaStream.uri_size = camera.getUriSize();
-						} else {
-							decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.device_addrs = camera.getDeviceAddrs().getBytes();
-						}
-						
-						decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.frameRate = camera.getFrameRate();
-						decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.streamType = streamType;
-						decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.deviceType = 0;
-						//decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.channelID = channel.getChannelID();
-						//decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.manufacterID = IPC_MACHINE_TYPE.ONVIF_PROTOCOL;
-						decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.manufacturer = camera.getManufactername().getBytes();
-						decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.model = camera.getModel().getBytes();
-						
-						// nUser
-						decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].nUser = (wChanUsed << 16 | windowId);
+					// 用户
+					decStratery.DecCircleStrateryChl[i][index].ChlInfo[0].Ipclogin.username = camera.getUsername().getBytes();
+					decStratery.DecCircleStrateryChl[i][index].ChlInfo[0].Ipclogin.password = camera.getPassword().getBytes();
+					
+					// 通道
+					decStratery.DecCircleStrateryChl[i][index].ChlInfo[0].ipc.ip = camera.getIp().getBytes();
+					decStratery.DecCircleStrateryChl[i][index].ChlInfo[0].ipc.port = camera.getPort();
+					decStratery.DecCircleStrateryChl[i][index].ChlInfo[0].ipc.wChanUsed = wChanUsed;
+					if (streamType == 0) {
+						decStratery.DecCircleStrateryChl[i][index].ChlInfo[0].ipc.mediaStream.stream_uri = camera.getStreamUri().getBytes();
+						decStratery.DecCircleStrateryChl[i][index].ChlInfo[0].ipc.mediaStream.uri_size = camera.getUriSize();
+					} else {
+						decStratery.DecCircleStrateryChl[i][index].ChlInfo[0].ipc.device_addrs = camera.getDeviceAddrs().getBytes();
 					}
-
+					
+					decStratery.DecCircleStrateryChl[i][index].ChlInfo[0].ipc.frameRate = camera.getFrameRate();
+					decStratery.DecCircleStrateryChl[i][index].ChlInfo[0].ipc.streamType = streamType;
+					decStratery.DecCircleStrateryChl[i][index].ChlInfo[0].ipc.deviceType = 0;
+					//decStratery.DecCircleStrateryChl[i][index].ChlInfo[0].ipc.channelID = channel.getChannelID();
+					//decStratery.DecCircleStrateryChl[i][index].ChlInfo[0].ipc.manufacterID = IPC_MACHINE_TYPE.ONVIF_PROTOCOL;
+					decStratery.DecCircleStrateryChl[i][index].ChlInfo[0].ipc.manufacturer = camera.getManufactername().getBytes();
+					decStratery.DecCircleStrateryChl[i][index].ChlInfo[0].ipc.model = camera.getModel().getBytes();
+					
+					// nUser
+					decStratery.DecCircleStrateryChl[i][index].ChlInfo[0].nUser = (wChanUsed << 16 | windowId);
+					
 					decStratery.DecCircleStrateryChl[i][index].nchanggeTime = channel.getNchanggeTime();
-					decStratery.DecCircleStrateryChl[i][index].nChlNum = cameras.size();
+					decStratery.DecCircleStrateryChl[i][index].nChlNum = 1;
 					decStratery.DecCircleStrateryChl[i][index].nTimeId = ntimeindex;
 					decStratery.DecCircleStrateryChl[i][index].nwinnum = channel.getNwndnumber();
 					decStratery.DecCircleStrateryChl[i][index].uistarttime = channel.getUlstarttime();
@@ -262,63 +255,57 @@ public class Nvr9CameraExecuteApi {
 			
 			int errCode = -1;
 			Boolean result = null;
-			List<Camera> cameras = channel.getCameras();
-			for (int i = 0; i < cameras.size(); i++) {
-				errCode = -1;
-				result = null;
-				
-				Camera camera = cameras.get(i);
-				int wChanUsed = camera.getWChanUsed();
-				byte streamType = camera.getStreamType();
+			Camera camera = channel.getCamera();
+			int wChanUsed = camera.getWChanUsed();
+			byte streamType = camera.getStreamType();
 
-				// 用户
-				IPC_ArrayEx IPC_ArrayEx = new IPC_ArrayEx();
-				IPC_ArrayEx.Ipclogin.username = camera.getUsername().getBytes();
-				IPC_ArrayEx.Ipclogin.password = camera.getPassword().getBytes();
-				
-				// 通道
-				IPC_ArrayEx.ipc.ip = camera.getIp().getBytes();
-				IPC_ArrayEx.ipc.port = camera.getPort();
-				IPC_ArrayEx.ipc.wChanUsed = wChanUsed;
-				if (streamType == 0) {
-					IPC_ArrayEx.ipc.mediaStream.stream_uri = camera.getStreamUri().getBytes();
-					IPC_ArrayEx.ipc.mediaStream.uri_size = camera.getUriSize();
-				} else {
-					IPC_ArrayEx.ipc.device_addrs = camera.getDeviceAddrs().getBytes();
-				}
-				
-				IPC_ArrayEx.ipc.frameRate = camera.getFrameRate();
-				IPC_ArrayEx.ipc.streamType = streamType;
-				IPC_ArrayEx.ipc.deviceType = 0;
-				//IPC_ArrayEx.ipc.channelID = channel.getChannelID();
-				//IPC_ArrayEx.ipc.manufacterID = IPC_MACHINE_TYPE.ONVIF_AXIS;
-				IPC_ArrayEx.ipc.manufacturer = camera.getManufactername().getBytes();
-				IPC_ArrayEx.ipc.model = camera.getModel().getBytes();
-				
-				// nUser
-				IPC_ArrayEx.nUser = (wChanUsed << 16) + windowId;	// 添加到的通道号与窗口号
-				
-				// 删除通道预览
-				DECV2_PROTO_IPC deletePreview = new DECV2_PROTO_IPC();
-				deletePreview.proHead.master = sdkChannelId;		//输出屏号从0开始
-				deletePreview.proHead.dataLen = IPC_ArrayEx.size();
-				result = NVR9Config.vskDevNet.NS_NET_SetNVRConfig(login_id, new WinDef.UINT(142), new WinDef.LONG(1), 
+			// 用户
+			IPC_ArrayEx IPC_ArrayEx = new IPC_ArrayEx();
+			IPC_ArrayEx.Ipclogin.username = camera.getUsername().getBytes();
+			IPC_ArrayEx.Ipclogin.password = camera.getPassword().getBytes();
+			
+			// 通道
+			IPC_ArrayEx.ipc.ip = camera.getIp().getBytes();
+			IPC_ArrayEx.ipc.port = camera.getPort();
+			IPC_ArrayEx.ipc.wChanUsed = wChanUsed;
+			if (streamType == 0) {
+				IPC_ArrayEx.ipc.mediaStream.stream_uri = camera.getStreamUri().getBytes();
+				IPC_ArrayEx.ipc.mediaStream.uri_size = camera.getUriSize();
+			} else {
+				IPC_ArrayEx.ipc.device_addrs = camera.getDeviceAddrs().getBytes();
+			}
+			
+			IPC_ArrayEx.ipc.frameRate = camera.getFrameRate();
+			IPC_ArrayEx.ipc.streamType = streamType;
+			IPC_ArrayEx.ipc.deviceType = 0;
+			//IPC_ArrayEx.ipc.channelID = channel.getChannelID();
+			//IPC_ArrayEx.ipc.manufacterID = IPC_MACHINE_TYPE.ONVIF_AXIS;
+			IPC_ArrayEx.ipc.manufacturer = camera.getManufactername().getBytes();
+			IPC_ArrayEx.ipc.model = camera.getModel().getBytes();
+			
+			// nUser
+			IPC_ArrayEx.nUser = (wChanUsed << 16) + windowId;	// 添加到的通道号与窗口号
+			
+			// 删除通道预览
+			DECV2_PROTO_IPC deletePreview = new DECV2_PROTO_IPC();
+			deletePreview.proHead.master = sdkChannelId;		//输出屏号从0开始
+			deletePreview.proHead.dataLen = IPC_ArrayEx.size();
+			result = NVR9Config.vskDevNet.NS_NET_SetNVRConfig(login_id, new WinDef.UINT(142), new WinDef.LONG(1), 
+					deletePreview.getPointer(), new WinDef.UINT(deletePreview.size()));
+			if (BooleanUtil.isTrue(result)) {
+				// 添加通道预览
+				DECV2_PROTO_IPC updatePreview = new DECV2_PROTO_IPC();
+				updatePreview.proHead.master = sdkChannelId;	//输出屏号从0开始
+				updatePreview.proHead.dataLen = IPC_ArrayEx.size();
+				result = NVR9Config.vskDevNet.NS_NET_SetNVRConfig(login_id, new WinDef.UINT(141), new WinDef.LONG(1), 
 						deletePreview.getPointer(), new WinDef.UINT(deletePreview.size()));
-				if (BooleanUtil.isTrue(result)) {
-					// 添加通道预览
-					DECV2_PROTO_IPC updatePreview = new DECV2_PROTO_IPC();
-					updatePreview.proHead.master = sdkChannelId;	//输出屏号从0开始
-					updatePreview.proHead.dataLen = IPC_ArrayEx.size();
-					result = NVR9Config.vskDevNet.NS_NET_SetNVRConfig(login_id, new WinDef.UINT(141), new WinDef.LONG(1), 
-							deletePreview.getPointer(), new WinDef.UINT(deletePreview.size()));
-					if (!BooleanUtil.isTrue(result)) {
-						errCode = NVR9Config.getErrCode();
-						log.warn("添加通道预览失败,错误码: " + errCode);
-					}
-				} else {
+				if (!BooleanUtil.isTrue(result)) {
 					errCode = NVR9Config.getErrCode();
-					log.warn("删除通道预览失败,错误码: " + errCode);
+					log.warn("添加通道预览失败,错误码: " + errCode);
 				}
+			} else {
+				errCode = NVR9Config.getErrCode();
+				log.warn("删除通道预览失败,错误码: " + errCode);
 			}
 			
 			// 退出登录
@@ -328,7 +315,7 @@ public class Nvr9CameraExecuteApi {
 			}
 		}
 		
-		return this.executeSuccess(false, "添加通道预览配置成功");
+		return this.executeSuccess(false, "投屏操作成功");
 	}
 
 	

+ 502 - 0
src/main/java/com/persagy/cameractl/service/windows/Nvr9CameraExecuteApiBak.java

@@ -0,0 +1,502 @@
+package com.persagy.cameractl.service.windows;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.persagy.cameractl.cache.SceneConfigCache;
+import com.persagy.cameractl.conf.NVR9Config;
+import com.persagy.cameractl.model.Camera;
+import com.persagy.cameractl.model.Channel;
+import com.persagy.cameractl.model.NvrSceneRelation;
+import com.persagy.cameractl.model.SceneConfig;
+import com.persagy.cameractl.service.socket.TclSocketClient;
+import com.persagy.cameractl.utils.OtherTools;
+import com.persagy.cameractl.utils.ResultClass;
+import com.persagy.vsknet.structure.CurShowDevEx;
+import com.persagy.vsknet.structure.DECV2_PROTO_DecCircleStrateryEx;
+import com.persagy.vsknet.structure.DECV2_PROTO_HEADER_T;
+import com.persagy.vsknet.structure.DECV2_PROTO_IPC;
+import com.persagy.vsknet.structure.DecCircleStrateryEx;
+import com.persagy.vsknet.structure.DecCircleTimeEx;
+import com.persagy.vsknet.structure.IPC_ArrayEx;
+import com.persagy.vsknet.tmp.AUTHORIZATION;
+import com.persagy.vsknet.tmp.SERVER_URI;
+import com.sun.jna.platform.win32.WinDef;
+import com.sun.jna.platform.win32.WinDef.UINT;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.BooleanUtil;
+import cn.hutool.core.util.StrUtil;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 支持屏中画面嵌套 
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年10月12日 上午11:03:13
+ */
+@Slf4j
+public class Nvr9CameraExecuteApiBak {
+	
+	/** 当前登陆者 */
+	private UINT login_id;
+	
+	/**
+	 * 切换场景
+	 * 
+	 * @param sceneConfig
+	 * @return
+	 * @date 2021年10月27日 下午6:01:38
+	 */
+	public ResultClass transitionScene(SceneConfig sceneConfig) {
+		if (sceneConfig.getGroup() <= 0 || sceneConfig.getScene() <= 0) {
+			return this.executeErr(false, null, "非法场景参数");
+		}
+		
+		TclSocketClient.connectAndSend(NVR9Config.tclIp, NVR9Config.tclPort, 
+				StrUtil.format(TclSocketClient.COMMAND, sceneConfig.getGroup(), sceneConfig.getScene()));
+		return this.executeSuccess(false, "场景已切换");
+	}
+	
+	/**
+	 * 轮询设置
+	 * 
+	 * @param sceneConfig
+	 * @return
+	 * @date 2021年10月27日 下午6:01:31
+	 */
+	public ResultClass lunx(SceneConfig sceneConfig) {
+		List<Channel> channels = sceneConfig.getChannels();
+		for (Channel channel : channels) {
+			int windowId = channel.getWindowId();
+			byte nweek = channel.getNweek();
+			int ntimeindex = channel.getNtimeindex();
+			int index = ntimeindex - 1;
+			byte noutputscreenno = channel.getNoutputscreenno();
+			
+			// 登录
+			NvrSceneRelation relation = SceneConfigCache.SCENE_CONFIG.get(SceneConfigCache.getCacheKey(sceneConfig.getGroup(), sceneConfig.getScene(), windowId));
+			//byte sdkChannelId = relation.getSdkChannelId();
+			boolean initAndLoginNVR9 = this.login(relation);
+			if (!initAndLoginNVR9) {
+				return this.executeErr(false, null, "登录失败");
+			}
+			
+			DecCircleStrateryEx decStratery = new DecCircleStrateryEx();
+			if (nweek == 7) {
+				for (int i = 0; i < nweek; i++) {
+					if (CollectionUtil.isEmpty(channels)) {
+						continue;
+					}
+					
+					List<Camera> cameras = channel.getCameras();
+					for (int j = 0; j < cameras.size(); j++) {
+						Camera camera = cameras.get(j);
+						int wChanUsed = camera.getWChanUsed();
+						byte streamType = camera.getStreamType();
+
+						// 用户
+						decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].Ipclogin.username = camera.getUsername().getBytes();
+						decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].Ipclogin.password = camera.getPassword().getBytes();
+						
+						// 通道
+						decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.ip = camera.getIp().getBytes();
+						decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.port = camera.getPort();
+						decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.wChanUsed = wChanUsed;
+						if (streamType == 0) {
+							decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.mediaStream.stream_uri = camera.getStreamUri().getBytes();
+							decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.mediaStream.uri_size = camera.getUriSize();
+						} else {
+							decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.device_addrs = camera.getDeviceAddrs().getBytes();
+						}
+						
+						decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.frameRate = camera.getFrameRate();
+						decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.streamType = streamType;
+						decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.deviceType = 0;
+						//decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.channelID = channel.getChannelID();
+						//decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.manufacterID = IPC_MACHINE_TYPE.ONVIF_PROTOCOL;
+						decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.manufacturer = camera.getManufactername().getBytes();
+						decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].ipc.model = camera.getModel().getBytes();
+						
+						// nUser
+						decStratery.DecCircleStrateryChl[i][index].ChlInfo[j].nUser = (wChanUsed << 16 | windowId);
+					}
+
+					decStratery.DecCircleStrateryChl[i][index].nchanggeTime = channel.getNchanggeTime();
+					decStratery.DecCircleStrateryChl[i][index].nChlNum = cameras.size();
+					decStratery.DecCircleStrateryChl[i][index].nTimeId = ntimeindex;
+					decStratery.DecCircleStrateryChl[i][index].nwinnum = channel.getNwndnumber();
+					decStratery.DecCircleStrateryChl[i][index].uistarttime = channel.getUlstarttime();
+					decStratery.DecCircleStrateryChl[i][index].uiendtime = channel.getUlendtime();
+				}
+			}
+			
+			DECV2_PROTO_DecCircleStrateryEx DECV2_PROTO_DecCircleStrateryEx = new DECV2_PROTO_DecCircleStrateryEx();
+			
+			DECV2_PROTO_HEADER_T proHead = new DECV2_PROTO_HEADER_T();
+			proHead.master = (byte)(noutputscreenno - 1);
+			proHead.weekday = nweek;
+			proHead.dataLen = decStratery.size();
+			DECV2_PROTO_DecCircleStrateryEx.proHead = proHead;
+			DECV2_PROTO_DecCircleStrateryEx.decStratery = decStratery;
+
+			// NS_NET_SetNVRConfig
+			Boolean setResult = NVR9Config.vskDevNet.NS_NET_SetNVRConfig(login_id, new WinDef.UINT(140),
+					new WinDef.LONG(0xFFFFFFFF), DECV2_PROTO_DecCircleStrateryEx.getPointer(),
+					new WinDef.UINT(decStratery.size()));
+			if (BooleanUtil.isTrue(setResult)) {
+				this.executeSuccess(true, null);
+			} else {
+				int errCode = NVR9Config.getErrCode();
+				return this.executeErr(true, "设置视频源轮巡策略失败,错误码:" + errCode + ",窗口号:" + noutputscreenno, "");
+			}
+		}
+		
+		return this.executeSuccess(false, "设置视频源轮巡策略成功");
+	}
+	
+	/**
+	 * 获取当前的轮询策略
+	 * 
+	 * @param sceneRelation
+	 * @return
+	 * @date 2021年10月26日 上午10:15:08
+	 */
+	public ResultClass currentlunx(NvrSceneRelation sceneRelation) {
+		byte sdkChannelId = sceneRelation.getSdkChannelId();
+		if (login_id == null) {
+			boolean initAndLoginNVR9 = this.login(sceneRelation);
+			if (!initAndLoginNVR9) {
+				return this.executeErr(false, null, "登录失败");
+			}
+		}
+		
+		// 获取当前的轮询策略
+		DecCircleStrateryEx decCircleStrateryEx = new DecCircleStrateryEx();
+		Boolean result = this.getDecCircleTimeExConfig(decCircleStrateryEx, sdkChannelId);
+		if (!BooleanUtil.isTrue(result)) {
+			int errCode = NVR9Config.getErrCode();
+			return this.executeErr(false, errCode + "", "获取解码器当前轮询策略信息失败");
+		}
+		
+		// 数据解析
+		Map<String, JSONObject> resultMap = this.parseDecCircleStrateryEx(decCircleStrateryEx);
+		return this.executeSuccess(true, resultMap);
+	}
+	
+	/**
+	 * 获取解码器的轮询策略配置信息
+	 * 
+	 * @param decCircleStrateryEx
+	 * @date 2021年10月26日 上午10:40:40
+	 */
+	private Boolean getDecCircleTimeExConfig(DecCircleStrateryEx decCircleStrateryEx, byte sdkChannelId) {
+		DECV2_PROTO_HEADER_T DECV2_PROTO_HEADER_T = new DECV2_PROTO_HEADER_T();
+		DECV2_PROTO_HEADER_T.master = sdkChannelId;
+		
+		Boolean result = NVR9Config.vskDevNet.NS_NET_GetNVRConfigEx(login_id, new WinDef.UINT(136), new WinDef.LONG(0), 
+				DECV2_PROTO_HEADER_T.getPointer(), new WinDef.UINT(DECV2_PROTO_HEADER_T.size()), decCircleStrateryEx.getPointer(), 
+				new WinDef.UINT(decCircleStrateryEx.size()), null);
+		return result;
+	}
+	
+	/**
+	 * 解析DecCircleStrateryEx结构体
+	 * 
+	 * @param decCircleStrateryEx
+	 * @return
+	 * @date 2021年10月26日 上午10:51:39
+	 */
+	private Map<String, JSONObject> parseDecCircleStrateryEx(DecCircleStrateryEx decCircleStrateryEx) {
+		Map<String, JSONObject> resultMap = new HashMap<String, JSONObject>();
+		DecCircleTimeEx[][] circleStrateryChl = decCircleStrateryEx.DecCircleStrateryChl;
+		for (int i = 0; i < circleStrateryChl.length; i++) {
+			// 获取二维中的数据
+			DecCircleTimeEx[] circleTimeExs = circleStrateryChl[i];
+			for (int j = 0; j < circleTimeExs.length; j++) {
+				String key = i + "_" + j;
+				
+				JSONObject jsonObject = new JSONObject();
+				jsonObject.put("nTimeId", circleStrateryChl[i][j].nTimeId);
+				jsonObject.put("uistarttime", circleStrateryChl[i][j].uistarttime);
+				jsonObject.put("uiendtime", circleStrateryChl[i][j].uiendtime);
+				jsonObject.put("nwinnum", circleStrateryChl[i][j].nwinnum);
+				jsonObject.put("nchanggeTime", circleStrateryChl[i][j].nchanggeTime);
+				jsonObject.put("nChlNum", circleStrateryChl[i][j].nChlNum);
+				
+				IPC_ArrayEx[] arrayExs = circleStrateryChl[i][j].ChlInfo;
+				JSONArray chlInfos = this.parseIPC_ArrayEx(arrayExs);
+				jsonObject.put("ChlInfo", chlInfos);
+				
+				resultMap.put(key, jsonObject);
+			}
+		}
+		
+		return resultMap;
+	}
+	
+	/**
+	 * 投屏
+	 * 
+	 * @param sceneConfig
+	 * @return
+	 * @date 2021年10月26日 上午10:14:59
+	 */
+	public ResultClass toup(SceneConfig sceneConfig) {
+		// 设置通道预览
+		List<Channel> channels = sceneConfig.getChannels();
+		for (Channel channel : channels) {
+			int windowId = channel.getWindowId();
+			
+			// 登录
+			NvrSceneRelation relation = SceneConfigCache.SCENE_CONFIG.get(SceneConfigCache.getCacheKey(sceneConfig.getGroup(), sceneConfig.getScene(), windowId));
+			byte sdkChannelId = relation.getSdkChannelId();
+			boolean initAndLoginNVR9 = this.login(relation);
+			if (!initAndLoginNVR9) {
+				return this.executeErr(false, null, "登录失败");
+			}
+			
+			int errCode = -1;
+			Boolean result = null;
+			List<Camera> cameras = channel.getCameras();
+			for (int i = 0; i < cameras.size(); i++) {
+				errCode = -1;
+				result = null;
+				
+				Camera camera = cameras.get(i);
+				int wChanUsed = camera.getWChanUsed();
+				byte streamType = camera.getStreamType();
+
+				// 用户
+				IPC_ArrayEx IPC_ArrayEx = new IPC_ArrayEx();
+				IPC_ArrayEx.Ipclogin.username = camera.getUsername().getBytes();
+				IPC_ArrayEx.Ipclogin.password = camera.getPassword().getBytes();
+				
+				// 通道
+				IPC_ArrayEx.ipc.ip = camera.getIp().getBytes();
+				IPC_ArrayEx.ipc.port = camera.getPort();
+				IPC_ArrayEx.ipc.wChanUsed = wChanUsed;
+				if (streamType == 0) {
+					IPC_ArrayEx.ipc.mediaStream.stream_uri = camera.getStreamUri().getBytes();
+					IPC_ArrayEx.ipc.mediaStream.uri_size = camera.getUriSize();
+				} else {
+					IPC_ArrayEx.ipc.device_addrs = camera.getDeviceAddrs().getBytes();
+				}
+				
+				IPC_ArrayEx.ipc.frameRate = camera.getFrameRate();
+				IPC_ArrayEx.ipc.streamType = streamType;
+				IPC_ArrayEx.ipc.deviceType = 0;
+				//IPC_ArrayEx.ipc.channelID = channel.getChannelID();
+				//IPC_ArrayEx.ipc.manufacterID = IPC_MACHINE_TYPE.ONVIF_AXIS;
+				IPC_ArrayEx.ipc.manufacturer = camera.getManufactername().getBytes();
+				IPC_ArrayEx.ipc.model = camera.getModel().getBytes();
+				
+				// nUser
+				IPC_ArrayEx.nUser = (wChanUsed << 16) + windowId;	// 添加到的通道号与窗口号
+				
+				// 删除通道预览
+				DECV2_PROTO_IPC deletePreview = new DECV2_PROTO_IPC();
+				deletePreview.proHead.master = sdkChannelId;		//输出屏号从0开始
+				deletePreview.proHead.dataLen = IPC_ArrayEx.size();
+				result = NVR9Config.vskDevNet.NS_NET_SetNVRConfig(login_id, new WinDef.UINT(142), new WinDef.LONG(1), 
+						deletePreview.getPointer(), new WinDef.UINT(deletePreview.size()));
+				if (BooleanUtil.isTrue(result)) {
+					// 添加通道预览
+					DECV2_PROTO_IPC updatePreview = new DECV2_PROTO_IPC();
+					updatePreview.proHead.master = sdkChannelId;	//输出屏号从0开始
+					updatePreview.proHead.dataLen = IPC_ArrayEx.size();
+					result = NVR9Config.vskDevNet.NS_NET_SetNVRConfig(login_id, new WinDef.UINT(141), new WinDef.LONG(1), 
+							deletePreview.getPointer(), new WinDef.UINT(deletePreview.size()));
+					if (!BooleanUtil.isTrue(result)) {
+						errCode = NVR9Config.getErrCode();
+						log.warn("添加通道预览失败,错误码: " + errCode);
+					}
+				} else {
+					errCode = NVR9Config.getErrCode();
+					log.warn("删除通道预览失败,错误码: " + errCode);
+				}
+			}
+			
+			// 退出登录
+			this.logout(true);
+			if (!BooleanUtil.isTrue(result)) {
+				return this.executeErr(true, errCode + "", "投屏操作失败");
+			}
+		}
+		
+		return this.executeSuccess(false, "添加通道预览配置成功");
+	}
+
+	
+	/**
+	 * 获取解码器当前预览视频信息
+	 * 
+	 * @param relation
+	 * @date 2021年10月21日 下午5:33:22
+	 */
+	public ResultClass currentVideo(NvrSceneRelation relation) {
+		byte sdkChannelId = relation.getSdkChannelId();
+		if (login_id == null) {
+			boolean initAndLoginNVR9 = this.login(relation);
+			if (!initAndLoginNVR9) {
+				return this.executeErr(false, null, "登录失败");
+			}
+		}
+		
+		CurShowDevEx curShowDevEx = new CurShowDevEx();
+		Boolean result = this.getCurShowDevExConfig(curShowDevEx, sdkChannelId);
+		if (!BooleanUtil.isTrue(result)) {
+			int errCode = NVR9Config.getErrCode();
+			return this.executeErr(false, errCode + "", "获取解码器当前预览视频信息失败");
+		}
+		
+		JSONObject jsonObject = new JSONObject();
+		jsonObject.put("ChlNum", curShowDevEx.ChlNum);
+		jsonObject.put("WindowsNum", curShowDevEx.WindowsNum);
+		
+		IPC_ArrayEx[] arrayExs = curShowDevEx.ChlInfo;
+		JSONArray chlInfos = this.parseIPC_ArrayEx(arrayExs);
+		jsonObject.put("ChlInfo", chlInfos);
+		
+		return this.executeSuccess(true, jsonObject);
+	}
+	
+	/**
+	 * 获取解码器当前预览视频信息
+	 * 
+	 * @param decCircleStrateryEx
+	 * @date 2021年10月26日 上午10:40:40
+	 */
+	private Boolean getCurShowDevExConfig(CurShowDevEx curShowDevEx, byte sdkChannelId) {
+		DECV2_PROTO_HEADER_T DECV2_PROTO_HEADER_T = new DECV2_PROTO_HEADER_T();
+		DECV2_PROTO_HEADER_T.master = sdkChannelId;
+		
+		Boolean result = NVR9Config.vskDevNet.NS_NET_GetNVRConfigEx(login_id, new WinDef.UINT(136), new WinDef.LONG(0), 
+				DECV2_PROTO_HEADER_T.getPointer(), new WinDef.UINT(DECV2_PROTO_HEADER_T.size()), curShowDevEx.getPointer(), 
+				new WinDef.UINT(curShowDevEx.size()), null);
+		return result;
+	}
+	
+	/**
+	 * 解析IPC_ArrayEx结构体
+	 * 
+	 * @param arrayExs
+	 * @return
+	 * @date 2021年10月26日 上午10:31:01
+	 */
+	private JSONArray parseIPC_ArrayEx(IPC_ArrayEx[] arrayExs) {
+		if (arrayExs == null) {
+			return null;
+		}
+		
+		JSONArray chlInfos = new JSONArray();
+		for (int i = 0; i < arrayExs.length; i++) {
+			JSONObject chlInfo = new JSONObject();
+			IPC_ArrayEx ipc_ArrayEx = arrayExs[i];
+			
+			SERVER_URI server_URI = ipc_ArrayEx.ipc;
+			JSONObject ipc = new JSONObject();
+			
+			ipc.put("wChanUsed", server_URI.wChanUsed);
+			ipc.put("device_addrs", new String(server_URI.device_addrs));
+			
+			JSONObject mediaStream = new JSONObject();
+			mediaStream.put("stream_uri", new String(server_URI.mediaStream.stream_uri));
+			mediaStream.put("uri_size", server_URI.mediaStream.uri_size);
+			ipc.put("mediaStream", mediaStream);
+			
+			ipc.put("addrs_size", server_URI.addrs_size);
+			ipc.put("ip", server_URI.wChanUsed);
+			ipc.put("wChanUsed", new String(server_URI.ip));
+			ipc.put("port", server_URI.port);
+			ipc.put("manufacterID", server_URI.manufacterID);
+			ipc.put("frameRate", server_URI.frameRate);
+			ipc.put("streamType", server_URI.streamType);
+			ipc.put("deviceType", server_URI.deviceType);
+			ipc.put("channelID", server_URI.channelID);
+			ipc.put("manufacturer", new String(server_URI.manufacturer));
+			ipc.put("model", new String(server_URI.model));
+			
+			AUTHORIZATION authorization = ipc_ArrayEx.Ipclogin;
+			JSONObject Ipclogin = new JSONObject();
+			Ipclogin.put("username", new String(authorization.username));
+			Ipclogin.put("password", new String(authorization.password));
+			
+			chlInfo.put("ipc", ipc);
+			chlInfo.put("Ipclogin", Ipclogin);
+			chlInfo.put("nUser", ipc_ArrayEx.nUser);
+			
+			chlInfos.add(chlInfo);
+		}
+		
+		return chlInfos;
+	}
+	
+	
+	/**
+	 * 初始化及登录
+	 */
+	private boolean login(NvrSceneRelation relation) {
+		if (NVR9Config.vskDevNet == null) {
+			log.warn("NVR9 SDK未初始化成功,请重启应用程序");
+			return false;
+		}
+		log.info(relation.toString());
+		
+		// 登录
+		login_id = NVR9Config.vskDevNet.NS_NET_Login(relation.getIp().getBytes(), new WinDef.WORD(relation.getPort()),
+				relation.getUsername().getBytes(), relation.getPassword().getBytes(), null, null);
+		long userId = login_id == null ? -1L : login_id.longValue();
+		if (userId < 0) {
+			log.warn("登录失败,错误码:{}", NVR9Config.getErrCode());
+			return false;
+		}
+
+		return true;
+	}
+	
+	/**
+	 * 返回错误结果,同时释放资源 isLogingout 是否注销登录,在注册失败时只需要释放SDK不需要注销登录 errCode
+	 * 调用sdk的结果,一般为错误码 errPrefix 返回给客户端调用者的错误信息前缀
+	 * 
+	 * @param isLogingout
+	 * @param errCode
+	 * @param errPrefix
+	 * @return
+	 * @date 2021年9月30日 上午11:23:43
+	 */
+	private ResultClass executeErr(boolean isLogingout, String errCode, String errPrefix) {
+		this.logout(isLogingout);
+		String errReason = OtherTools.joinErrStr(errCode, errPrefix);
+		return OtherTools.executeErr(errReason);
+	}
+
+	/**
+	 * 返回调用成功及结果数据,同时注销登陆
+	 */
+	private ResultClass executeSuccess(boolean isLogingout, Object resultData) {
+		this.logout(isLogingout);
+		return OtherTools.executeSuccess(resultData);
+	}
+
+	/**
+	 * 注销登录 isLogingout 是否注销登录,在注册失败时只需要释放SDK不需要注销登录
+	 */
+	private void logout(boolean isLogingout) {
+		// 注销设备,即注销登录
+		if (isLogingout) {
+			Boolean logout = NVR9Config.vskDevNet.NS_NET_Logout(this.login_id);
+			if (BooleanUtil.isTrue(logout)) {
+				log.info("NVR9000 SDK 注销成功");
+			} else {
+				log.error("NVR9000 SDK 注销失败");
+			}
+		}
+	}
+
+}