From 5ba0fba03d9fcb09eea0c1e703a4f050378d7992 Mon Sep 17 00:00:00 2001
From: panlinlin <648540858@qq.com>
Date: 星期一, 26 四月 2021 09:13:17 +0800
Subject: [PATCH] 添加部分onvif代码

---
 libs/onvif-java-1.0.2.jar                                                               |    0 
 src/main/java/com/genersoft/iot/vmp/vmanager/onvif/ONVIFController.java                 |  120 +++++++++++++++
 .gitmodules                                                                             |    3 
 web_src/src/components/StreamProxyList.vue                                              |   36 ++++
 src/main/java/com/genersoft/iot/vmp/onvif/impl/ONVIFServerIMpl.java                     |  116 ++++++++++++++
 src/main/java/com/genersoft/iot/vmp/onvif/IONVIFServer.java                             |   13 +
 web_src/src/components/dialog/onvifEdit.vue                                             |  121 +++++++++++++++
 web_src/src/components/dialog/StreamProxyEdit.vue                                       |    4 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java |    2 
 pom.xml                                                                                 |   33 +++
 src/main/java/com/genersoft/iot/vmp/onvif/dto/ONVIFCallBack.java                        |    5 
 11 files changed, 446 insertions(+), 7 deletions(-)

diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..202b14c
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "be.teletask.onvif-java"]
+	path = be.teletask.onvif-java
+	url = https://gitee.com/18010473990/be.teletask.onvif-java.git
diff --git a/libs/onvif-java-1.0.2.jar b/libs/onvif-java-1.0.2.jar
new file mode 100644
index 0000000..dd62a23
--- /dev/null
+++ b/libs/onvif-java-1.0.2.jar
Binary files differ
diff --git a/pom.xml b/pom.xml
index 91b90e6..f8a8b53 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,7 +10,7 @@
 	</parent>
 
 	<groupId>com.genersoft</groupId>
-	<artifactId>wvp</artifactId>
+	<artifactId>wvp-gb28181</artifactId>
 	<version>2.0.0</version>
 	<name>web video platform</name>
 
@@ -44,6 +44,7 @@
 
 	<properties>
 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format>
 
 		<!-- 渚濊禆鐗堟湰 -->
 		<pagehelper.version>5.2.0</pagehelper.version>
@@ -167,10 +168,36 @@
 			<artifactId>okhttp</artifactId>
 			<version>4.9.0</version>
 		</dependency>
-    </dependencies>
+
+		<!-- okhttp-digest -->
+		<dependency>
+			<groupId>com.burgstaller</groupId>
+			<artifactId>okhttp-digest</artifactId>
+			<version>2.1</version>
+		</dependency>
+
+		<!-- https://mvnrepository.com/artifact/net.sf.kxml/kxml2 -->
+		<dependency>
+			<groupId>net.sf.kxml</groupId>
+			<artifactId>kxml2</artifactId>
+			<version>2.3.0</version>
+		</dependency>
+
+
+		<!-- onvif鍗忚鏍� -->
+		<dependency>
+			<groupId>be.teletask</groupId>
+			<artifactId>onvif-java</artifactId>
+			<version>1.0.2</version>
+			<scope>system</scope>
+			<systemPath>${project.basedir}/libs/onvif-java-1.0.2.jar</systemPath>
+		</dependency>
+	</dependencies>
+
+
 	
 	<build>
-		<finalName>wvp-2.0</finalName>
+		<finalName>${project.artifactId}-${project.version}-${maven.build.timestamp}</finalName>
 		<plugins>
 			<plugin>
 				<groupId>org.springframework.boot</groupId>
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
index b7f592e..f21895c 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
@@ -35,6 +35,8 @@
 
 	public static final String CALLBACK_CMD_STOP = "CALLBACK_STOP";
 
+	public static final String CALLBACK_ONVIF = "CALLBACK_ONVIF";
+
 	public static final String CALLBACK_CMD_MOBILEPOSITION = "CALLBACK_MOBILEPOSITION";
 
 	public static final String CALLBACK_CMD_PRESETQUERY = "CALLBACK_PRESETQUERY";
diff --git a/src/main/java/com/genersoft/iot/vmp/onvif/IONVIFServer.java b/src/main/java/com/genersoft/iot/vmp/onvif/IONVIFServer.java
new file mode 100644
index 0000000..eb81a36
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/onvif/IONVIFServer.java
@@ -0,0 +1,13 @@
+package com.genersoft.iot.vmp.onvif;
+
+import be.teletask.onvif.models.OnvifDevice;
+import com.genersoft.iot.vmp.onvif.dto.ONVIFCallBack;
+
+import java.util.List;
+
+public interface IONVIFServer {
+
+    void search(int timeout, ONVIFCallBack<List<String>> callBack);
+
+    void getRTSPUrl(int timeout, OnvifDevice device, ONVIFCallBack<String> callBack);
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/onvif/dto/ONVIFCallBack.java b/src/main/java/com/genersoft/iot/vmp/onvif/dto/ONVIFCallBack.java
new file mode 100644
index 0000000..3fdbde5
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/onvif/dto/ONVIFCallBack.java
@@ -0,0 +1,5 @@
+package com.genersoft.iot.vmp.onvif.dto;
+
+public interface ONVIFCallBack<T> {
+    void run(int errorCode, T t);
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/onvif/impl/ONVIFServerIMpl.java b/src/main/java/com/genersoft/iot/vmp/onvif/impl/ONVIFServerIMpl.java
new file mode 100644
index 0000000..e747118
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/onvif/impl/ONVIFServerIMpl.java
@@ -0,0 +1,116 @@
+package com.genersoft.iot.vmp.onvif.impl;
+
+
+import be.teletask.onvif.DiscoveryManager;
+import be.teletask.onvif.OnvifManager;
+import be.teletask.onvif.listeners.*;
+import be.teletask.onvif.models.*;
+import be.teletask.onvif.responses.OnvifResponse;
+import com.genersoft.iot.vmp.onvif.IONVIFServer;
+import com.genersoft.iot.vmp.onvif.dto.ONVIFCallBack;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 澶勭悊onvif鐨勫悇绉嶆搷浣�
+ */
+@Service
+public class ONVIFServerIMpl implements IONVIFServer {
+
+    private final static Logger logger = LoggerFactory.getLogger(ONVIFServerIMpl.class);
+
+    @Override
+    public void search(int timeout, ONVIFCallBack<List<String>> callBack) {
+        DiscoveryManager manager = new DiscoveryManager();
+        manager.setDiscoveryTimeout(timeout);
+        Map<String, Device> deviceMap = new HashMap<>();
+        // 鎼滅储璁惧
+        manager.discover(new DiscoveryListener() {
+            @Override
+            public void onDiscoveryStarted() {
+                logger.info("Discovery started");
+            }
+
+            @Override
+            public void onDevicesFound(List<Device> devices) {
+                if (devices == null || devices.size() == 0) return;
+                for (Device device : devices){
+                    System.out.println(device.getHostName());
+                    deviceMap.put(device.getHostName(),  device);
+                }
+            }
+
+            // 鎼滅储缁撴潫
+            @Override
+            public void onDiscoveryFinished() {
+                ArrayList<String> result = new ArrayList<>();
+                for (Device device : deviceMap.values()) {
+                    System.out.println(device.getHostName());
+                    result.add(device.getHostName());
+                }
+                callBack.run(0, result);
+            }
+        });
+    }
+
+    @Override
+    public void getRTSPUrl(int timeout, OnvifDevice device, ONVIFCallBack<String> callBack) {
+        if (device.getHostName() == null ){
+            callBack.run(400, null);
+        }
+        OnvifManager onvifManager = new OnvifManager();
+        onvifManager.setOnvifResponseListener(new OnvifResponseListener(){
+
+            @Override
+            public void onResponse(OnvifDevice onvifDevice, OnvifResponse response) {
+                System.out.println("[RESPONSE] " + onvifDevice.getHostName()
+                        + "======" + response.getErrorCode()
+                        + "======" + response.getErrorMessage());
+            }
+
+            @Override
+            public void onError(OnvifDevice onvifDevice, int errorCode, String errorMessage) {
+                System.out.println("[ERROR] " + onvifDevice.getHostName() + "======" + errorCode + "=======" + errorMessage);
+                callBack.run(errorCode, errorMessage);
+            }
+        });
+
+        try {
+            onvifManager.getServices(device, (OnvifDevice onvifDevice, OnvifServices services) -> {
+                if (services.getProfilesPath().equals("/onvif/Media")) {
+                    onvifDevice.setPath(services);
+                    onvifManager.getMediaProfiles(onvifDevice, new OnvifMediaProfilesListener() {
+                        @Override
+                        public void onMediaProfilesReceived(OnvifDevice device, List<OnvifMediaProfile> mediaProfiles) {
+                            for (OnvifMediaProfile mediaProfile : mediaProfiles) {
+                                System.out.println(mediaProfile.getName());
+                                System.out.println(mediaProfile.getToken());
+                                if (mediaProfile.getName().equals("mainStream")) {
+                                    onvifManager.getMediaStreamURI(device, mediaProfile, (OnvifDevice onvifDevice,
+                                                                                          OnvifMediaProfile profile, String uri) -> {
+
+                                        uri = uri.replace("rtsp://", "rtsp://"+ device.getUsername() + ":"+ device.getPassword() + "@");
+                                        logger.info(onvifDevice.getHostName() + "鐨勫湴鍧�" + uri);
+                                        callBack.run(0, uri);
+                                    });
+                                }
+                            }
+                        }
+                    });
+                }
+            });
+        }catch (Exception e) {
+            callBack.run(400, e.getMessage());
+        }
+
+
+    }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/onvif/ONVIFController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/onvif/ONVIFController.java
new file mode 100644
index 0000000..a484b51
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/onvif/ONVIFController.java
@@ -0,0 +1,120 @@
+package com.genersoft.iot.vmp.vmanager.onvif;
+
+import be.teletask.onvif.models.OnvifDevice;
+import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
+import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
+import com.genersoft.iot.vmp.onvif.IONVIFServer;
+import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.context.request.async.DeferredResult;
+
+import java.util.List;
+import java.util.UUID;
+
+@Api(tags = "onvif璁惧")
+@CrossOrigin
+@RestController
+@RequestMapping("/api/onvif")
+public class ONVIFController {
+
+
+    @Autowired
+    private DeferredResultHolder resultHolder;
+
+    @Autowired
+    private IONVIFServer onvifServer;
+
+
+    @ApiOperation("鎼滅储")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name="timeout", value = "瓒呮椂鏃堕棿", required = true, dataTypeClass = Integer.class),
+    })
+    @GetMapping(value = "/search")
+    @ResponseBody
+    public DeferredResult<ResponseEntity<WVPResult>> search(@RequestParam(required = false)Integer timeout){
+        DeferredResult<ResponseEntity<WVPResult>> result = new DeferredResult<>(timeout + 10L);
+        UUID uuid = UUID.randomUUID();
+        result.onTimeout(()->{
+            RequestMessage msg = new RequestMessage();
+            msg.setId(DeferredResultHolder.CALLBACK_ONVIF + uuid);
+            WVPResult<String> wvpResult = new WVPResult();
+            wvpResult.setCode(0);
+            wvpResult.setMsg("鎼滅储瓒呮椂");
+            msg.setData(wvpResult);
+            resultHolder.invokeResult(msg);
+        });
+        resultHolder.put(DeferredResultHolder.CALLBACK_ONVIF + uuid, result);
+
+        onvifServer.search(timeout, (errorCode, onvifDevices) ->{
+            RequestMessage msg = new RequestMessage();
+            msg.setId(DeferredResultHolder.CALLBACK_ONVIF + uuid);
+            WVPResult<List<String>> resultData = new WVPResult();
+            resultData.setCode(errorCode);
+            if (errorCode == 0) {
+                resultData.setMsg("success");
+                resultData.setData(onvifDevices);
+            }else {
+                resultData.setMsg("fail");
+            }
+            msg.setData(resultData);
+            msg.setData(resultData);
+            resultHolder.invokeResult(msg);
+        });
+
+        return result;
+    }
+
+    @ApiOperation("鑾峰彇onvif鐨剅tsp鍦板潃")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name="timeout", value = "瓒呮椂鏃堕棿", required = true, dataTypeClass = Integer.class),
+            @ApiImplicitParam(name="hostname", value = "onvif鍦板潃", required = true, dataTypeClass = String.class),
+            @ApiImplicitParam(name="username", value = "鐢ㄦ埛鍚�", required = true, dataTypeClass = String.class),
+            @ApiImplicitParam(name="password", value = "瀵嗙爜", required = true, dataTypeClass = String.class),
+    })
+    @GetMapping(value = "/rtsp")
+    @ResponseBody
+    public DeferredResult<ResponseEntity<WVPResult>> getRTSPUrl(@RequestParam(value="timeout", required=false, defaultValue="3000") Integer timeout,
+                                                                @RequestParam(required = true) String hostname,
+                                                                @RequestParam(required = false) String username,
+                                                                @RequestParam(required = false) String password
+                                                                ){
+
+        DeferredResult<ResponseEntity<WVPResult>> result = new DeferredResult<>(timeout + 10L);
+        UUID uuid = UUID.randomUUID();
+        result.onTimeout(()->{
+            RequestMessage msg = new RequestMessage();
+            msg.setId(DeferredResultHolder.CALLBACK_ONVIF + uuid);
+            WVPResult<String> wvpResult = new WVPResult();
+            wvpResult.setCode(0);
+            wvpResult.setMsg("鑾峰彇onvif鐨剅tsp鍦板潃瓒呮椂");
+            msg.setData(wvpResult);
+            resultHolder.invokeResult(msg);
+        });
+        resultHolder.put(DeferredResultHolder.CALLBACK_ONVIF + uuid, result);
+        OnvifDevice onvifDevice = new OnvifDevice(hostname, username, password);
+        onvifServer.getRTSPUrl(timeout, onvifDevice,  (errorCode, url) ->{
+            RequestMessage msg = new RequestMessage();
+            msg.setId(DeferredResultHolder.CALLBACK_ONVIF + uuid);
+            WVPResult<String> resultData = new WVPResult();
+            resultData.setCode(errorCode);
+            if (errorCode == 0) {
+                resultData.setMsg("success");
+                resultData.setData(url);
+            }else {
+                resultData.setMsg(url);
+            }
+            msg.setData(resultData);
+
+            resultHolder.invokeResult(msg);
+        });
+
+        return result;
+    }
+
+}
diff --git a/web_src/src/components/StreamProxyList.vue b/web_src/src/components/StreamProxyList.vue
index 0e0fcdd..d71de84 100644
--- a/web_src/src/components/StreamProxyList.vue
+++ b/web_src/src/components/StreamProxyList.vue
@@ -10,6 +10,7 @@
 				</div>
 				<div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;">
 					<el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="addStreamProxy">娣诲姞浠g悊</el-button>
+					<el-button v-if="false" icon="el-icon-search" size="mini" style="margin-right: 1rem;" type="primary" @click="addOnvif">鎼滅储ONVIF</el-button>
 				</div>
 				<devicePlayer ref="devicePlayer"></devicePlayer>
 				<el-table :data="streamProxyList" border style="width: 100%" :height="winHeight">
@@ -79,6 +80,7 @@
 					:total="total">
 				</el-pagination>
 			<streamProxyEdit ref="streamProxyEdit" ></streamProxyEdit>
+			<onvifEdit ref="onvifEdit" ></onvifEdit>
 			</el-main>
 		</el-container>
 	</div>
@@ -86,6 +88,7 @@
 
 <script>
 	import streamProxyEdit from './dialog/StreamProxyEdit.vue'
+	import onvifEdit from './dialog/onvifEdit.vue'
 	import devicePlayer from './dialog/devicePlayer.vue'
 	import uiHeader from './UiHeader.vue'
 	export default {
@@ -93,6 +96,7 @@
 		components: {
 			devicePlayer,
 			streamProxyEdit,
+      onvifEdit,
 			uiHeader
 		},
 		data() {
@@ -113,7 +117,7 @@
 		},
 		mounted() {
 			this.initData();
-			// this.updateLooper = setInterval(this.initData, 10000);
+			this.updateLooper = setInterval(this.initData, 1000);
 		},
 		destroyed() {
 			this.$destroy('videojs');
@@ -155,6 +159,36 @@
 			addStreamProxy: function(){
 				this.$refs.streamProxyEdit.openDialog(null, this.initData)
 			},
+      addOnvif: function(){
+        this.getListLoading = true;
+        this.getListLoading = true;
+        this.$axios({
+          method: 'get',
+          url:`/api/onvif/search?timeout=3000`,
+        }).then((res) =>{
+          this.getListLoading = false;
+          if (res.data.code == 0 ){
+            if (res.data.data.length > 0) {
+              console.log(res.data.data)
+              this.$refs.onvifEdit.openDialog(res.data.data, (url)=>{
+                  if (url != null) {
+                    this.$refs.onvifEdit.close();
+                    this.$refs.streamProxyEdit.openDialog({type: "default", url: url, src_url: url}, this.initData())
+                  }
+              })
+            }else {
+              this.$message.success("鏈壘鍒板彲鐢ㄨ澶�");
+            }
+        }else {
+            this.$message.error(res.data.msg);
+          }
+
+        }).catch((error)=> {
+          this.getListLoading = false;
+          this.$message.error(error.response.data.msg);
+        });
+
+			},
 			saveStreamProxy: function(){
 			},
 			play: function(row){
diff --git a/web_src/src/components/dialog/StreamProxyEdit.vue b/web_src/src/components/dialog/StreamProxyEdit.vue
index 696379e..1c0d3b9 100644
--- a/web_src/src/components/dialog/StreamProxyEdit.vue
+++ b/web_src/src/components/dialog/StreamProxyEdit.vue
@@ -139,9 +139,6 @@
       this.listChangeCallback = callback;
       if (proxyParam != null) {
         this.proxyParam = proxyParam;
-        this.onSubmit_text = "淇濆瓨";
-      } else {
-        this.onSubmit_text = "绔嬪嵆鍒涘缓";
       }
     },
     onSubmit: function () {
@@ -163,6 +160,7 @@
           that.showDialog = false;
           if (that.listChangeCallback != null) {
             that.listChangeCallback();
+            that.dialogLoading = false;
           }
         }
       }).catch(function (error) {
diff --git a/web_src/src/components/dialog/onvifEdit.vue b/web_src/src/components/dialog/onvifEdit.vue
new file mode 100644
index 0000000..c853294
--- /dev/null
+++ b/web_src/src/components/dialog/onvifEdit.vue
@@ -0,0 +1,121 @@
+<template>
+  <div id="onvif鎼滅储" v-loading="isLoging">
+    <el-dialog
+      title="onvif鎼滅储"
+      width="40%"
+      top="2rem"
+      :close-on-click-modal="false"
+      :visible.sync="showDialog"
+      :destroy-on-close="true"
+      @close="close()"
+    >
+      <div id="shared" style="margin-top: 1rem;margin-right: 100px;">
+        <el-form ref="form" :rules="rules" :model="form" label-width="140px" >
+          <el-form-item label="鍦板潃" prop="hostName" >
+            <el-select v-model="form.hostName" style="float: left; width: 100%" >
+              <el-option
+                v-for="item in hostNames"
+                :key="item"
+                :label="item.replace('http://', '')"
+                :value="item">
+              </el-option>
+            </el-select>
+
+          </el-form-item>
+          <el-form-item label="鐢ㄦ埛鍚�" prop="username">
+            <el-input v-model="form.username" clearable></el-input>
+          </el-form-item>
+          <el-form-item label="瀵嗙爜" prop="password">
+            <el-input v-model="form.password" clearable></el-input>
+          </el-form-item>
+          <el-form-item>
+            <div style="float: right;">
+              <el-button type="primary" @click="onSubmit" >纭</el-button>
+              <el-button @click="close">鍙栨秷</el-button>
+            </div>
+
+          </el-form-item>
+        </el-form>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "onvifEdit",
+  props: {},
+  computed: {},
+  created() {},
+  data() {
+    return {
+      listChangeCallback: null,
+      showDialog: false,
+      isLoging: false,
+      hostNames:[],
+      form: {
+        hostName: null,
+        username: "admin",
+        password: "admin123",
+      },
+
+      rules: {
+        hostName: [{ required: true, message: "璇烽�夋嫨", trigger: "blur" }],
+        username: [{ required: true, message: "璇疯緭鍏ョ敤鎴峰悕", trigger: "blur" }],
+        password: [{ required: true, message: "璇疯緭鍏ュ瘑鐮�", trigger: "blur" }],
+      },
+    };
+  },
+  methods: {
+    openDialog: function (hostNamesParam, callback) {
+      console.log(hostNamesParam)
+      this.showDialog = true;
+      this.listChangeCallback = callback;
+      if (hostNamesParam != null) {
+        this.hostNames = hostNamesParam;
+      }
+
+    },
+    onSubmit: function () {
+      console.log("onSubmit");
+      console.log(this.form);
+      this.$axios({
+        method: 'get',
+        url:`api/onvif/rtsp`,
+        params: {
+          hostname: this.form.hostName,
+          timeout: 3000,
+          username: this.form.username,
+          password: this.form.password,
+        }
+      }).then((res) => {
+        console.log(res.data)
+        if (res.data.code == 0) {
+          if (res.data.data != null) {
+            this.listChangeCallback(res.data.data)
+          }else {
+            this.$message({
+              showClose: true,
+              message: res.data.msg,
+              type: "error",
+            });
+          }
+
+        }else {
+          this.$message({
+            showClose: true,
+            message: res.data.msg,
+            type: "error",
+          });
+        }
+      }).catch(function (error) {
+        console.log(error);
+      });
+    },
+    close: function () {
+      this.showDialog = false;
+      this.$refs.form.resetFields();
+    },
+  },
+};
+</script>

--
Gitblit v1.8.0