由于之前公司项目中需要用到海康威视的摄像头,所以之前也在网上调研过,虽然也是给我一点启示,但是还是满足不了很多疑问,下面是自己踩的坑
- 首先下载官方的sdk,注意请先确认自己是linux版本 还是windows版本的,sdk是有差异的,调用的插件文件也是不一样的。官网下载自己对应的sdk
- 解压完打开最后一个txt文件,按照说明将制定文件copy到指定目录
- 然后将实例demo导入到IDE中,注意examples.jar和jna.jar要导入到项目中,然后打开HCNetSDK.java,找到
HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary("C:\\Users\\Administrator\\Desktop\\项目资料\\摄像头sdk\\CH-HCNetSDK(Windows64)V5.3.1.21_build20170811\\Demo示例\\4- Java 开发示例\\ClientDemo-NetBeansPro\\HCNetSDK",
HCNetSDK.class);
我这里HCNetSDK是放到c盘的目录下面的,根据自己的目录调整路径,然后启动项目就可以看demo啦。如图
输入摄像头的信息就可以点击预览了。
- 下面是我在开发过程中遇到的问题,和解决方案,希望对大家有所帮助
在客流量统计模块,按照开发文档的流程,编写了demo发现回调函数不走
第一种原因是,完全按照官方文档来,布防以后,回调函数还没来得及执行,就直接撤防了,导致回调函数不走,这个要根据自己的情况进行撤防和释放资源。
第二种原因是摄像头没有摄像硬件布防,登录网站
http://摄像头ip/doc/page/config.asp进行配置(配置教程)
- 视频下载模块,因为我们是用CVR将多个摄像头上面的情况,在视频下载中有个通道号设置
HCNetSDK.NET_DVR_PLAYCOND netDvrPlaycond = new HCNetSDK.NET_DVR_PLAYCOND();
//通道号
netDvrPlaycond.dwChannel = Integer.valueOf(1);
netDvrPlaycond.struStartTime = struStartTime;
netDvrPlaycond.struStopTime = struStopTime;
这个netDvrPlaycond.dwChannel设置非常重要,每个摄像头将视频传到cvr中的时候都有一个唯一的通道号,我们就是根据这个通道号去查询对应的摄像头视频,去保存到我们自己服务器上。
- 我们的需求是将下载的视频在页面上直接播放,但是在播放的时候发现播放不出来,尝试了各种视频插件都不行。在大佬的指导下才知道原来是视频的音频格式不对。下面大佬的问答
因为你的音频不是mpeg4容器支持的音频格式。通过mediainfo分析可知,你的音频格式是pcm_alaw,并且还有一行警告信息:
FileExtension_Invalid : mpeg mpg m2p vob vro pss evo
你的视频格式应该是MPEG-PS格式,但是后缀却是mp4,其实是一个非法的MP4。mediainfo还会告诉你合法的后缀应该是上述那几个。由于你的音频格式根本不被浏览器支持,但是视频格式是被浏览器支持的(H.264/AVC)。那么解决方案其实也简单,抽调音频即可。参考ffmpeg命令行(不转码,直接复制流):
ffmpeg -i demo.mp4 -c copy -an demp_enc.mp4
速度很快,使用-an参数屏蔽掉音频流,将封装格式转为mp4。再次用mediainfo查看,格式已经显示MPEG-4,是一个标准的mp4容器封装了,在当今主流的浏览器都能直接播放。
下载ffmpeg解码工具官网下载ffmpeg,解压安装找到ffmpeg.exe。下面是我的java测试代码
private static String ffmpegEXE = "E:\\ffmpeg-20190425-1ae5a64-win64-static\\bin\\ffmpeg.exe";
public static void main(String[] args) {
try {
convetor("E:\\ffmpeg-20190425-1ae5a64-win64-static\\bin\\demo.mp4","E:\\ffmpeg-20190425-1ae5a64-win64-static\\bin\\test.mp4");
} catch (Exception e) {
e.printStackTrace();
}
}
//ffmpeg -i demo.mp4 -c copy -an demp_enc.mp4
public static void convetor(String videoInputPath, String videoOutPath) throws Exception {
List<String> command = new ArrayList<String>();
command.add(ffmpegEXE);
command.add("-i");
command.add(videoInputPath);
command.add("-c");
command.add("copy");
command.add("-an");
command.add(videoOutPath);
ProcessBuilder builder = new ProcessBuilder(command);
Process process = null;
try {
process = builder.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 使用这种方式会在瞬间大量消耗CPU和内存等系统资源,所以这里我们需要对流进行处理
InputStream errorStream = process.getErrorStream();
InputStreamReader inputStreamReader = new InputStreamReader(errorStream);
BufferedReader br = new BufferedReader(inputStreamReader);
String line = "";
while ((line = br.readLine()) != null) {
}
if (br != null) {
br.close();
}
if (inputStreamReader != null) {
inputStreamReader.close();
}
if (errorStream != null) {
errorStream.close();
}
}
运行完就会多一个视频文件,然后就可以用通用播放器播放这个新的视频了,至于老的视频任凭自己需求处理掉就行啦
- 最后在附上官方开发人员的邮箱 sdk@hikvision.com 。感谢海康威视在开发中对我的疑问做出解答