123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- package com.persagy.cameractl.controller;
- import java.io.BufferedReader;
- import java.io.File;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.util.ArrayList;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.web.bind.annotation.RequestBody;
- import com.persagy.cameractl.service.HCNetSDKWindows;
- import com.persagy.cameractl.utils.Camera;
- import com.persagy.cameractl.utils.OtherTools;
- import com.persagy.cameractl.utils.ResultClass;
- import com.sun.jna.NativeLong;
- import com.sun.jna.ptr.IntByReference;
- import cn.hutool.core.date.DateUtil;
- //@RestController
- public class TestController {
- public static Logger logger = LoggerFactory.getLogger(TestController.class);
-
- private volatile boolean isInit = false;
-
- private volatile HCNetSDKWindows hcNetSdk;
-
- //@RequestMapping(value = "/test", method = RequestMethod.POST)
- public ResultClass hello(@RequestBody Camera camera) {
- ResultClass returnResult = new ResultClass();
- String targetFile = OtherTools.getVideoFilePath();
- returnResult.name = false;
- if (targetFile.equals("")) {
- returnResult.reason = "回放文件名称生成失败";
- return returnResult;
- }
- logger.info("playback path: " + targetFile);
-
- File mp4File = new File(targetFile);
- String targetFileName = mp4File.getName();
- File fileParent = mp4File.getParentFile();
- String targetFilePath = fileParent.getPath();
-
- // SDK初始化
- boolean init = this.init();
- if (!init) {
- returnResult.reason = "SDK初始化失败";
- return returnResult;
- }
-
- // 文件下载,这里不使用原文件,因为还需要转码
- String downloadFile = targetFilePath + "/_" + targetFileName;
- String downloadVideo = this.downloadVideo(camera, downloadFile);
- if (!"true".equals(downloadVideo)) {
- returnResult.reason = downloadVideo;
- return returnResult;
- }
-
- try {
- logger.info("-------- start transcoding --------");
- Map<String, String> data = new HashMap<String, String>(4);
- convetorVideo(downloadFile, targetFile);
- data.put("url", OtherTools.playMp4RootUrl + OtherTools.getMp4NamePrefix(targetFileName));
- returnResult.resultData = data;
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- returnResult.name = true;
- returnResult.reason = "回放文件生成成功";
- return returnResult;
- }
-
- /**
- * 按时间进行视频下载,实现回放
- *
- * @param Camera 请求参数
- * @param filePath 文件路径,包含文件名称及后缀
- * @param channel 通道号
- * @return
- */
- private String downloadVideo(Camera camera, String filePath) {
- // 注册设备 -1表示失败,其他值表示返回的用户ID值。接口返回失败请调用NET_DVR_GetLastError获取错误码,通过错误码判断出错原因。
- HCNetSDKWindows.NET_DVR_DEVICEINFO_V30 m_strDeviceInfo = new HCNetSDKWindows.NET_DVR_DEVICEINFO_V30();
- NativeLong lUserID = hcNetSdk.NET_DVR_Login_V30(camera.cameraIp, (short) camera.cameraPort, camera.userName, camera.password, m_strDeviceInfo);
- // 注册失败
- if (lUserID.longValue() == -1) {
- int errCode = hcNetSdk.NET_DVR_GetLastError();
- // 返回失败时的错误码
- return "设备注册失败,失败码:" + errCode;
- }
-
- // 准备文件下载
- NativeLong loadHandle = hcNetSdk.NET_DVR_GetFileByTime(lUserID, new NativeLong(camera.channel), getHkTime(camera.startDateStr), getHkTime(camera.endDateStr), filePath);
- logger.info("hksdk playback file status: " + loadHandle.longValue());
-
- if (loadHandle.longValue() >= 0) {
- // 判断文件夹是否存在
- File files = new File(filePath);
- if(!files.exists()){
- files.mkdirs();
- }
-
- // 发送回放开始的信号
- hcNetSdk.NET_DVR_PlayBackControl(loadHandle, HCNetSDKWindows.NET_DVR_PLAYSTART, 0, null);
-
- IntByReference pos = new IntByReference();
- while (true) {
- boolean backFlag = hcNetSdk.NET_DVR_PlayBackControl(loadHandle, HCNetSDKWindows.NET_DVR_PLAYGETPOS, 0, pos);
- // 回放下载异常,直接跳出
- if (!backFlag) {
- logger.warn("hksdk download exception");
- break;
- }
-
- int produce = pos.getValue();
- if (produce > 0) {
- logger.info("hksdk download progress: " + produce + "%");
- }
-
- if (produce == 100) {//下载成功
- hcNetSdk.NET_DVR_StopGetFile(loadHandle);
- hcNetSdk.NET_DVR_Logout(lUserID);
- logger.info("hksdk exit status: " + hcNetSdk.NET_DVR_GetLastError());
- //hcNetSdk.NET_DVR_Cleanup(); // 这里不进行释放
- return "true";
- }
- if (produce > 100) { //下载失败,异常终止,这时返回true
- hcNetSdk.NET_DVR_StopGetFile(loadHandle);
- logger.info("hksdk exit status: " + hcNetSdk.NET_DVR_GetLastError());
- hcNetSdk.NET_DVR_Logout(lUserID);
- return "true";
- }
- }
- }
-
- int net_DVR_GetLastError = hcNetSdk.NET_DVR_GetLastError();
- logger.error("hksdk download failed: " + net_DVR_GetLastError);
- return "文件下载失败,失败码:" + net_DVR_GetLastError;
- }
- /**
- * 初始化SDK
- *
- * @return
- */
- private boolean init() {
- if (!isInit) {
- // 初始化
- hcNetSdk = HCNetSDKWindows.INSTANCE;
- isInit = hcNetSdk.NET_DVR_Init();
- }
- return isInit;
- }
-
- /**
- * 获取海康录像机格式的时间
- */
- private HCNetSDKWindows.NET_DVR_TIME getHkTime(String timeParam) {
- Date time = DateUtil.parse(timeParam);
-
- HCNetSDKWindows.NET_DVR_TIME dvrTime = new HCNetSDKWindows.NET_DVR_TIME();
- dvrTime.dwYear = DateUtil.year(time);
- dvrTime.dwMonth = DateUtil.month(time) + 1;
- dvrTime.dwDay = DateUtil.dayOfMonth(time);
- dvrTime.dwHour = DateUtil.hour(time, true);
- dvrTime.dwMinute = DateUtil.minute(time);
- dvrTime.dwSecond = DateUtil.second(time);
-
- return dvrTime;
- }
-
- /**
- * 文件转码
- *
- * @param videoInputFile
- * @param videoOutFile
- * @throws Exception
- */
- public static void convetor(String videoInputFile, String videoOutFile) throws Exception {
- File sourceFile = new File(videoInputFile);
- // 把源MP4转为页面上可播放的MP4
- Runtime run = Runtime.getRuntime();
- Process p = run.exec("ffmpeg -i \"" + videoInputFile + "\" -c copy -y \"" + videoOutFile + "\"");
- // 读取标准输入流、输出流,防止进程阻塞
- // 标准输入流(必须写在 waitFor 之前)
- String inputStreamStr = OtherTools.consumeInputStream(p.getInputStream());
- // 标准错误流(必须写在 waitFor 之前)
- String errStreamStr = OtherTools.consumeInputStream(p.getErrorStream());
- int retCode = p.waitFor();
- if (retCode != 0) {
- String errStr = errStreamStr != null ? errStreamStr : inputStreamStr;
- logger.error("ffmpeg转换mp4时失败,错误信息:" + errStr);
- }
- p.destroy();
- sourceFile.delete();
- }
-
- /**
- * 文件转码
- *
- * @param videoInputFile
- * @param videoOutFile
- * @throws Exception
- */
- @SuppressWarnings("unused")
- public static void convetorVideo(String videoInputFile, String videoOutFile) throws Exception {
- List<String> command = new ArrayList<String>();
- command.add("ffmpeg");
- command.add("-i");
- command.add(videoInputFile);
- command.add("-c");
- command.add("copy");
- command.add("-an");
- command.add(videoOutFile);
- ProcessBuilder builder = new ProcessBuilder(command);
- Process process = null;
- try {
- process = builder.start();
- } catch (IOException e) {
- 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();
- }
-
- //File sourceFile = new File(videoInputFile);
- //sourceFile.delete();
- }
-
- public static void main(String[] args) throws Exception {
- //convetor("C:\\Users\\25694\\Desktop\\testffmepg\\sss.mp4", "C:\\Users\\25694\\Desktop\\testffmepg\\demo.mp4");
- convetorVideo("C:\\Users\\25694\\Desktop\\testffmepg\\sss.mp4", "C:\\Users\\25694\\Desktop\\testffmepg\\demoss.mp4");
- }
-
- }
|