大华SDK+JAVA+4g网络摄像头进行二次开发

这篇具有很好参考价值的文章主要介绍了大华SDK+JAVA+4g网络摄像头进行二次开发。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

监控,相信大家都不陌生。现在的监控技术发展迅速,国内以海康威视为首的智能视频监控提供商也层出不穷。现在,这些提供商都已经提供了相应的SDK以及API接口,能够很好的支撑我们进行摄像机的二次开发工作。相信大家都有接触过这么一个需求:利用手机可以自己进行摄像机的录像控制,然后在规定的时间内停止录制,然后将这个时间段内的视频保存下来。方便客户端的客户进行查看相应时间段的检控视频。这样就避免了视频一直录制,存储空间不足以承受如此之大的压力,而且也可以降低对于实时拉流的带宽要求。

本文关键词

JAVA、大华SDK、视频拉流、自定义拉流时长、录像保存、4G网络摄像机

硬件设备

本次所用到的摄像机是大华的4G网络摄像机,此摄像机支持利用SIM卡进行4G上网
springboot中集成大华摄像头,java,网络,java,服务器
现在不借助大华自带的软件来控制摄像机,自行开发软件来实现手机端访问摄像头进行拉流的触发,摄像头执行相应的程序进行一段时间的拉流,到了预定的时间进行自动保存视频数据到服务器的相应位置。

技术分析

首先,我们要明确的知道要实现这么一个简单的需求要具备哪些知识。
①手机怎么通过网络触发摄像机?
答:摄像头通过手机进行触发使用get请求的方式访问URL,输入设备ID,告诉服务器我要控制那台摄像头,服务器收到请求进行触发。(此技术属于基本的web开发的基本技能实现起来难度不大)
②通过什么样的方式让摄像头执行自己编写的程序?
答:程序运行在服务器上,同时需要让摄像头能够通过固定IP找到这台服务器。
③摄像头怎么找到服务器?
答:摄像头具备一个功能叫做自动注册(相当于第一次在服务器上使用需要创建一样,让服务器知道这个摄像机)主动注册时输入需要摄像头执行相应程序的服务器的固定IP,以及摄像机的端口号(可自定义)设备登录账号和设备登录密码即可完成注册,这个时候形成长连接就可以相互获取信息和传输数据了,服务器也就可以获取到设备的ID,与手机端发送的设备ID对应就可以触发相应的设备进行工作。

技术逻辑图

使用大华的SDK进行二次开发都会有相应的资料,内部也有很多逻辑流程图,这里提取出相关的那一块内容进行展示:
springboot中集成大华摄像头,java,网络,java,服务器

由上图可见,在我们利用手机触发摄像头的时候服务器内程序执行的逻辑是,首先要进行设备的初始化,然后服务器会寻找在记录中是否注册过本台摄像机,是否有此设备的信息,如果没有摄像机的信息需要进行主动注册。这个时候摄像机会执行访问本服务器固定IP的程序进行自动的注册,注册完成后服务器就会收到本台摄像机的设备ID(此时服务器与摄像头已经形成长连接),然后就可以等待客户端利用手机对摄像头进行触发时发出的信号做比对,让对应的摄像头开始工作。最后就是定义录制的时长,和自动保存的功能,完成后会清理内存。

代码实现

前期准备

首先打开我们心爱的idea(我这里使用的是2021 64位版本的)
springboot中集成大华摄像头,java,网络,java,服务器
进入到项目列表的窗口,选择New Project 新建立一个Spring Boot项目
springboot中集成大华摄像头,java,网络,java,服务器
然后,选择Spring Initializr,在右侧的对话框中进行项目名称的修改(我这里名字为CameraTest),然后根据自己的命名习惯将Group、Artifact、Package name名字做修改(这里仅修改了Grop的名称为com.ruoyi),最后注意自己的java的版本号。修改完后点击Next。
springboot中集成大华摄像头,java,网络,java,服务器
创建成功后我们会看到如图所示的界面
src/main/java/com.ruoyi.cameratest/CameraTestApplication
为springboot的启动程序。
springboot中集成大华摄像头,java,网络,java,服务器
然后我们需要修改下自己的maven的文件保存的路径,之后此项目所要用到的外部jar包都会保存在这些文件夹下。
①我们点击File/Settings

springboot中集成大华摄像头,java,网络,java,服务器
②在搜索框内搜索maven会出现如图所示的内容(Maven home path 为当时我们下载maven的源文件文件位置;User settings file首先找到自己的maven安装位置下conf文件下的settings.xml文件;Local repository找到自己maven安装位置下的自己创建的一个用于保存第三方jar包的文件夹)
springboot中集成大华摄像头,java,网络,java,服务器
例如我的maven安装在D:\SoftWares\apache-maven-3.6.1配置如下,完成后点击Apply,点击OK完成设置。
springboot中集成大华摄像头,java,网络,java,服务器
最后我们修改pom.xml文件
springboot中集成大华摄像头,java,网络,java,服务器
pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.ruoyi</groupId>
    <artifactId>CameraTest</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <name>CameraTest</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>net.java.dev.jna</groupId>
            <artifactId>jna</artifactId>
            <version>5.4.0</version>
        </dependency>
        <dependency>
            <groupId>com.dahua.netsdk</groupId>
            <artifactId>dahua-netsdk-jni</artifactId>
            <version>1.0.0</version>
        </dependency>
        <!--lombok插件-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
        <!-- Mysql驱动包 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

这里我们修改了pom.xml文件后需要进行刷新,最后测试一下是否可以成功启动springboot
springboot中集成大华摄像头,java,网络,java,服务器
再来就是进入大华公司的官网找到对应的SDK进行下载
springboot中集成大华摄像头,java,网络,java,服务器

1.消息接收实现类和接口

首先创建如下图所示的文件和类
springboot中集成大华摄像头,java,网络,java,服务器
instructController.java

package com.ruoyi.controller;


import com.ruoyi.service.instructService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/test")
public class instructController {
    @Autowired
    private instructService service;

    public String VideoPath;
    public String getVideoPath() {
        return VideoPath;
    }
    public void setVideoPath(String videoPath) {
        VideoPath = videoPath;
    }

    @GetMapping("/ss")
    public Map<String,Object> SendMessage(PreInfo info){
        service.SendMessage(info);
        instructController instr = new instructController();

        Map<String, Object> result = new HashMap<String, Object>();
        result.put("videopath", instr.getVideoPath());
        return result;
    }


}

PreInfo.java

package com.ruoyi.controller;

import lombok.Data;

@Data
public class PreInfo {
    private String PreDeviceId;
}

instructService.java

package com.ruoyi.service;

import com.ruoyi.controller.PreInfo;

public interface instructService {
    void SendMessage(PreInfo info);
}

ServiceCB.java

package com.ruoyi.demo.frame;

import com.ruoyi.controller.PreInfo;
import com.ruoyi.service.instructService;
import org.springframework.stereotype.Component;

@Component
public class ServiceCB implements instructService {
    @Override
    public void SendMessage(PreInfo info) {
        System.out.println("成功触发!");
    }
}

2.主动注册

首先在src/mian/resources文件中将SDK中的dynamic-lib-load.xml文件复制过来,这个文件是为了满足不同平台下需要加载的C动态库

dynamic-lib-load.xml

<?xml version="1.0" encoding="UTF-8" ?>
<dynamic-lib>
    <win64>
        <lib>avnetsdk</lib>
        <lib>dhconfigsdk</lib>
        <lib>dhnetsdk</lib>
        <lib>dhplay</lib>
        <lib>ImageAlg</lib>
        <lib>Infra</lib>
        <lib>IvsDrawer</lib>
        <lib>StreamConvertor</lib>
        <lib>jninetsdk</lib>
    </win64>
    <win32>
        <lib>avnetsdk</lib>
        <lib>dhconfigsdk</lib>
        <lib>dhnetsdk</lib>
        <lib>dhplay</lib>
        <lib>Infra</lib>
        <lib>ImageAlg</lib>
        <lib>StreamConvertor</lib>
        <lib>jninetsdk</lib>
    </win32>
    <linux64>
        <lib>avnetsdk</lib>
        <lib>dhnetsdk</lib>
        <lib>dhconfigsdk</lib>
        <lib>StreamConvertor</lib>
        <lib>jninetsdk</lib>
    </linux64>
    <linux32>
        <lib>avnetsdk</lib>
        <lib>dhconfigsdk</lib>
        <lib>dhnetsdk</lib>
        <lib>StreamConvertor</lib>
        <lib>jninetsdk</lib>
    </linux32>
    <mac64>
        <lib>avnetsdk</lib>
        <lib>dhnetsdk</lib>
        <lib>dhconfigsdk</lib>
        <lib>StreamConvertor</lib>
    </mac64>
</dynamic-lib>

接着在项目目录中新建子文件夹com.ruoyi/lib
springboot中集成大华摄像头,java,网络,java,服务器

打开我们的大华SDK项目在一个新的窗口中,将我们需要的实现类拷贝过来。如下图是大华SDK-java-x64版本的文件目录。
springboot中集成大华摄像头,java,网络,java,服务器
首先我们将SDK中的lib文件中的所有文件全部拷贝到刚建立的lib中。(如果复制过来出现报错,检查import 中的文件路径名称,因为SDK中的项目名称为com.netsdk我们的不是所以需要修改)。后面功能实现类,由于官方的SDK中的实现类功能太多太杂,我做了整理,大家可以复制我整理后的代码。首先我们需要主动注册的实现类AutoRegisterModule.java,登录设备的实现类LoginModule.java,设备的信息类DeviceInfo.java

AutoRegisterModule.java

package com.ruoyi.demo.module;

import com.ruoyi.demo.module.LoginModule;
import com.ruoyi.lib.NetSDKLib.LLong;
import com.ruoyi.lib.NetSDKLib.fServiceCallBack;
import com.ruoyi.lib.NetSDKLib;
import com.ruoyi.lib.ToolKits;

public class AutoRegisterModule {

    // 监听服务句柄
    public static LLong mServerHandler = new LLong(0);

    // 设备信息
    public static NetSDKLib.NET_DEVICEINFO_Ex m_stDeviceInfo = new NetSDKLib.NET_DEVICEINFO_Ex();

    /**
     * 开启服务
     *
     * @param address  本地IP地址
     * @param port     本地端口, 可以任意
     * @param callback 回调函数
     */
    public static boolean startServer(String address, int port, fServiceCallBack callback) {
        //调用监听接口实现服务的开启
        mServerHandler = LoginModule.netsdk.CLIENT_ListenServer(address, port, 1000, callback, null);
        if (0 == mServerHandler.longValue()) {
            System.err.println("Failed to start server." + ToolKits.getErrorCodePrint());
        } else {
            System.out.printf("Start server, [Server address %s][Server port %d]\n", address, port);
        }
        return mServerHandler.longValue() != 0;
    }

    /**
     * 结束服务
     */
    public static boolean stopServer() {
        boolean bRet = false;

        if (mServerHandler.longValue() != 0) {
            bRet = LoginModule.netsdk.CLIENT_StopListenServer(mServerHandler);
            mServerHandler.setValue(0);
            System.out.println("Stop server!");
        }

        return bRet;
    }

}

LoginModule.java

package com.ruoyi.demo.module;

import com.ruoyi.lib.NetSDKLib;
import com.ruoyi.lib.NetSDKLib.LLong;
import com.ruoyi.lib.NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY;
import com.ruoyi.lib.NetSDKLib.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY;
import com.ruoyi.lib.ToolKits;

import java.io.File;

/**
 * 登陆接口实现
 * 主要有 :初始化、登陆、登出功能
 */
public class LoginModule {

	public static NetSDKLib netsdk 		= NetSDKLib.NETSDK_INSTANCE;

	// 设备信息
	public static NetSDKLib.NET_DEVICEINFO_Ex m_stDeviceInfo = new NetSDKLib.NET_DEVICEINFO_Ex();
	
	// 登陆句柄
	public static LLong m_hLoginHandle = new LLong(0);   
	
	private static boolean bInit    = false;
	private static boolean bLogopen = false;
	
	/**
	 * 初始化
	 */
	public static boolean init(NetSDKLib.fDisConnect disConnect, NetSDKLib.fHaveReConnect haveReConnect) {	
		bInit = netsdk.CLIENT_Init(disConnect, null);
		if(!bInit) {
			System.out.println("Initialize SDK failed");
			return false;
		}

		//打开日志,可选
		NetSDKLib.LOG_SET_PRINT_INFO setLog = new NetSDKLib.LOG_SET_PRINT_INFO();
        File path = new File("./sdklog/");
        if (!path.exists()) {
            path.mkdir();
        }
		String logPath = path.getAbsoluteFile().getParent() + "\\sdklog\\" + ToolKits.getDate() + ".log";
		setLog.nPrintStrategy = 0;
		setLog.bSetFilePath = 1;
		System.arraycopy(logPath.getBytes(), 0, setLog.szLogFilePath, 0, logPath.getBytes().length);
		System.out.println(logPath);
		setLog.bSetPrintStrategy = 1;
		bLogopen = netsdk.CLIENT_LogOpen(setLog);
		if(!bLogopen ) {
			System.err.println("Failed to open NetSDK log");
		}
		
		// 设置断线重连回调接口,设置过断线重连成功回调函数后,当设备出现断线情况,SDK内部会自动进行重连操作
		// 此操作为可选操作,但建议用户进行设置
		netsdk.CLIENT_SetAutoReconnect(haveReConnect, null);
	    
		//设置登录超时时间和尝试次数,可选
		int waitTime = 5000; //登录请求响应超时时间设置为5S
		int tryTimes = 1;    //登录时尝试建立链接1次
		netsdk.CLIENT_SetConnectTime(waitTime, tryTimes);
		
		
		// 设置更多网络参数,NET_PARAM的nWaittime,nConnectTryNum成员与CLIENT_SetConnectTime 
		// 接口设置的登录设备超时时间和尝试次数意义相同,可选
		NetSDKLib.NET_PARAM netParam = new NetSDKLib.NET_PARAM();
		netParam.nConnectTime = 10000;      // 登录时尝试建立链接的超时时间
		netParam.nGetConnInfoTime = 3000;   // 设置子连接的超时时间
		netParam.nGetDevInfoTime = 3000;//获取设备信息超时时间,为0默认1000ms
		netsdk.CLIENT_SetNetworkParam(netParam);	
		
		return true;
	}
	
	/**
	 * 清除环境
	 */
	public static void cleanup() {
		if(bLogopen) {
			netsdk.CLIENT_LogClose();
		}
		
		if(bInit) {
			netsdk.CLIENT_Cleanup();
		}
	}

	/**
	 * 登录设备
	 */
	public static boolean login(String m_strIp, int m_nPort, String m_strUser, String m_strPassword) {	
		//IntByReference nError = new IntByReference(0);
		//入参
		NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY pstInParam=new NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY();
		pstInParam.nPort=m_nPort;
		pstInParam.szIP=m_strIp.getBytes();
		pstInParam.szPassword=m_strPassword.getBytes();
		pstInParam.szUserName=m_strUser.getBytes();
		//出参
		NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY pstOutParam=new NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY();
		pstOutParam.stuDeviceInfo=m_stDeviceInfo;
		//m_hLoginHandle = netsdk.CLIENT_LoginEx2(m_strIp, m_nPort, m_strUser, m_strPassword, 0, null, m_stDeviceInfo, nError);		
		m_hLoginHandle=netsdk.CLIENT_LoginWithHighLevelSecurity(pstInParam, pstOutParam);
		if(m_hLoginHandle.longValue() == 0) {
			System.err.printf("Login Device[%s] Port[%d]Failed. %s\n", m_strIp, m_nPort, ToolKits.getErrorCodePrint());
		} else {
			System.out.println("Login Success [ " + m_strIp + " ]");
		}	
		
		return m_hLoginHandle.longValue() == 0? false:true;
	}
	
	/**
	 * 登出设备
	 */
	public static boolean logout() {
		if(m_hLoginHandle.longValue() == 0) {
			return false;
		}
		
		boolean bRet = netsdk.CLIENT_Logout(m_hLoginHandle);
		if(bRet) {			
			m_hLoginHandle.setValue(0);	
		}
		
		return bRet;
	}
}

DeviceInfo.java

package com.ruoyi.demo.module;
import com.ruoyi.lib.NetSDKLib;
import com.ruoyi.lib.NetSDKLib.LLong;


public class DeviceInfo {

    
    private String m_strIp;
    private int m_nPort;
    private String m_strUser;
    private String m_strPassword;
    private String m_srtId;
    

    public DeviceInfo(String m_strIp, int m_nPort, String m_strUser, String m_strPassword) {
        this.m_strIp = m_strIp; //设备ip
        this.m_nPort = m_nPort; //设备端口号
        this.m_strUser = m_strUser;  //设备登录用户名
        this.m_strPassword = m_strPassword;  //设备登陆密码
    }

    public DeviceInfo() {
    }

    //获取设备ID
    public String getM_srtId() {
        return m_srtId;
    }
    //设置设备ID
    public void setM_srtId(String m_srtId) {
        this.m_srtId = m_srtId;
    }
    //获取设备用户名
    public String getM_strUser() {
        return m_strUser;
    }
    //设置设备用户名
    public void setM_strUser(String m_strUser) {
        this.m_strUser = m_strUser;
    }
    //获取设备登录密码
    public String getM_strPassword() {
        return m_strPassword;
    }
    //设置设备登录密码
    public void setM_strPassword(String m_strPassword) {
        this.m_strPassword = m_strPassword;
    }
    //获取设备IP
    public String getM_strIp() {
        return m_strIp;
    }
    //设置设备IP
    public void setM_strIp(String m_strIp) {
        this.m_strIp = m_strIp;
    }
    //获取设备端口号
    public int getM_nPort() {
        return m_nPort;
    }
    //设置设备端口号
    public void setM_nPort(int m_nPort) {
        this.m_nPort = m_nPort;
    }

    public static final NetSDKLib netSdk = NetSDKLib.NETSDK_INSTANCE;
    //获取登录句柄
    public LLong getLoginHandle() {
        return loginHandle;
    }

    // 登陆句柄
    private LLong loginHandle = new LLong(0);

}

3.主动注册监听

在编写主动监听实现类之前我们=将内部用到的回调监听的功能都封装成了类这样我们调用起来方便一些
springboot中集成大华摄像头,java,网络,java,服务器
DisConnectCallBack.java(设备断线监听回调用于监听设备的在线状态,如果掉线进行消息回传)

package com.ruoyi.demo.frame;

import com.ruoyi.lib.NetSDKLib;
import com.sun.jna.Pointer;

/**
 * 设备断线回调
 */

public class DisConnectCallBack implements NetSDKLib.fDisConnect {

    public DisConnectCallBack() {
    }

    private static class CallBackHolder {
        private static DisConnectCallBack instance = new DisConnectCallBack();
    }

    public static DisConnectCallBack getInstance() {
        return CallBackHolder.instance;
    }

    public void invoke(NetSDKLib.LLong lLoginID, String pchDVRIP, int nDVRPort, Pointer dwUser) {
        System.out.printf("Device[%s] Port[%d] DisConnect!\n", pchDVRIP, nDVRPort);
    }
}

HaveReConnectCallBack.java(设备重连回调,用与监听离线设备重连的状态,将重连成功后的设备信息进行回传)

package com.ruoyi.demo.frame;

import com.ruoyi.lib.NetSDKLib;
import com.sun.jna.Pointer;

/**
 * 设备重连回调
 */
public class HaveReConnectCallBack implements NetSDKLib.fHaveReConnect {
    public HaveReConnectCallBack() {
    }

    private static class CallBackHolder {
        private static HaveReConnectCallBack instance = new HaveReConnectCallBack();
    }

    public static HaveReConnectCallBack getInstance() {
        return CallBackHolder.instance;
    }

    public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) {
        System.out.printf("ReConnect Device[%s] Port[%d]\n", pchDVRIP, nDVRPort);

    }
}

CbfRealDataCallBackEx.java(在摄像机工作过程中进行工作状态的监听,将设备数据进行回传)

package com.ruoyi.demo.frame;

import com.ruoyi.lib.NetSDKLib;
import com.sun.jna.Pointer;

/**
 * 实时监视数据回调函数--扩展(pBuffer内存由SDK内部申请释放)
 */

public class CbfRealDataCallBackEx implements NetSDKLib.fRealDataCallBackEx {
    private static class CallBackHolder {
        private static CbfRealDataCallBackEx instance = new CbfRealDataCallBackEx();
    }

    public static CbfRealDataCallBackEx getInstance() {
        return CallBackHolder.instance;
    }

    @Override
    public void invoke(NetSDKLib.LLong lRealHandle, int dwDataType, Pointer pBuffer, int dwBufSize, int param, Pointer dwUser) {
        if (0 != lRealHandle.longValue()) {
            switch (dwDataType) {
                case 0:

                    break;
                case 1:
                    //标准视频数据
                    System.out.println("[1]"+"码流大小为" + dwBufSize + "\n" + "码流类型为原始音视频混合数据");
                    break;
                case 2:
                    //yuv 数据
                    System.out.println("[2]"+"码流大小为" + dwBufSize + "\n" + "码流类型为原始音视频混合数据");
                    break;
                case 3:
                    //pcm 音频数据
                    System.out.println("[3]"+"码流大小为" + dwBufSize + "\n" + "码流类型为原始音视频混合数据");
                    break;
                case 4:
                    //原始音频数据
                    System.out.println("[4]"+"码流大小为" + dwBufSize + "\n" + "码流类型为原始音视频混合数据");
                    break;
                default:
                    break;
            }
        }
    }
}

Run.java(主动注册实现函数,进行主动注册监听)

package com.ruoyi.demo.frame;

import com.ruoyi.demo.module.AutoRegisterModule;
import com.ruoyi.demo.module.LoginModule;

import javax.swing.*;
import java.net.InetAddress;
import java.net.UnknownHostException;

public class Run extends JFrame {
    // 主动注册监听回调
    private final ServiceCB servicCallback = new ServiceCB();
    // 设备断线通知回调
    private final DisConnectCallBack disConnectCallback = new DisConnectCallBack();

    /**
     * 主动注册
     * @param ServiceAddress 服务器公网IP
     * @param ServicePort  服务器注册端口默认为9500
     * */
    public boolean AutoListen(String ServiceAddress , int ServicePort){
        //window系统下监听设备返回信息函数,必须增加不增加无法返回注册设备信息
        pack();
        //初始化
        LoginModule.init(disConnectCallback,null);
        if (ServiceAddress == null){
            System.out.println("service is null");
        }
        if (ServicePort == 0){
            System.out.println("service port is zero");
        }
        //进行主动注册开启服务
        return(AutoRegisterModule.startServer(ServiceAddress, ServicePort, servicCallback));
    }
    /**
     * 获取本地地址
     * @return 获取本机ip
     */
    public String getHostAddress() {
        String address = "";
        try {
            InetAddress inetAddress = InetAddress.getLocalHost();
            address = inetAddress.getHostAddress();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }

        return address;
    }
}

ServiceCB.java(主动监听回调函数)

package com.ruoyi.demo.frame;

import com.ruoyi.conversion.CaseMenu;
import com.ruoyi.controller.PreInfo;
import com.ruoyi.conversion.RealPlayByDataTypeDemo;
import com.ruoyi.demo.module.DeviceInfo;
import com.ruoyi.lib.NetSDKLib;
import com.ruoyi.service.instructService;
import com.sun.jna.Pointer;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.util.HashSet;
import java.util.Set;

/**
 * 注册服务监听回调
 */
@Component
public class ServiceCB implements NetSDKLib.fServiceCallBack,instructService {
    //设备信息类对象用于获取注册后设备信息
    DeviceInfo info = new DeviceInfo();

    /**
     * 前端发送信息
     *
     * @param preInfo  前端发送信息
     */
    private static final Set<PreInfo> preInfoSet = new HashSet<>();

    @Override
    public int invoke(NetSDKLib.LLong lHandle, String pIp, int wPort,
                      int lCommand, Pointer pParam, int dwParamLen,
                      Pointer dwUserData) {
        // 将 pParam 转化为序列号
        byte[] buffer = new byte[dwParamLen];
        pParam.read(0, buffer, 0, dwParamLen);
        String deviceId = "";
        try {
            deviceId = new String(buffer, "GBK").trim();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        System.out.printf("Register Device Info [Device address %s][port %s][DeviceID %s] \n", pIp, wPort, deviceId);

        switch (lCommand) {
            case NetSDKLib.EM_LISTEN_TYPE.NET_DVR_DISCONNECT: {  // 验证期间设备断线回调
                info.setM_strIp("");
                info.setM_nPort(0);
                break;
            }
            case NetSDKLib.EM_LISTEN_TYPE.NET_DVR_SERIAL_RETURN: { // 设备注册携带序列号
                info.setM_strIp(pIp);
                info.setM_nPort(wPort);
                info.setM_srtId(deviceId);

                /**
                 * 判断前端是否传输数据
                 * */
                if (preInfoSet.size() != 0) {
                    //这判断设备id是否相同
                    preInfoSet.forEach(preInfo -> {
                        if (info.getM_srtId().equals(preInfo.getPreDeviceId())) {
                            preInfoSet.remove(preInfo);
                            System.out.println("前端触发ID:" + preInfo.getPreDeviceId());
                            System.out.println("设备当前ID:" + info.getM_srtId());
                            if (preInfo.getPreDeviceId().equals(info.getM_srtId())) {

                                new Thread(() -> {
                                    System.out.println("开始录制");
                                    info.setM_strUser("自己的大华相机用户名");
                                    info.setM_strPassword("自己的大华相机密码");

                                    RealPlayByDataTypeDemo demo = new RealPlayByDataTypeDemo();

                                    demo.addItem(new CaseMenu.Item(demo, "mp4", "attachFlv"));
                                    demo.addItem(new CaseMenu.Item(demo, "stop", "detach"));

                                    /**
                                     * SDK初始化
                                     * @param disConnect 断线回调函数
                                     * @param haveReConnect 重连回调函数
                                     * */
                                    DisConnectCallBack disConnect = new DisConnectCallBack();
                                    HaveReConnectCallBack haveReConnect = new HaveReConnectCallBack();
                                    demo.init(disConnect, haveReConnect);

                                    System.out.println(info.getM_strIp());
                                    System.out.println(info.getM_nPort());

                                    if (demo.login(info.getM_strIp(), info.getM_nPort(), info.getM_strUser(), info.getM_strPassword(),2,null,info.getM_srtId())) {
                                        System.out.println("登录成功");
                                        // 登录成功后
                                        demo.run(0,info.getM_srtId());
                                        try {
                                            /**
                                             * 视频录制60s
                                             * */
                                            Thread.sleep(60 * 1000);
                                            demo.run(1,null);
                                        } catch (InterruptedException e) {
                                            e.printStackTrace();
                                        }
                                    }
                                    // 登出设备
                                    demo.logout();
                                    // 测试结束,释放sdk资源
//                          demo.clean();
                                    System.out.println("录制结束");
                                }).start();
                            } else {
                                System.out.println("设备id不一致登录失败!");
                            }
                        }
                    });
                }
                break;
            }
            default:
                break;
        }
        return lCommand;
    }

    @Override
    //向前端进行摄像机触发成功的消息提醒
    public void SendMessage(PreInfo info) {
        preInfoSet.add(info);
        System.out.println("成功触发!");
    }

}

4.剩余包含的实现类

剩下的实现类均是大华提供的SDK中本身具备的我们只需要复制即可
springboot中集成大华摄像头,java,网络,java,服务器
springboot中集成大华摄像头,java,网络,java,服务器
由于摄像机不再旁边无法进行测试。我会将源文件上传到资源,感兴趣的可自行下载。资源超链接

注意

主动注册使用了基于window.java的pack()监听函数实现实时监听设备的注册功能;在主动注册中的回调函数为多线程执行模式,每一个新注册的设备都单独运行在一个线程。
所有的业务逻辑需要书写在主动注册的回调函数中作为监听项。
在进行业务操作前必须要使用SDK初始化函数对SDK资源进行初始化,避免产生脏数据。
对于主动注册的登录操作需要使用“高安全的登录”方式,且需要传入设备ID作为参数,才可利用主动注册的登录方式成功登录服务器。
拉流保存的操作可以利用接口“NET_IN_REALPLAY_BY_DATA_TYPE(开始流数据解码)”与“NET_OUT_REALPLAY_BY_DATA_TYPE(停止流数据解码)”两个接口进行视频的录制与解码。(详细可见大华SDK开发文档)
部署服务器的时候需要注意服务器安全规则中的入站安全规则需要将“9500(主动注册端口)”,“Springboot访问端口xxxx”填入入站规则中,才可实现主动注册与远端触发功能。文章来源地址https://www.toymoban.com/news/detail-808002.html

到了这里,关于大华SDK+JAVA+4g网络摄像头进行二次开发的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • python_获取网络(大华)摄像头画面,并存储为图片和视频

    网络摄像头 USB摄像头

    2024年02月12日
    浏览(9)
  • Java对接大华云睿摄像头(人流统计/客流量统计)

    Java对接大华云睿摄像头(人流统计/客流量统计)

    环境准备(注意区分开发环境和正式服务器环境) 开发环境 win11 + IDEA + spring boot + mysql 正式服务器环境 Linux 下载开发环境和正式环境的SDK SDK下载地址:https://support.dahuatech.com/tools/sdkExploit ** 注意选择对应的语言和操作系统 ** 打开下载的(win64)SDK,查看人流统计部分实现逻

    2024年02月01日
    浏览(9)
  • 大华摄像头实时预览(spring boot+websocket+flv.js)Java开发

    大华摄像头实时预览(spring boot+websocket+flv.js)Java开发

    1.大华NetSDK_JAVA; 这里使用的是 Linux64的架包 2.websocket 前端使用的vue框架    3.flv.js的播放插件     4.大华摄像头提供的平台(后面称为官方平台) 根据大华《NetSDK_JAVA编程指导手册》的流程图 根据图可以得知关键流程为: 初始化sdk——登录设备——打开实时预览——设置视

    2024年02月04日
    浏览(13)
  • 大华摄像头有问题,海康摄像头也有问题

    买了个大华摄像头,除了抗噪方面效果不好,我是很满意的。前一段时间摄像头启动出了点问题(忘记拔掉SD卡),于是买了个海康的。 大华摄像头是3寸,海康是2寸。视频效果差多了。看来大有大的道理。 更可恨的是,萤石云不支持这个摄像头(说是要插录像机)。买的时

    2024年02月11日
    浏览(11)
  • web接入大华摄像头实时视频

    web接入大华摄像头实时视频

    目录 一、FFmpeg下载及配置​​​​ 二、nginx下载及配置 三、摄像rtsp取流 四、ffmpeg推流 五、html前端工作 地址:Download FFmpeg    下载并解压FFmpeg文件夹,配置环境变量:在“Path”变量原有变量值内容上加上d:ffmpegbin,验证:ffmpeg -version 出现版本号则成功。 这个我之前有,

    2023年04月20日
    浏览(12)
  • 基于海康SDK实现Python调用海康威视网络摄像头

    基于海康SDK实现Python调用海康威视网络摄像头

    本文参考博客,写得很好: Python调用海康威视网络相机之——python调用海康威视C++的SDK Python调用海康威视网络相机C++的SDK 写本文的目的,也是快速复盘,所以没有很详细 保存视频流到本地可参考下一篇:基于海康SDK实现Python保存海康威视网络摄像头拍摄的视频 Windows11 Vis

    2024年02月02日
    浏览(24)
  • ☀️将大华摄像头画面接入Unity 【1】配置硬件和初始化摄像头

    ☀️将大华摄像头画面接入Unity 【1】配置硬件和初始化摄像头

    目前的设想是后期采用网口供电的形式把画面传出来,所以这边我除了大华摄像头还准备了POE供电交换机,为了方便索性都用大华的了,然后全都连接电脑主机即可。 这边初始化摄像头需要用到大华的Configtool软件,下载地址如下。 全部-浙江大华技术股份有限公司 (dahuatech

    2024年02月21日
    浏览(8)
  • 大华摄像头windows、linuxJavaSDK开发使用

    大华摄像头windows、linuxJavaSDK开发使用

    本文档主要介绍 SDK 接口参考信息,包括主要功能、接口函数和回调函数。 主要功能包括:SDK 初始化、设备登录、实时预览、云台控制、语音对讲、报警监听、智能订阅、 录像回放和录像下载等。 根据环境不同,开发包包含的文件会不同,具体如下所示。 Windows 开发包所包

    2024年01月20日
    浏览(11)
  • unity海康威视原生SDK拉取网络摄像头画面,并展示在一个Material上

    unity海康威视原生SDK拉取网络摄像头画面,并展示在一个Material上

    untiy版本是2019.4,低版本会有问题,速度比UMP插件快得多 原理是使用sdk获取视频流,格式为YUV,然后分离YUV通道到三张不同的Texture2D上,通过shader将三个通道重新输出为原始图像。 我将所用的各个部分已经整理成一个压缩包,免积分下载 压缩包结构如下 使用步骤 1 DLL:放在

    2024年02月13日
    浏览(8)
  • 海康摄像头4G内网连接方案

    海康摄像头4G内网连接方案

    放在内网中的海康摄像头需要通过4G路由器远程访问,调研了几种方案: 这个是海康特有的方案,其他摄像头是否有类似的方案未知。 在萤石云注册账号,过程略 我注册账号以后,登陆时提示: 当前浏览器版本不支持视频插件,请采用IE浏览器(ie8以上)或者下载萤石工作

    2024年02月10日
    浏览(5)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包