一、下载SDK
在 海康开放平台 下载最新的网络设备sdk(有windows和linux)
解压下载的sdk,将库文件目录下的文件放到一个固定地址,后期要根据这个地址来加载dll文件(windows和linux加载的文件不同,如需适配2个平台,需要在代码里面做如下判断)
//加载海康ddl
if (OsInfoUtil.isWindows()) {
hCNetSDK = (HCNetSDK) Native.loadLibrary("E:\\hikvision\\lib\\HCNetSDK.dll", HCNetSDK.class);
} else {
hCNetSDK = (HCNetSDK) Native.loadLibrary("/usr/local/hikvision/lib/libhcnetsdk.so", HCNetSDK.class);
}
二、搭建项目
1、新建springboot项目,在resources下创建lib文件夹将sdk的java demo示例文件中的examples.jar、jna.jar拷贝到该文件夹下
2、在pom文件里面加入如下内容,引入jar包3
<!--海康威视-->
<dependency>
<groupId>net.java.jna</groupId>
<artifactId>jna</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/jna.jar</systemPath>
</dependency>
<dependency>
<groupId>net.java.examples</groupId>
<artifactId>examples</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/examples.jar</systemPath>
</dependency>
3、将java demo演示项目的HCNetSDK.java文件拷贝到当前项目中,后续接口开发均是基于该文件
4、视频转码
在截取了视频保存到本地之后,发现不能直接打开,只能通过海康的VSPlayer软件打开,所以需要通过ffmpeg进行转码,转码工具内容如下
package com.hikvision.nvr.util;
import cn.hutool.core.date.DateUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
@Component
public class FFMpegUtil {
//windows下ffmpeg的路径
@Value("${ffmpeg.windows}")
private String ffmpegEXE_windows;
//Linux下ffmpeg的路径
@Value("${ffmpeg.linux}")
private String ffmpegEXE_linux;
private String ffmpegPath;
@PostConstruct
private void getFmpeg(){
if(OsInfoUtil.isWindows()){
ffmpegPath = ffmpegEXE_windows;
}else {
ffmpegPath = ffmpegEXE_linux;
}
}
/**
* @param videoInputPath 视频的输入路径 linux真实路径
* @param videoOutPath 视频的输出路径 linux真实路径
* @throws Exception
*/
// 拷贝视频,并指定新的视频的名字以及格式
// ffmpeg.exe -i old.mp4 new.avi
public void convetor(String videoInputPath, String videoOutPath) throws Exception {
String videoCommend = ffmpegPath + " -y -i " + videoInputPath + " -b:v 500k -s 960x540 -threads 8 -preset ultrafast -strict -2 " + videoOutPath;
System.out.println(videoCommend);
try {
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(videoCommend);
InputStream stderr = proc.getErrorStream();
InputStreamReader isr = new InputStreamReader(stderr);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ( (line = br.readLine()) != null) {
System.out.println(line);
}
int exitVal = proc.waitFor();
System.out.println("Process exitValue: " + exitVal);
} catch (Throwable t) {
t.printStackTrace();
}
}
/**
* 多视频拼接合并
*
* @param videoResourcesPathList 视频文件路径的List
*/
public void mergeVideos(List<String> videoResourcesPathList,String videoPath) {
String videosPath= videoPath+"file.txt";
try(PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(videosPath, false)))) {
for (String video:videoResourcesPathList) {
writer.println("file '"+video+"'");
}
}catch (IOException e) {
System.err.println(e);
}
List<String> command = new ArrayList<>();
command.add(ffmpegPath);
command.add("-f");
command.add("concat");
command.add("-safe");
command.add("0");
command.add("-i");
command.add(videosPath);
command.add("-c");
command.add("copy");
command.add(videoPath + "merge.mp4");
commandStart(command);
}
/**
* 调用命令行执行
*
* @param command 命令行参数
*/
public static void commandStart(List<String> command) {
command.forEach(v -> System.out.print(v + " "));
System.out.println();
System.out.println();
ProcessBuilder builder = new ProcessBuilder();
//正常信息和错误信息合并输出
builder.redirectErrorStream(true);
builder.command(command);
//开始执行命令
Process process = null;
try {
process = builder.start();
//如果你想获取到执行完后的信息,那么下面的代码也是需要的
String line = "";
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
不过对于大的视频文件,这个转码速度是有点慢的,即使用了多线程命令,依旧很慢,暂时没找到解决方案