|
@@ -1,25 +1,42 @@
|
|
-package com.ruoyi.web.controller.hk;
|
|
|
|
|
|
+package com.ruoyi.hk;
|
|
|
|
|
|
import com.ruoyi.common.core.domain.AjaxResult;
|
|
import com.ruoyi.common.core.domain.AjaxResult;
|
|
-import com.ruoyi.web.controller.hk.CommonMethod.osSelect;
|
|
|
|
|
|
+import com.ruoyi.hk.CommonMethod.osSelect;
|
|
import com.sun.jna.Native;
|
|
import com.sun.jna.Native;
|
|
import com.sun.jna.Pointer;
|
|
import com.sun.jna.Pointer;
|
|
-import org.springframework.web.bind.annotation.PostMapping;
|
|
|
|
-import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
|
-import org.springframework.web.bind.annotation.RestController;
|
|
|
|
|
|
+
|
|
|
|
+import java.io.File;
|
|
|
|
+import java.io.FileInputStream;
|
|
|
|
+import java.io.IOException;
|
|
|
|
|
|
/**
|
|
/**
|
|
* @Author: tjf
|
|
* @Author: tjf
|
|
- * @Date: 2025/6/6 星期五 16:03
|
|
|
|
|
|
+ * @Date: 2025/8/12 星期二 9:23
|
|
* @Describe:
|
|
* @Describe:
|
|
*/
|
|
*/
|
|
-@RestController
|
|
|
|
-@RequestMapping("/hk")
|
|
|
|
-public class BjsbController {
|
|
|
|
|
|
+public class HkUtils {
|
|
|
|
+ static int lUserID = -1;
|
|
static HCNetSDK hCNetSDK = null;
|
|
static HCNetSDK hCNetSDK = null;
|
|
- static int lUserID = -1;//用户句柄
|
|
|
|
|
|
+ static int lVoiceComHandle = -1; //语音对讲句柄
|
|
|
|
+ static int Count = 0;
|
|
|
|
+ static int PCM_SEND = 1920;
|
|
static int lAlarmHandle = -1;
|
|
static int lAlarmHandle = -1;
|
|
static FMSGCallBack_V31 fMSFCallBack_V31 = null; //报警布防回调函数
|
|
static FMSGCallBack_V31 fMSFCallBack_V31 = null; //报警布防回调函数
|
|
|
|
+ static cbVoicePcmDataCallBack_MR_V30 cbVoicePcmDataCallBack_mr_v30 = null;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 海康摄像头音频转发
|
|
|
|
+ */
|
|
|
|
+ static class cbVoicePcmDataCallBack_MR_V30 implements HCNetSDK.FVoiceDataCallback_MR_V30 {
|
|
|
|
+ public void invoke(int lVoiceComHandle, Pointer pRecvDataBuffer, int dwBufSize, byte byAudioFlag, Pointer pUser) {
|
|
|
|
+ if (Count == 250) {//降低打印频率
|
|
|
|
+ System.out.println("-----=cbVoiceDataCallBack_MR_V30 enter---------");
|
|
|
|
+ Count = 0;
|
|
|
|
+ }
|
|
|
|
+ Count++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* 根据不同操作系统选择不同的库文件和库路径
|
|
* 根据不同操作系统选择不同的库文件和库路径
|
|
*
|
|
*
|
|
@@ -34,9 +51,10 @@ public class BjsbController {
|
|
if (osSelect.isWindows())
|
|
if (osSelect.isWindows())
|
|
//win系统加载库路径
|
|
//win系统加载库路径
|
|
strDllPath = System.getProperty("user.dir") + "\\lib\\HCNetSDK.dll";
|
|
strDllPath = System.getProperty("user.dir") + "\\lib\\HCNetSDK.dll";
|
|
|
|
+
|
|
else if (osSelect.isLinux())
|
|
else if (osSelect.isLinux())
|
|
//Linux系统加载库路径
|
|
//Linux系统加载库路径
|
|
- strDllPath = System.getProperty("user.dir") + "/libOne/libhcnetsdk.so";
|
|
|
|
|
|
+ strDllPath = System.getProperty("user.dir") + "/lib/libhcnetsdk.so";
|
|
hCNetSDK = (HCNetSDK) Native.loadLibrary(strDllPath, HCNetSDK.class);
|
|
hCNetSDK = (HCNetSDK) Native.loadLibrary(strDllPath, HCNetSDK.class);
|
|
} catch (Exception ex) {
|
|
} catch (Exception ex) {
|
|
System.out.println("loadLibrary: " + strDllPath + " Error: " + ex.getMessage());
|
|
System.out.println("loadLibrary: " + strDllPath + " Error: " + ex.getMessage());
|
|
@@ -47,11 +65,207 @@ public class BjsbController {
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * 登录设备,支持 V40 和 V30 版本,功能一致。
|
|
|
|
+ *
|
|
|
|
+ * @param ip 设备IP地址
|
|
|
|
+ * @param port SDK端口,默认为设备的8000端口
|
|
|
|
+ * @param user 设备用户名
|
|
|
|
+ * @param psw 设备密码
|
|
|
|
+ * @return 登录成功返回用户ID,失败返回-1
|
|
|
|
+ */
|
|
|
|
+ public static int loginDevice(String ip, short port, String user, String psw) {
|
|
|
|
+ // 创建设备登录信息和设备信息对象
|
|
|
|
+ HCNetSDK.NET_DVR_USER_LOGIN_INFO loginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
|
|
|
|
+ HCNetSDK.NET_DVR_DEVICEINFO_V40 deviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
|
|
|
|
+
|
|
|
|
+ // 设置设备IP地址
|
|
|
|
+ byte[] deviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
|
|
|
|
+ byte[] ipBytes = ip.getBytes();
|
|
|
|
+ System.arraycopy(ipBytes, 0, deviceAddress, 0, Math.min(ipBytes.length, deviceAddress.length));
|
|
|
|
+ loginInfo.sDeviceAddress = deviceAddress;
|
|
|
|
+
|
|
|
|
+ // 设置用户名和密码
|
|
|
|
+ byte[] userName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
|
|
|
|
+ byte[] password = psw.getBytes();
|
|
|
|
+ System.arraycopy(user.getBytes(), 0, userName, 0, Math.min(user.length(), userName.length));
|
|
|
|
+ System.arraycopy(password, 0, loginInfo.sPassword, 0, Math.min(password.length, loginInfo.sPassword.length));
|
|
|
|
+ loginInfo.sUserName = userName;
|
|
|
|
+
|
|
|
|
+ // 设置端口和登录模式
|
|
|
|
+ loginInfo.wPort = port;
|
|
|
|
+ loginInfo.bUseAsynLogin = false; // 同步登录
|
|
|
|
+ loginInfo.byLoginMode = 0; // 使用SDK私有协议
|
|
|
|
+
|
|
|
|
+ // 执行登录操作
|
|
|
|
+ int userID = hCNetSDK.NET_DVR_Login_V40(loginInfo, deviceInfo);
|
|
|
|
+ if (userID == -1) {
|
|
|
|
+ System.err.println("登录失败,错误码为: " + hCNetSDK.NET_DVR_GetLastError());
|
|
|
|
+ } else {
|
|
|
|
+ System.out.println(ip + " 设备登录成功!");
|
|
|
|
+ // 处理通道号逻辑
|
|
|
|
+ int startDChan = deviceInfo.struDeviceV30.byStartDChan;
|
|
|
|
+ System.out.println("预览起始通道号: " + startDChan);
|
|
|
|
+ }
|
|
|
|
+ return userID; // 返回登录结果
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 获取音频编码参数
|
|
|
|
+ *
|
|
|
|
+ * @param userID 设备注册句柄
|
|
|
|
+ */
|
|
|
|
+ public static void getCurrentAudioCompress(int userID) {
|
|
|
|
+ HCNetSDK.NET_DVR_COMPRESSION_AUDIO net_dvr_compression_audio = new HCNetSDK.NET_DVR_COMPRESSION_AUDIO();
|
|
|
|
+ boolean b_AudioCompress = hCNetSDK.NET_DVR_GetCurrentAudioCompress(userID, net_dvr_compression_audio);
|
|
|
|
+ if (b_AudioCompress == false) {
|
|
|
|
+ System.out.println("获取音频编码格式参数失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ net_dvr_compression_audio.read();
|
|
|
|
+ System.out.println("音频编码类型:" + net_dvr_compression_audio.byAudioEncType);
|
|
|
|
+ System.out.println("音频采样率:" + net_dvr_compression_audio.byAudioSamplingRate);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 设备注销
|
|
|
|
+ */
|
|
|
|
+ public static boolean logout() {
|
|
|
|
+
|
|
|
|
+ if (hCNetSDK.NET_DVR_Logout(lUserID)) {
|
|
|
|
+ System.out.println("注销成功");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 给对应摄像头发送音频
|
|
|
|
+ *
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ public static AjaxResult sendAudio() throws InterruptedException, IOException {
|
|
|
|
+ if (hCNetSDK == null) {
|
|
|
|
+ if (!createSDKInstance()) {
|
|
|
|
+ System.out.println("Load SDK fail");
|
|
|
|
+ return AjaxResult.error("Load SDK fail");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ //linux系统建议调用以下接口加载组件库
|
|
|
|
+ if (osSelect.isLinux()) {
|
|
|
|
+ HCNetSDK.BYTE_ARRAY ptrByteArray1 = new HCNetSDK.BYTE_ARRAY(256);
|
|
|
|
+ HCNetSDK.BYTE_ARRAY ptrByteArray2 = new HCNetSDK.BYTE_ARRAY(256);
|
|
|
|
+ //这里是库的绝对路径,请根据实际情况修改,注意改路径必须有访问权限
|
|
|
|
+ String strPath1 = System.getProperty("user.dir") + "/lib/libcrypto.so.1.1";
|
|
|
|
+ String strPath2 = System.getProperty("user.dir") + "/lib/libssl.so.1.1";
|
|
|
|
+ System.arraycopy(strPath1.getBytes(), 0, ptrByteArray1.byValue, 0, strPath1.length());
|
|
|
|
+ ptrByteArray1.write();
|
|
|
|
+ hCNetSDK.NET_DVR_SetSDKInitCfg(HCNetSDK.NET_SDK_INIT_CFG_LIBEAY_PATH, ptrByteArray1.getPointer());
|
|
|
|
+ System.arraycopy(strPath2.getBytes(), 0, ptrByteArray2.byValue, 0, strPath2.length());
|
|
|
|
+ ptrByteArray2.write();
|
|
|
|
+ hCNetSDK.NET_DVR_SetSDKInitCfg(HCNetSDK.NET_SDK_INIT_CFG_SSLEAY_PATH, ptrByteArray2.getPointer());
|
|
|
|
+ String strPathCom = System.getProperty("user.dir") + "/lib/";
|
|
|
|
+ HCNetSDK.NET_DVR_LOCAL_SDK_PATH struComPath = new HCNetSDK.NET_DVR_LOCAL_SDK_PATH();
|
|
|
|
+ System.arraycopy(strPathCom.getBytes(), 0, struComPath.sPath, 0, strPathCom.length());
|
|
|
|
+ struComPath.write();
|
|
|
|
+ hCNetSDK.NET_DVR_SetSDKInitCfg(HCNetSDK.NET_SDK_INIT_CFG_SDK_PATH, struComPath.getPointer());
|
|
|
|
+ }
|
|
|
|
+ boolean initSuc = hCNetSDK.NET_DVR_Init();
|
|
|
|
+ if (initSuc != true) {
|
|
|
|
+ System.out.println("初始化失败");
|
|
|
|
+ }
|
|
|
|
+ hCNetSDK.NET_DVR_SetLogToFile(3, "./sdkLog", false);
|
|
|
|
+ //设备登录 需要设备信息
|
|
|
|
+ lUserID = HkUtils.loginDevice("10.90.90.68", (short) 8000, "admin", "zxy123456");
|
|
|
|
+ //获取设备音频编码参数,确定转发音频参数
|
|
|
|
+ HkUtils.getCurrentAudioCompress(lUserID);
|
|
|
|
+ System.out.println("\n[Module]开启PCM语音转发示例代码");
|
|
|
|
+ HkUtils.startTransPCMData(lUserID);
|
|
|
|
+ HkUtils.logout();
|
|
|
|
+ //释放SDK
|
|
|
|
+ hCNetSDK.NET_DVR_Cleanup();
|
|
|
|
+ return AjaxResult.success();
|
|
|
|
+ }
|
|
|
|
+ /**
|
|
|
|
+ * :: 生成临时WAV文件
|
|
|
|
+ * powershell -Command "Add-Type -AssemblyName System.Speech; $speak = New-Object System.Speech.Synthesis.SpeechSynthesizer; $speak.SetOutputToWaveFile('%USERPROFILE%\Desktop\temp.wav'); $speak.Speak('测试'); $speak.Dispose()"
|
|
|
|
+ *
|
|
|
|
+ * :: 转换为PCM
|
|
|
|
+ * ffmpeg -i "%USERPROFILE%\Desktop\temp.wav" -f s16le -acodec pcm_s16le -ar 16000 -ac 1 "%USERPROFILE%\Desktop\123.pcm"
|
|
|
|
+ *
|
|
|
|
+ * :: 清理临时文件
|
|
|
|
+ * del "%USERPROFILE%\Desktop\temp.wav"
|
|
|
|
+ */
|
|
|
|
+ /**
|
|
|
|
+ * pcm音频转发
|
|
|
|
+ *
|
|
|
|
+ * @param luserID
|
|
|
|
+ */
|
|
|
|
+ public static void startTransPCMData(int luserID) {
|
|
|
|
+ //设置语音PCM回调函数
|
|
|
|
+ if (cbVoicePcmDataCallBack_mr_v30 == null) {
|
|
|
|
+ cbVoicePcmDataCallBack_mr_v30 = new cbVoicePcmDataCallBack_MR_V30();
|
|
|
|
+ }
|
|
|
|
+ lVoiceComHandle = hCNetSDK.NET_DVR_StartVoiceCom_MR_V30(lUserID, 1, cbVoicePcmDataCallBack_mr_v30, null);
|
|
|
|
+ if (lVoiceComHandle < 0) {
|
|
|
|
+ System.out.println("NET_DVR_StartVoiceCom_MR_V30 error," + hCNetSDK.NET_DVR_GetLastError());
|
|
|
|
+ hCNetSDK.NET_DVR_Logout(lUserID);
|
|
|
|
+ hCNetSDK.NET_DVR_Cleanup();
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ System.out.println("NET_DVR_StartVoiceCom_MR_V30 suss\n");
|
|
|
|
+ //读取发送到设备的PCM音频文件,视频采样率和位数需要和设备编码参数保持一致
|
|
|
|
+ File m_hStreamFile = new File(System.getProperty("user.dir") + "\\AudioFile\\123.pcm");
|
|
|
|
+ try {
|
|
|
|
+ // 获取文件的输入流
|
|
|
|
+ FileInputStream inputStream = new FileInputStream(m_hStreamFile);
|
|
|
|
+ int PCMdataLength = 0;
|
|
|
|
+ try {
|
|
|
|
+ //返回文件的总字节数
|
|
|
|
+ PCMdataLength = inputStream.available();
|
|
|
|
+ } catch (IOException e1) {
|
|
|
|
+ e1.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ if (PCMdataLength < 0) {
|
|
|
|
+ System.out.println("MP3 file dataSize < 0");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ HCNetSDK.BYTE_ARRAY ptrVoicePcmByte = new HCNetSDK.BYTE_ARRAY(PCMdataLength);
|
|
|
|
+ try {
|
|
|
|
+ inputStream.read(ptrVoicePcmByte.byValue);
|
|
|
|
+ } catch (IOException e2) {
|
|
|
|
+ e2.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ ptrVoicePcmByte.write();
|
|
|
|
+ for (int i = 0; i < PCMdataLength / PCM_SEND; i++) {
|
|
|
|
+ HCNetSDK.BYTE_ARRAY ptrPcmSend = new HCNetSDK.BYTE_ARRAY(PCM_SEND);
|
|
|
|
+ System.arraycopy(ptrVoicePcmByte.byValue, i * PCM_SEND, ptrPcmSend.byValue, 0, PCM_SEND);
|
|
|
|
+ ptrPcmSend.write();
|
|
|
|
+ if (hCNetSDK.NET_DVR_VoiceComSendData(lVoiceComHandle, ptrPcmSend.byValue, PCM_SEND) == false) {
|
|
|
|
+ System.out.println("NET_DVR_VoiceComSendData failed, error code:" + hCNetSDK.NET_DVR_GetLastError());
|
|
|
|
+ } else {
|
|
|
|
+ System.out.println("NET_DVR_VoiceComSendData:" + PCM_SEND + ":succeed ,data is " + i * PCM_SEND);
|
|
|
|
+ }
|
|
|
|
+ //需要实时速率发送数据
|
|
|
|
+ try {
|
|
|
|
+ Thread.sleep(40);
|
|
|
|
+ } catch (InterruptedException e) {
|
|
|
|
+ // TODO Auto-generated catch block
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* 获取表计数据
|
|
* 获取表计数据
|
|
*/
|
|
*/
|
|
- @PostMapping("/getBj")
|
|
|
|
- public AjaxResult getBj() {
|
|
|
|
|
|
+ public static AjaxResult getBj() {
|
|
if (hCNetSDK == null) {
|
|
if (hCNetSDK == null) {
|
|
if (!createSDKInstance()) {
|
|
if (!createSDKInstance()) {
|
|
System.out.println("Load SDK fail");
|
|
System.out.println("Load SDK fail");
|
|
@@ -128,52 +342,6 @@ public class BjsbController {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 登录设备,支持 V40 和 V30 版本,功能一致。
|
|
|
|
- *
|
|
|
|
- * @param ip 设备IP地址
|
|
|
|
- * @param port SDK端口,默认为设备的8000端口
|
|
|
|
- * @param user 设备用户名
|
|
|
|
- * @param psw 设备密码
|
|
|
|
- * @return 登录成功返回用户ID,失败返回-1
|
|
|
|
- */
|
|
|
|
- public static int loginDevice(String ip, short port, String user, String psw) {
|
|
|
|
- // 创建设备登录信息和设备信息对象
|
|
|
|
- HCNetSDK.NET_DVR_USER_LOGIN_INFO loginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
|
|
|
|
- HCNetSDK.NET_DVR_DEVICEINFO_V40 deviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
|
|
|
|
-
|
|
|
|
- // 设置设备IP地址
|
|
|
|
- byte[] deviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
|
|
|
|
- byte[] ipBytes = ip.getBytes();
|
|
|
|
- System.arraycopy(ipBytes, 0, deviceAddress, 0, Math.min(ipBytes.length, deviceAddress.length));
|
|
|
|
- loginInfo.sDeviceAddress = deviceAddress;
|
|
|
|
-
|
|
|
|
- // 设置用户名和密码
|
|
|
|
- byte[] userName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
|
|
|
|
- byte[] password = psw.getBytes();
|
|
|
|
- System.arraycopy(user.getBytes(), 0, userName, 0, Math.min(user.length(), userName.length));
|
|
|
|
- System.arraycopy(password, 0, loginInfo.sPassword, 0, Math.min(password.length, loginInfo.sPassword.length));
|
|
|
|
- loginInfo.sUserName = userName;
|
|
|
|
-
|
|
|
|
- // 设置端口和登录模式
|
|
|
|
- loginInfo.wPort = port;
|
|
|
|
- loginInfo.bUseAsynLogin = false; // 同步登录
|
|
|
|
- loginInfo.byLoginMode = 0; // 使用SDK私有协议
|
|
|
|
-
|
|
|
|
- // 执行登录操作
|
|
|
|
- int userID = hCNetSDK.NET_DVR_Login_V40(loginInfo, deviceInfo);
|
|
|
|
- if (userID == -1) {
|
|
|
|
- System.err.println("登录失败,错误码为: " + hCNetSDK.NET_DVR_GetLastError());
|
|
|
|
- } else {
|
|
|
|
- System.out.println(ip + " 设备登录成功!");
|
|
|
|
- // 处理通道号逻辑
|
|
|
|
- int startDChan = deviceInfo.struDeviceV30.byStartDChan;
|
|
|
|
- System.out.println("预览起始通道号: " + startDChan);
|
|
|
|
- }
|
|
|
|
- return userID; // 返回登录结果
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* 报警主机注销用户,释放资源
|
|
* 报警主机注销用户,释放资源
|
|
*/
|
|
*/
|
|
@@ -198,5 +366,4 @@ public class BjsbController {
|
|
}
|
|
}
|
|
return AjaxResult.error("报警主机注销用户失败,错误号:" + hCNetSDK.NET_DVR_GetLastError());
|
|
return AjaxResult.error("报警主机注销用户失败,错误号:" + hCNetSDK.NET_DVR_GetLastError());
|
|
}
|
|
}
|
|
-
|
|
|
|
}
|
|
}
|