| | |
| | | import com.ard.common.core.exception.ServiceException; |
| | | import com.ard.common.core.exception.device.CameraSDKException; |
| | | import com.ard.common.core.utils.StringUtils; |
| | | import com.ard.common.core.utils.file.FileMultipartFile; |
| | | import com.ard.common.core.utils.file.FileUtils; |
| | | import com.ard.common.core.utils.file.MimeTypeUtils; |
| | | import com.ard.common.redis.service.RedisService; |
| | |
| | | import com.ard.work.sdk.model.PtzScope; |
| | | import com.ard.work.sdk.service.CameraSDK; |
| | | import com.ard.work.utils.FFmpegUtils; |
| | | import com.ard.work.utils.file.MultipartFileUtil; |
| | | import com.ard.work.utils.gis.GisUtil; |
| | | import com.sun.jna.Native; |
| | | import com.sun.jna.Pointer; |
| | |
| | | import org.springframework.context.ApplicationEventPublisher; |
| | | import org.springframework.util.StopWatch; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.awt.geom.Point2D; |
| | | import java.io.ByteArrayInputStream; |
| | | import java.io.File; |
| | |
| | | String cameraId = cmd.getCameraId(); |
| | | Integer chanNo = cmd.getChanNo(); |
| | | int userId = cmd.getLoginId().intValue(); |
| | | |
| | | NET_DVR_PTZPOS m_ptzPosCurrent = new NET_DVR_PTZPOS(); |
| | | Pointer point = m_ptzPosCurrent.getPointer(); |
| | | IntByReference ibrBytesReturned = new IntByReference(0); |
| | | m_ptzPosCurrent.write(); |
| | | boolean bool = hCNetSDK.NET_DVR_GetDVRConfig(userId, HCNetSDK.NET_DVR_GET_PTZPOS, chanNo, point, |
| | | m_ptzPosCurrent.size(), ibrBytesReturned); |
| | | if (!bool) { |
| | | int errorCode = hCNetSDK.NET_DVR_GetLastError(); |
| | | String errorDesc = SdkErrorCodeEnum.getDescByCode(errorCode); |
| | | String errorMsg = String.format("获取ptz失败,错误码:%s,原因:%s", errorCode, errorDesc); |
| | | log.warn(errorMsg); |
| | | return null; |
| | | ArdCamera camera = getCamera(cameraId); |
| | | if ("1".equals(camera.getType())) { |
| | | return getPtzHigh(cmd); |
| | | } else { |
| | | NET_DVR_PTZPOS m_ptzPosCurrent = new NET_DVR_PTZPOS(); |
| | | Pointer point = m_ptzPosCurrent.getPointer(); |
| | | IntByReference ibrBytesReturned = new IntByReference(0); |
| | | m_ptzPosCurrent.write(); |
| | | boolean bool = hCNetSDK.NET_DVR_GetDVRConfig(userId, HCNetSDK.NET_DVR_GET_PTZPOS, chanNo, point, |
| | | m_ptzPosCurrent.size(), ibrBytesReturned); |
| | | if (!bool) { |
| | | int errorCode = hCNetSDK.NET_DVR_GetLastError(); |
| | | String errorDesc = SdkErrorCodeEnum.getDescByCode(errorCode); |
| | | String errorMsg = String.format("获取ptz失败,错误码:%s,原因:%s", errorCode, errorDesc); |
| | | log.warn(errorMsg); |
| | | return null; |
| | | } |
| | | m_ptzPosCurrent.read(); |
| | | // DecimalFormat df = new DecimalFormat("0.0");//设置保留位数 |
| | | //16进制转Integer后除10,保留小数点1位 |
| | | //实际显示的PTZ值是获取到的十六进制值的十分之一, |
| | | //如获取的水平参数P的值是0x1750,实际显示的P值为175度; |
| | | //获取到的垂直参数T的值是0x0789,实际显示的T值为78.9度; |
| | | //获取到的变倍参数Z的值是0x1100,实际显示的Z值为110倍。 |
| | | BigDecimal b = |
| | | BigDecimal.valueOf((float) Integer.parseInt(Integer.toHexString(m_ptzPosCurrent.wPanPos)) / 10); |
| | | BigDecimal c = |
| | | BigDecimal.valueOf((float) Integer.parseInt(Integer.toHexString(m_ptzPosCurrent.wTiltPos)) / 10); |
| | | BigDecimal d = |
| | | BigDecimal.valueOf((float) Integer.parseInt(Integer.toHexString(m_ptzPosCurrent.wZoomPos)) / 10); |
| | | float p = b.setScale(1, RoundingMode.HALF_UP).floatValue(); |
| | | float t = c.setScale(1, RoundingMode.HALF_UP).floatValue(); |
| | | float z = d.setScale(1, RoundingMode.HALF_UP).floatValue(); |
| | | return new PtzDto(p, t, z); |
| | | } |
| | | m_ptzPosCurrent.read(); |
| | | // DecimalFormat df = new DecimalFormat("0.0");//设置保留位数 |
| | | //16进制转Integer后除10,保留小数点1位 |
| | | //实际显示的PTZ值是获取到的十六进制值的十分之一, |
| | | //如获取的水平参数P的值是0x1750,实际显示的P值为175度; |
| | | //获取到的垂直参数T的值是0x0789,实际显示的T值为78.9度; |
| | | //获取到的变倍参数Z的值是0x1100,实际显示的Z值为110倍。 |
| | | BigDecimal b = BigDecimal.valueOf((float) Integer.parseInt(Integer.toHexString(m_ptzPosCurrent.wPanPos)) / 10); |
| | | BigDecimal c = BigDecimal.valueOf((float) Integer.parseInt(Integer.toHexString(m_ptzPosCurrent.wTiltPos)) / 10); |
| | | BigDecimal d = BigDecimal.valueOf((float) Integer.parseInt(Integer.toHexString(m_ptzPosCurrent.wZoomPos)) / 10); |
| | | float p = b.setScale(1, RoundingMode.HALF_UP).floatValue(); |
| | | float t = c.setScale(1, RoundingMode.HALF_UP).floatValue(); |
| | | float z = d.setScale(1, RoundingMode.HALF_UP).floatValue(); |
| | | return new PtzDto(p, t, z); |
| | | } |
| | | |
| | | /** |
| | |
| | | * @author 刘苏义 |
| | | * @date 2024/9/5 17:00 |
| | | */ |
| | | @Override |
| | | public PtzDto getPtzHigh(CameraCmd cmd) { |
| | | private PtzDto getPtzHigh(CameraCmd cmd) { |
| | | try { |
| | | String cameraId = cmd.getCameraId(); |
| | | Integer chanNo = cmd.getChanNo(); |
| | |
| | | Integer channelNum = cmd.getChanNo(); |
| | | PtzDto ptzDto = cmd.getPtzDto(); |
| | | int userId = cmd.getLoginId().intValue(); |
| | | NET_DVR_PTZPOS m_ptzPosCurrent = new NET_DVR_PTZPOS(); |
| | | m_ptzPosCurrent.wAction = 1; |
| | | try { |
| | | String p = String.valueOf((int) (ptzDto.getP() * 10)); |
| | | String t = String.valueOf((int) (ptzDto.getT() * 10)); |
| | | String z = String.valueOf((int) (ptzDto.getZ() * 10)); |
| | | m_ptzPosCurrent.wPanPos = (short) (Integer.parseInt(p, 16)); |
| | | m_ptzPosCurrent.wTiltPos = (short) (Integer.parseInt(t, 16)); |
| | | m_ptzPosCurrent.wZoomPos = (short) (Integer.parseInt(z, 16)); |
| | | Pointer point = m_ptzPosCurrent.getPointer(); |
| | | m_ptzPosCurrent.write(); |
| | | boolean bool = hCNetSDK.NET_DVR_SetDVRConfig(userId, NET_DVR_SET_PTZPOS, channelNum, point, |
| | | m_ptzPosCurrent.size()); |
| | | if (!bool) { |
| | | int errorCode = hCNetSDK.NET_DVR_GetLastError(); |
| | | String errorDesc = SdkErrorCodeEnum.getDescByCode(errorCode); |
| | | String errorMsg = String.format("设置PTZ参数失败,错误码:%s,原因:%s", errorCode, errorDesc); |
| | | log.warn(errorMsg); |
| | | ArdCamera camera = getCamera(cameraId); |
| | | if ("1".equals(camera.getType())) { |
| | | DeviceCFG systemInfo = getSystemInfo(cmd); |
| | | if (systemInfo != null && "5.5.112".equals(systemInfo.getDwSoftwareVersion())) { |
| | | return setPtzHighT(cmd); |
| | | } |
| | | return setPtzHigh(cmd); |
| | | } else { |
| | | NET_DVR_PTZPOS m_ptzPosCurrent = new NET_DVR_PTZPOS(); |
| | | m_ptzPosCurrent.wAction = 1; |
| | | try { |
| | | String p = String.valueOf((int) (ptzDto.getP() * 10)); |
| | | String t = String.valueOf((int) (ptzDto.getT() * 10)); |
| | | String z = String.valueOf((int) (ptzDto.getZ() * 10)); |
| | | m_ptzPosCurrent.wPanPos = (short) (Integer.parseInt(p, 16)); |
| | | m_ptzPosCurrent.wTiltPos = (short) (Integer.parseInt(t, 16)); |
| | | m_ptzPosCurrent.wZoomPos = (short) (Integer.parseInt(z, 16)); |
| | | Pointer point = m_ptzPosCurrent.getPointer(); |
| | | m_ptzPosCurrent.write(); |
| | | boolean bool = hCNetSDK.NET_DVR_SetDVRConfig(userId, NET_DVR_SET_PTZPOS, channelNum, point, |
| | | m_ptzPosCurrent.size()); |
| | | if (!bool) { |
| | | int errorCode = hCNetSDK.NET_DVR_GetLastError(); |
| | | String errorDesc = SdkErrorCodeEnum.getDescByCode(errorCode); |
| | | String errorMsg = String.format("设置PTZ参数失败,错误码:%s,原因:%s", errorCode, errorDesc); |
| | | log.warn(errorMsg); |
| | | return false; |
| | | } |
| | | return true; |
| | | } catch (Exception ex) { |
| | | log.error(ex.getMessage()); |
| | | return false; |
| | | } |
| | | return true; |
| | | } catch (Exception ex) { |
| | | log.error(ex.getMessage()); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | |
| | | * @author 刘苏义 |
| | | * @date 2024/9/5 17:04 |
| | | */ |
| | | @Override |
| | | public Boolean setPtzHighT(CameraCmd cmd) { |
| | | private Boolean setPtzHighT(CameraCmd cmd) { |
| | | String cameraId = cmd.getCameraId(); |
| | | Integer chanNo = cmd.getChanNo(); |
| | | PtzDto ptzDto = cmd.getPtzDto(); |
| | |
| | | } |
| | | |
| | | //非透传 旧设备使用 新固件会导致2通道不自动聚焦 |
| | | @Override |
| | | public Boolean setPtzHigh(CameraCmd cmd) { |
| | | private Boolean setPtzHigh(CameraCmd cmd) { |
| | | String cameraId = cmd.getCameraId(); |
| | | Integer chanNo = cmd.getChanNo(); |
| | | PtzDto ptzDto = cmd.getPtzDto(); |
| | |
| | | String type = cmd.getType() == null ? "other" : cmd.getType(); |
| | | String bucketName = cmd.getBucketName() == null ? "pic" : cmd.getBucketName(); |
| | | int userId = cmd.getLoginId().intValue(); |
| | | |
| | | //图片信息 |
| | | NET_DVR_JPEGPARA jpeg = new NET_DVR_JPEGPARA(); |
| | | //设置图片分辨率 |
| | |
| | | IntByReference a = new IntByReference(); |
| | | //设置图片大小 |
| | | ByteBuffer jpegBuffer = ByteBuffer.allocate(1024 * 1024); |
| | | // 抓图到内存,单帧数据捕获并保存成JPEG存放在指定的内存空间中 |
| | | // 抓图到内存 |
| | | boolean bool = hCNetSDK.NET_DVR_CaptureJPEGPicture_NEW(userId, chanNo, jpeg, jpegBuffer, 1024 * 1024, a); |
| | | |
| | | if (!bool) { |
| | | int errorCode = hCNetSDK.NET_DVR_GetLastError(); |
| | | String errorDesc = SdkErrorCodeEnum.getDescByCode(errorCode); |
| | |
| | | log.warn(errorMsg); |
| | | return ""; |
| | | } |
| | | |
| | | log.debug("hikSdk(抓图)-结果状态值(0表示成功):{}", hCNetSDK.NET_DVR_GetLastError()); |
| | | byte[] array = jpegBuffer.array(); |
| | | //存储到minio |
| | | String objectName = cameraId + "_" + chanNo + ".jpeg"; |
| | | InputStream inputStream = new ByteArrayInputStream(array); |
| | | String url = ""; |
| | | MultipartFile multipartFile = MultipartFileUtil.inputStreamToMultipartFile(inputStream, objectName, |
| | | MimeTypeUtils.IMAGE_JPEG); |
| | | R<SysFile> sysFileR = remoteFileService.upload(multipartFile, bucketName, type); |
| | | if (sysFileR.getCode() == R.SUCCESS) { |
| | | url = sysFileR.getData().getUrl(); |
| | | log.debug("上传文件成功:{}", url); |
| | | |
| | | // 获取实际图片数据 |
| | | int actualLength = a.getValue(); |
| | | byte[] imageBytes; |
| | | if (actualLength > 0 && actualLength < 1024 * 1024) { |
| | | imageBytes = new byte[actualLength]; |
| | | System.arraycopy(jpegBuffer.array(), 0, imageBytes, 0, actualLength); |
| | | } else { |
| | | imageBytes = jpegBuffer.array(); |
| | | } |
| | | |
| | | // 存储到minio |
| | | String objectName = cameraId + "_" + chanNo + ".jpeg"; |
| | | String url = ""; |
| | | File tempFile = null; |
| | | |
| | | try { |
| | | // 创建临时文件 |
| | | tempFile = File.createTempFile("snap_", ".jpeg"); |
| | | java.nio.file.Files.write(tempFile.toPath(), imageBytes); |
| | | |
| | | // 使用 FileMultipartFile 转换 |
| | | MultipartFile multipartFile = new FileMultipartFile(tempFile, objectName, MimeTypeUtils.IMAGE_JPEG); |
| | | |
| | | R<SysFile> sysFileR = remoteFileService.upload(multipartFile, bucketName, type); |
| | | if (sysFileR.getCode() == R.SUCCESS) { |
| | | url = sysFileR.getData().getUrl(); |
| | | log.debug("上传文件成功:{}", url); |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("上传失败", e); |
| | | } finally { |
| | | // 删除临时文件 |
| | | if (tempFile != null && tempFile.exists()) { |
| | | tempFile.delete(); |
| | | } |
| | | } |
| | | |
| | | return url; |
| | | } |
| | | |
| | |
| | | Integer chanNo = cmd.getChanNo(); |
| | | String type = cmd.getType() == null ? "other" : cmd.getType(); |
| | | Integer userId = cmd.getLoginId().intValue(); |
| | | |
| | | //图片信息 |
| | | NET_DVR_JPEGPARA jpeg = new NET_DVR_JPEGPARA(); |
| | | //设置图片分辨率 |
| | |
| | | ByteBuffer jpegBuffer = ByteBuffer.allocate(1024 * 1024); |
| | | // 抓图到内存,单帧数据捕获并保存成JPEG存放在指定的内存空间中 |
| | | boolean bool = hCNetSDK.NET_DVR_CaptureJPEGPicture_NEW(userId, chanNo, jpeg, jpegBuffer, 1024 * 1024, a); |
| | | |
| | | if (!bool) { |
| | | int errorCode = hCNetSDK.NET_DVR_GetLastError(); |
| | | String errorDesc = SdkErrorCodeEnum.getDescByCode(errorCode); |
| | |
| | | log.warn(errorMsg); |
| | | return ""; |
| | | } |
| | | byte[] array = jpegBuffer.array(); |
| | | InputStream inputStream = new ByteArrayInputStream(array); |
| | | String url = ""; |
| | | MultipartFile multipartFile = MultipartFileUtil.inputStreamToMultipartFile(inputStream, objectName, |
| | | MimeTypeUtils.IMAGE_JPEG); |
| | | R<SysFile> sysFileR = remoteFileService.upload(multipartFile, bucketName, type); |
| | | if (sysFileR.getCode() == R.SUCCESS) { |
| | | url = sysFileR.getData().getUrl(); |
| | | log.debug("上传文件成功:{}", url); |
| | | |
| | | // 获取实际图片数据(只复制有效长度) |
| | | int actualLength = a.getValue(); |
| | | byte[] imageBytes; |
| | | if (actualLength > 0 && actualLength < 1024 * 1024) { |
| | | imageBytes = new byte[actualLength]; |
| | | System.arraycopy(jpegBuffer.array(), 0, imageBytes, 0, actualLength); |
| | | } else { |
| | | imageBytes = jpegBuffer.array(); |
| | | } |
| | | |
| | | String url = ""; |
| | | File tempFile = null; |
| | | |
| | | try { |
| | | // 创建临时文件 |
| | | tempFile = File.createTempFile("snap_", ".jpeg"); |
| | | java.nio.file.Files.write(tempFile.toPath(), imageBytes); |
| | | |
| | | // 使用 FileMultipartFile 转换 |
| | | MultipartFile multipartFile = new FileMultipartFile(tempFile, objectName, MimeTypeUtils.IMAGE_JPEG); |
| | | |
| | | R<SysFile> sysFileR = remoteFileService.upload(multipartFile, bucketName, type); |
| | | if (sysFileR.getCode() == R.SUCCESS) { |
| | | url = sysFileR.getData().getUrl(); |
| | | log.debug("上传文件成功:{}", url); |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("上传失败", e); |
| | | } finally { |
| | | if (tempFile != null && tempFile.exists()) { |
| | | tempFile.delete(); |
| | | } |
| | | } |
| | | |
| | | return url; |
| | | } |
| | | |
| | | //短时录像 |
| | | @Override |
| | | public String record(CameraCmd cmd) { |
| | | String url = ""; |
| | | File tempFile = null; |
| | | |
| | | try { |
| | | String cameraId = cmd.getCameraId(); |
| | | Integer chanNo = cmd.getChanNo(); |
| | |
| | | String path = FileUtils.createFile(tempDir + "/record/" + name + ".mp4"); |
| | | boolean enable = cmd.isEnable(); |
| | | Integer userId = cmd.getLoginId().intValue(); |
| | | |
| | | //强制I帧结构体对象 |
| | | NET_DVR_I_FRAME netDvrIFrame = new NET_DVR_I_FRAME(); //新建结构体对象 |
| | | NET_DVR_I_FRAME netDvrIFrame = new NET_DVR_I_FRAME(); |
| | | netDvrIFrame.read(); |
| | | netDvrIFrame.dwChannel = chanNo;//因为上文代码中设置了通道号,按照上文中的设置 |
| | | netDvrIFrame.dwChannel = chanNo; |
| | | netDvrIFrame.byStreamType = 0; |
| | | netDvrIFrame.dwSize = netDvrIFrame.size(); |
| | | netDvrIFrame.write(); |
| | | |
| | | if (!hCNetSDK.NET_DVR_RemoteControl(userId, 3402, netDvrIFrame.getPointer(), netDvrIFrame.dwSize)) { |
| | | log.error("强制I帧 错误码为:{}", hCNetSDK.NET_DVR_GetLastError()); |
| | | } |
| | | |
| | | //预览参数 |
| | | NET_DVR_PREVIEWINFO previewInfo = new NET_DVR_PREVIEWINFO(); |
| | | previewInfo.read(); |
| | | previewInfo.lChannel = chanNo; |
| | | previewInfo.dwStreamType = 0;//码流类型:0-主码流,1-子码流,2-三码流,3-虚拟码流,以此类推 |
| | | previewInfo.dwLinkMode = 0;//连接方式:0-TCP方式,1-UDP方式,2-多播方式,3-RTP方式,4-RTP/RTSP,5-RTP/HTTP,6-HRUDP(可靠传输),7 |
| | | // -RTSP/HTTPS,8-NPQ |
| | | previewInfo.hPlayWnd = null;//播放窗口的句柄,为NULL表示不解码显示。 |
| | | previewInfo.bBlocked = 0;//0- 非阻塞取流,1-阻塞取流 |
| | | previewInfo.byNPQMode = 0;//NPQ模式:0-直连模式,1-过流媒体模式 |
| | | previewInfo.dwStreamType = 0; |
| | | previewInfo.dwLinkMode = 0; |
| | | previewInfo.hPlayWnd = null; |
| | | previewInfo.bBlocked = 0; |
| | | previewInfo.byNPQMode = 0; |
| | | previewInfo.write(); |
| | | String url = ""; |
| | | |
| | | if (enable) { |
| | | // 开始录像 |
| | | if (!GlobalVariable.previewMap.containsKey(name)) { |
| | | int lRealHandle = hCNetSDK.NET_DVR_RealPlay_V40(userId, previewInfo, null, null); |
| | | if (lRealHandle == -1) { |
| | |
| | | log.debug("取流成功"); |
| | | GlobalVariable.previewMap.put(name, lRealHandle); |
| | | } |
| | | |
| | | if (!hCNetSDK.NET_DVR_SaveRealData_V30((int) GlobalVariable.previewMap.get(name), 2, path)) { |
| | | log.error("保存视频文件到临时文件夹失败 错误码为:{}", hCNetSDK.NET_DVR_GetLastError()); |
| | | return ""; |
| | |
| | | log.debug("录像开始"); |
| | | |
| | | } else { |
| | | // 停止录像 |
| | | if (GlobalVariable.previewMap.containsKey(name)) { |
| | | Integer lRealHandle = (Integer) GlobalVariable.previewMap.get(name); |
| | | hCNetSDK.NET_DVR_StopRealPlay(lRealHandle); |
| | | GlobalVariable.previewMap.remove(name); |
| | | } |
| | | log.debug("录像停止"); |
| | | //存入minio |
| | | |
| | | // 检查录像文件是否存在 |
| | | File videoFile = new File(path); |
| | | if (!videoFile.exists() || videoFile.length() == 0) { |
| | | log.error("录像文件不存在或为空: {}", path); |
| | | return ""; |
| | | } |
| | | |
| | | // 存入minio - 使用 FileMultipartFile |
| | | String bucketName = "record"; |
| | | String objectName = cameraId + "_" + chanNo; |
| | | MultipartFile multipartFile = MultipartFileUtil.filePathToMultipartFile(path, objectName, |
| | | MimeTypeUtils.VIDEO_MP4); |
| | | String objectName = cameraId + "_" + chanNo + ".mp4"; |
| | | |
| | | // 创建临时文件对象(实际上 path 已经是文件路径) |
| | | tempFile = new File(path); |
| | | |
| | | // 使用 FileMultipartFile 转换 |
| | | MultipartFile multipartFile = new FileMultipartFile(tempFile, objectName, MimeTypeUtils.VIDEO_MP4); |
| | | |
| | | R<SysFile> sysFileR = remoteFileService.upload(multipartFile, bucketName); |
| | | if (sysFileR.getCode() == R.SUCCESS) { |
| | | url = sysFileR.getData().getUrl(); |
| | | log.debug("上传文件成功:{}", url); |
| | | } |
| | | } |
| | | |
| | | return url; |
| | | |
| | | } catch (Exception ex) { |
| | | log.error("录像异常:{}", ex.getMessage()); |
| | | return ""; |
| | |
| | | @Override |
| | | public String recordStop(CameraCmd cmd) { |
| | | String url = ""; |
| | | File videoFile = null; |
| | | File transcodeFile = null; |
| | | |
| | | try { |
| | | String cameraId = cmd.getCameraId(); |
| | | Integer chanNo = cmd.getChanNo(); |
| | | String name = cameraId + "_" + chanNo; |
| | | // 本地临时录像地址 |
| | | String path = FileUtils.createFile(tempDir + "/record/" + name + ".mp4"); |
| | | Integer userId = cmd.getLoginId().intValue(); |
| | | //region 强制I帧 |
| | | NET_DVR_I_FRAME netDvrIFrame = new NET_DVR_I_FRAME(); //新建结构体对象 |
| | | netDvrIFrame.read(); |
| | | netDvrIFrame.dwChannel = chanNo;//因为上文代码中设置了通道号,按照上文中的设置 |
| | | netDvrIFrame.byStreamType = 0; |
| | | netDvrIFrame.dwSize = netDvrIFrame.size(); |
| | | netDvrIFrame.write(); |
| | | if (!hCNetSDK.NET_DVR_RemoteControl(userId, 3402, netDvrIFrame.getPointer(), netDvrIFrame.dwSize)) { |
| | | log.error("强制I帧 错误码为:{}", hCNetSDK.NET_DVR_GetLastError()); |
| | | } |
| | | //endregion |
| | | //region 预览参数 |
| | | NET_DVR_PREVIEWINFO previewInfo = new NET_DVR_PREVIEWINFO(); |
| | | previewInfo.read(); |
| | | previewInfo.lChannel = chanNo; |
| | | previewInfo.dwStreamType = 0;//码流类型:0-主码流,1-子码流,2-三码流,3-虚拟码流,以此类推 |
| | | previewInfo.dwLinkMode = 0;//连接方式:0-TCP方式,1-UDP方式,2-多播方式,3-RTP方式,4-RTP/RTSP,5-RTP/HTTP,6-HRUDP(可靠传输),7 |
| | | // -RTSP/HTTPS,8-NPQ |
| | | previewInfo.hPlayWnd = null;//播放窗口的句柄,为NULL表示不解码显示。 |
| | | previewInfo.bBlocked = 0;//0- 非阻塞取流,1-阻塞取流 |
| | | previewInfo.byNPQMode = 0;//NPQ模式:0-直连模式,1-过流媒体模式 |
| | | previewInfo.write(); |
| | | //endregion |
| | | |
| | | // 停止录像 |
| | | if (GlobalVariable.previewMap.containsKey(name)) { |
| | | Integer lRealHandle = (Integer) GlobalVariable.previewMap.get(name); |
| | | hCNetSDK.NET_DVR_StopRealPlay(lRealHandle); |
| | | GlobalVariable.previewMap.remove(name); |
| | | } |
| | | log.debug("录像停止"); |
| | | //ffmpeg转码 |
| | | |
| | | // 检查原录像文件是否存在 |
| | | videoFile = new File(path); |
| | | if (!videoFile.exists() || videoFile.length() == 0) { |
| | | log.error("录像文件不存在或为空: {}", path); |
| | | return ""; |
| | | } |
| | | |
| | | // ffmpeg转码 |
| | | StopWatch watchStop = new StopWatch(); |
| | | watchStop.start(); |
| | | String newpath = FileUtils.createFile(tempDir + "/record/" + name + "_c.mp4"); |
| | | transcodeFile = new File(newpath); |
| | | FFmpegUtils.transcodeToMP4(path, newpath); |
| | | watchStop.stop(); |
| | | log.warn("转码耗时:{}", watchStop.getTotalTimeMillis()); |
| | | //存入minio |
| | | |
| | | // 检查转码后的文件是否存在 |
| | | if (!transcodeFile.exists() || transcodeFile.length() == 0) { |
| | | log.error("转码文件不存在或为空: {}", newpath); |
| | | return ""; |
| | | } |
| | | |
| | | // 存入minio - 使用 FileMultipartFile |
| | | String bucketName = "record"; |
| | | String objectName = cameraId + "_" + chanNo; |
| | | String objectName = cameraId + "_" + chanNo + ".mp4"; |
| | | String type = cmd.getType(); |
| | | MultipartFile multipartFile = MultipartFileUtil.filePathToMultipartFile(newpath, objectName, |
| | | MimeTypeUtils.VIDEO_MP4); |
| | | |
| | | MultipartFile multipartFile = new FileMultipartFile(transcodeFile, objectName, MimeTypeUtils.VIDEO_MP4); |
| | | R<SysFile> sysFileR = remoteFileService.upload(multipartFile, bucketName, type); |
| | | |
| | | if (sysFileR.getCode() == R.SUCCESS) { |
| | | url = sysFileR.getData().getUrl(); |
| | | log.info("上传文件成功:{}", url); |
| | | } |
| | | |
| | | return url; |
| | | |
| | | } catch (Exception ex) { |
| | | log.error("录像异常:{}", ex.getMessage()); |
| | | return ""; |
| | | } finally { |
| | | // 清理临时文件 |
| | | try { |
| | | if (videoFile != null && videoFile.exists()) { |
| | | videoFile.delete(); |
| | | log.debug("删除原录像文件: {}", videoFile.getPath()); |
| | | } |
| | | if (transcodeFile != null && transcodeFile.exists()) { |
| | | transcodeFile.delete(); |
| | | log.debug("删除转码文件: {}", transcodeFile.getPath()); |
| | | } |
| | | } catch (Exception e) { |
| | | log.warn("删除临时文件失败", e); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | camera.getRtspPort(), |
| | | channel.getChanNo() |
| | | ); |
| | | channel.setRtspUrl(rtspUrl); |
| | | channel.setLiveAddress(rtspUrl); |
| | | channelList.add(channel); |
| | | } |
| | | } |
| | |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取相机信息(会校验存在性) |
| | | */ |
| | | private ArdCamera getCamera(String cameraId) { |
| | | ArdCamera camera = redisService.getCacheMapValue(CacheConstants.CAMERA_LIST, cameraId); |
| | | if (camera == null) { |
| | | throw CameraSDKException.cameraNotExist(cameraId); |
| | | } |
| | | return camera; |
| | | } |
| | | } |