宇视摄像头双向语音-第一部分
IPC672LR-ADUWKCF40-DT浙江宇视摄像头
他们官网的SDK包对win10兼容性不行,需要的话需要找宇视的开发人员单独要。
只有宇视单独开发的版本才能双向语音,下面的版本是单独给我的。
NetDEVSDK_Win64_20210906.zip
我将它解压到D:\project\yushi\NetDEVSDK_Win64_20210906
Java JNI部分
第一步,写Java的JNI程序
package cn.xx.utils;
//dll项目路径D:\project\yushi\YuShiNetDllRelease
public class YuShiNetDevSDKUtils {
static {
System.loadLibrary("YuShiNetDllRelease");
}
/**
* 打开宇视语音通道 IPC Speak
*
* @param ipAddress
*/
public native static void openSpeak(String ipAddress);
/**
* 关闭宇视语音通道 IPC Speak
*
* @param ipAddress
*/
public native static void closeSpeak(String ipAddress);
public native static void test(int value);
public static void main(String[] args) {
System.out.println(System.getProperty("java.library.path"));
try {
YuShiNetDevSDKUtils.openSpeak("192.168.100.131");
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
// yushiSDK.test(3);
}
}
第二步,编译java源码
D:\sts-bundle\workspace\practice\src\test\java\cn\xx\utils>javac YuShiNetDevSDKUtils .java
第三步,使用javah生成C需要的头文件
D:\sts-bundle\workspace\practice\src\test\java>javah cn.xx.utils.YuShiNetDevSDKUtils
cn_xx_utils_YuShiNetDevSDKUtils.h
C语言部分
1.使用vs2019创建dll动态链接库
2.配置项目环境
A、添加工程的头文件目录:工程---属性---配置属性---c/c++---常规---附加包含目录:加上头文件存放目录。
B 添加文件引用的lib静态库路径:工程---属性---配置属性---链接器---常规---附加库目录:加上lib文件存放目录。
C 然后添加工程引用的lib文件名:工程---属性---配置属性---链接器---输入---附加依赖项:加上lib文件名
3.导入头文件
此时出了导入刚刚生成的.h文件,还需要导入java的头文件 jni.h 和jni_md.h
jni.h 以及jni_md.h的路径在 java的安装位置下的include文件夹内 以及win32下
4.编辑源文件
YuShiNetDllRelease.cpp文件内容如下
#include "pch.h"
#include "framework.h"
#include "NetDEVSDK.h"
#include "Windows.h"
#include "cn_xx_utils_YuShiNetDevSDKUtils.h"
#include "malloc.h"
LPVOID lUserID = NULL;
char* Jstring2CStr(JNIEnv* env, jstring jstr)
{
char* rtn = NULL;
jclass clsstring = env->FindClass("java/lang/String");
jstring strencode = env->NewStringUTF("GB2312");
jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
jbyteArray barr = (jbyteArray)env->CallObjectMethod(jstr, mid, strencode);
jsize alen = env->GetArrayLength(barr);
jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
if (alen > 0)
{
rtn = (char*)malloc(alen + 1); //new char[alen+1];
memcpy(rtn, ba, alen);
rtn[alen] = 0;
}
env->ReleaseByteArrayElements(barr, ba, 0);
return rtn;
}
// This is an example of an exported variable
//YUSHINETDLL_API int nYuShiNetDll=0;
void STDCALL NETDEV_DECODE_AUDIO_DATA_CALLBACK(LPVOID lpPlayHandle, const NETDEV_WAVE_DATA_S* pstWaveData, LPVOID lpUserParam)
{
printf("DataLen: %d\n", pstWaveData->dwDataLen);
}
JNIEXPORT void JNICALL Java_cn_xx_utils_YuShiNetDevSDKUtils_test
(JNIEnv*, jclass, jint a) {
printf("this is java call
c++ print%d\n", a);
// printf("NETDEV_Init begin\n");
}
JNIEXPORT void JNICALL Java_cn_xx_utils_YuShiNetDevSDKUtils_openSpeak
(JNIEnv* env, jclass, jstring ipaddress) {
//JNI调用此函数,只会调用单例模式下的函数。所以重复调用让它失败。
if (lUserID != NULL) {
return;
}
NETDEV_Init();
printf("system inited \n");
//设置连接时间
NETDEV_REV_TIMEOUT_S stRevTimeout = { 0 };
stRevTimeout.dwRevTimeOut = 5;
stRevTimeout.dwFileReportTimeOut = 30;
NETDEV_SetRevTimeOut(&stRevTimeout);
//登录参数,包括设备地址、登录用户、密码等
NETDEV_DEVICE_LOGIN_INFO_S stDevLoginInfo = { 0 };
strncpy_s(stDevLoginInfo.szIPAddr, Jstring2CStr(env, ipaddress), sizeof(stDevLoginInfo.szIPAddr)); //设备IP地址
strncpy_s(stDevLoginInfo.szUserName, "admin", sizeof(stDevLoginInfo.szUserName)); //设备登录用户名
strncpy_s(stDevLoginInfo.szPassword, "123456", sizeof(stDevLoginInfo.szPassword)); //设备登录密码
stDevLoginInfo.dwPort = 80; //设备服务端口
stDevLoginInfo.dwLoginProto = NETDEV_LOGIN_PROTO_ONVIF; //登录协议
//输出参数,仅私有协议登录有效
NETDEV_SELOG_INFO_S stSELogInfo = { 0 };
lUserID = NETDEV_Login_V30(&stDevLoginInfo, &stSELogInfo);
if (NULL == lUserID)
{
printf("Login failed, error code: %d\n", NETDEV_GetLastError());
//释放SDK资源
NETDEV_Cleanup();
return;
}
printf("Login sucessful, %d\n", stSELogInfo);
//通道查询
NETDEV_VIDEO_CHL_DETAIL_INFO_EX_S stVideoChlDetailInfoEx[128] = { 0 }; //分配个通道
INT32 dwCount = 128; //128个通道
BOOL bRet = NETDEV_QueryVideoChlDetailListEx(lUserID, &dwCount, stVideoChlDetailInfoEx);
if (FALSE == bRet && NETDEV_E_NEEDMOREDATA == NETDEV_GetLastError())
{
//默认分配数组大小小于实际通道数,重新分配内存获取
NETDEV_VIDEO_CHL_DETAIL_INFO_EX_S* pstVideoChlDetailInfoEx = new NETDEV_VIDEO_CHL_DETAIL_INFO_EX_S[dwCount];
memset(pstVideoChlDetailInfoEx, 0, sizeof(NETDEV_VIDEO_CHL_DETAIL_INFO_EX_S) * dwCount);
bRet = NETDEV_QueryVideoChlDetailListEx(lUserID, &dwCount, pstVideoChlDetailInfoEx);
//释放分配内存
delete[]pstVideoChlDetailInfoEx;
}
if (TRUE == bRet) {
printf("QueryVideoChlDetailList Success\n");
}
else {
printf("QueryVideoChlDetailList failed, error code: %d\n", NETDEV_GetLastError());
}
//开启语音对讲
LPVOID lpPlayHandle = NETDEV_StartVoiceCom(lUserID, 1, NETDEV_DECODE_AUDIO_DATA_CALLBACK, 0);
if (NULL == lpPlayHandle)
{
printf("StartVoiceCom failed, error code: %d\n", NETDEV_GetLastError());
}
else
{
Sleep(20000); //millisecond
//停止语音对讲
NETDEV_StopVoiceCom(lpPlayHandle);
}
//注销用户
NETDEV_Logout(lUserID);
//释放SDK资源
NETDEV_Cleanup();
lUserID = NULL;
printf("NETDEV_Init done\n");
}
5.编译项目打包
导出路径
D:\project\yushi\YuShiNetDllRelease\x64\Release\YuShiNetDllRelease.dll
生成dll文件。
Java引用部分
1.部署方法
1.1拷贝文件方式
将生成的YuShiNetDll.dll文件,按操作系统类型的不同,放入不同的目录下。
32位放入System32下 、64位放入SysWOW64下 、或者放入项目文件中(访问System32下的可以跳过这一步)
1.2 IDE项目导入方式
将所有的dll文件拷贝到一个文件夹下
Java项目导入libs文件夹。
1.3正式项目部署方式
宇视双向语音配置要求如下:
在Windows10下的安装方法。
第1步:
保证PATH变量里面只有一个%JAVA_HOME%\bin 指向JDK的安装目录。不能是jre的目录.
把PATH变量中的Oracle的javapath删除掉 C:\Program Files (x86)\Common Files\Oracle\Java\javapath
否则无法启用宇视的dll文件
第2步:
PATH路径中加入,DLL所在的文件夹。
D:\sts-bundle\workspace\practice\libs\win64\
2.java代码
package cn.xx.utils;
//dll项目路径D:\project\yushi\YuShiNetDllRelease
public class YuShiNetDevSDKUtils {
static {
System.loadLibrary("YuShiNetDllRelease");
}
/**
* 打开宇视语音通道 IPC Speak
*
* @param ipAddress
*/
public native static void openSpeak(String ipAddress);
/**
* 关闭宇视语音通道 IPC Speak
*
* @param ipAddress
*/
public native static void closeSpeak(String ipAddress);
public native static void test(int value);
public static void main(String[] args) {
System.out.println(System.getProperty("java.library.path"));
try {
YuShiNetDevSDKUtils.openSpeak("192.168.100.131");
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
// yushiSDK.test(3);
}
}
宇视摄像头广播-第二部分
实现,一个麦克风,同时呼叫多个摄像头,实现广播功能。
Java部分
package cn.xx.utils;
//dll项目路径D:\project\yushi\YuShiNetDllRelease
public class YuShiNetDevSDKUtils {
static {
System.loadLibrary("YuShiNetDllRelease");
}
/**
* 打开宇视语音通道 IPC Speak
*
* @param ipAddress
*/
public native static void openSpeak(String ipAddress);
/**
* 关闭宇视语音通道 IPC Speak
*
* @param ipAddress
*/
public native static void closeSpeak(String ipAddress);
/**
* open one broadcast
*/
public native static void startOneVoiceBroadcast(String ipAddress);
/**
* open broadcast
*/
public native static void startVoiceBroadcast(String[] ids);
/**
* stop broadcast
*/
public native static void stopVoiceBroadcast();
public native static int test(int value);
public static void main(String[] args) {
System.out.println(System.getProperty("java.library.path"));
//开启广播。
try {
String[] ids = {"192.168.100.131", "192.168.100.132"};
YuShiNetDevSDKUtils.startVoiceBroadcast(ids);
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
//关闭广播
//YuShiNetDevSDKUtils.stopVoiceBroadcast();
}
}
c语言部分
cn_xx_utils_YuShiNetDevSDKUtils.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class cn_xx_utils_YuShiNetDevSDKUtils */
#ifndef _Included_cn_xx_utils_YuShiNetDevSDKUtils
#define _Included_cn_xx_utils_YuShiNetDevSDKUtils
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: cn_xx_utils_YuShiNetDevSDKUtils
* Method: openSpeak
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_cn_xx_utils_YuShiNetDevSDKUtils_openSpeak
(JNIEnv*, jclass, jstring);
/*
* Class: cn_xx_utils_YuShiNetDevSDKUtils
* Method: closeSpeak
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_cn_xx_utils_YuShiNetDevSDKUtils_closeSpeak
(JNIEnv*, jclass, jstring);
/*
* Class: cn_xx_utils_YuShiNetDevSDKUtils
* Method: startVoiceBroadcast
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_cn_xx_utils_YuShiNetDevSDKUtils_startOneVoiceBroadcast
(JNIEnv*, jclass, jstring);
/*
* Class: cn_xx_utils_YuShiNetDevSDKUtils
* Method: startVoiceBroadcast
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_cn_xx_utils_YuShiNetDevSDKUtils_startVoiceBroadcast
(JNIEnv*, jclass, jobjectArray);
/*
* Class: cn_xx_utils_YuShiNetDevSDKUtils
* Method: stopVoiceBroadcast
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_cn_xx_utils_YuShiNetDevSDKUtils_stopVoiceBroadcast
(JNIEnv*, jclass);
/*
* Class: cn_xx_utils_YuShiNetDevSDKUtils
* Method: test
* Signature: (I)V
*/
JNIEXPORT jint JNICALL Java_cn_xx_utils_YuShiNetDevSDKUtils_test
(JNIEnv*, jclass, jint);
#ifdef __cplusplus
}
#endif
#endif
YuShiNetDllRelease.cpp
#include "pch.h"
#include "framework.h"
#include "NetDEVSDK.h"
#include "Windows.h"
#include "cn_xx_utils_YuShiNetDevSDKUtils.h"
#include "malloc.h"
#include <string>
#include <map>
#include <thread>
using namespace std;
LPVOID lUserID = NULL;
//多摄像头广播标记,true为还在运行,false为可以开启广播。
volatile bool flag = false;
map<char*, LPVOID> userIdList;
map<char*, LPVOID> playHandleList;
char* Jstring2CStr(JNIEnv* env, jstring jstr)
{
char* rtn = NULL;
jclass clsstring = env->FindClass("java/lang/String");
jstring strencode = env->NewStringUTF("GB2312");
jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
jbyteArray barr = (jbyteArray)env->CallObjectMethod(jstr, mid, strencode);
jsize alen = env->GetArrayLength(barr);
jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
if (alen > 0)
{
rtn = (char*)malloc(alen + 1); //new char[alen+1];
memcpy(rtn, ba, alen);
rtn[alen] = 0;
}
env->ReleaseByteArrayElements(barr, ba, 0);
return rtn;
}
// This is an example of an exported variable
//YUSHINETDLL_API int nYuShiNetDll=0;
void STDCALL NETDEV_DECODE_AUDIO_DATA_CALLBACK(LPVOID lpPlayHandle, const NETDEV_WAVE_DATA_S* pstWaveData, LPVOID lpUserParam)
{
printf("DataLen: %d\n", pstWaveData->dwDataLen);
}
JNIEXPORT jint JNICALL Java_cn_xx_utils_YuShiNetDevSDKUtils_test
(JNIEnv*, jclass, jint a) {
printf("this is java call c++ print%d\n", a);
return a;
// printf("NETDEV_Init begin\n");
}
void openOnBroadcast(char* ipaddress) {
//设置连接时间
NETDEV_REV_TIMEOUT_S stRevTimeout = { 0 };
stRevTimeout.dwRevTimeOut = 5;
stRevTimeout.dwFileReportTimeOut = 30;
NETDEV_SetRevTimeOut(&stRevTimeout);
//登录参数,包括设备地址、登录用户、密码等
NETDEV_DEVICE_LOGIN_INFO_S stDevLoginInfo = { 0 };
strncpy_s(stDevLoginInfo.szIPAddr, ipaddress, sizeof(stDevLoginInfo.szIPAddr)); //设备IP地址
strncpy_s(stDevLoginInfo.szUserName, "admin", sizeof(stDevLoginInfo.szUserName)); //设备登录用户名
strncpy_s(stDevLoginInfo.szPassword, "123456", sizeof(stDevLoginInfo.szPassword)); //设备登录密码
stDevLoginInfo.dwPort = 80; //设备服务端口
stDevLoginInfo.dwLoginProto = NETDEV_LOGIN_PROTO_ONVIF; //登录协议
//输出参数,仅私有协议登录有效
NETDEV_SELOG_INFO_S stSELogInfo = { 0 };
LPVOID lUserID = NETDEV_Login_V30(&stDevLoginInfo, &stSELogInfo);
if (NULL == lUserID)
{
printf("Login failed, error code: %d\n", NETDEV_GetLastError());
//释放SDK资源
//NETDEV_Cleanup();
return;
}
printf("Login sucessful, %d\n", stSELogInfo);
//通道查询
NETDEV_VIDEO_CHL_DETAIL_INFO_EX_S stVideoChlDetailInfoEx[128] = { 0 }; //分配个通道
INT32 dwCount = 128; //128个通道
BOOL bRet = NETDEV_QueryVideoChlDetailListEx(lUserID, &dwCount, stVideoChlDetailInfoEx);
if (FALSE == bRet && NETDEV_E_NEEDMOREDATA == NETDEV_GetLastError())
{
//默认分配数组大小小于实际通道数,重新分配内存获取
NETDEV_VIDEO_CHL_DETAIL_INFO_EX_S* pstVideoChlDetailInfoEx = new NETDEV_VIDEO_CHL_DETAIL_INFO_EX_S[dwCount];
memset(pstVideoChlDetailInfoEx, 0, sizeof(NETDEV_VIDEO_CHL_DETAIL_INFO_EX_S) * dwCount);
bRet = NETDEV_QueryVideoChlDetailListEx(lUserID, &dwCount, pstVideoChlDetailInfoEx);
//释放分配内存
delete[]pstVideoChlDetailInfoEx;
}
if (TRUE == bRet) {
printf("QueryVideoChlDetailList Success\n");
}
else {
printf("QueryVideoChlDetailList failed, error code: %d\n", NETDEV_GetLastError());
}
userIdList[ipaddress] = lUserID;
//开启语音广播
LPVOID lpPlayHandle = NETDEV_StartVoiceBroadcast(lUserID, 1);
if (NULL == lpPlayHandle) {
printf("StartVoiceBroadcast failed, error code: %d\n", NETDEV_GetLastError());
}
else {
playHandleList[ipaddress] = lpPlayHandle;
//Sleep(20000); //millisecond
while (flag) {}//一直运行,直到用户关闭广播为止。
//std::this_thread::sleep_for(std::chrono::milliseconds(20000));//线程休眠5分钟开启,之后自动关闭
//停止语音对讲
//NETDEV_StopVoiceBroadcast(lpPlayHandle);
}
//注销用户
//NETDEV_Logout(lUserID);
//userIdList[ipaddress] = NULL;
}
JNIEXPORT void JNICALL Java_cn_xx_utils_YuShiNetDevSDKUtils_startOneVoiceBroadcast
(JNIEnv* env, jclass, jstring ipaddress) {
if (userIdList.size() > 0) {
return;
}
thread newThread(openOnBroadcast, Jstring2CStr(env, ipaddress));
newThread.join();
}
/*
* 广播----开启
*/
JNIEXPORT void JNICALL Java_cn_xx_utils_YuShiNetDevSDKUtils_startVoiceBroadcast
(JNIEnv* env, jclass, jobjectArray addrssList) {
if (flag) {
return;
}
//初始化网络参数
NETDEV_Init();
flag = true;
printf("NETDEV_Init start\n");
jsize size = (env)->GetArrayLength(addrssList);
int i = 0;
for (i = 0; i < size; i++) {
jstring jstrAddrss = (jstring)env->GetObjectArrayElement(addrssList, i);
thread newThread(openOnBroadcast, Jstring2CStr(env, jstrAddrss));
newThread.detach();
}
printf("NETDEV_Init done\n");
}
/*
广播----关闭
*/
JNIEXPORT void JNICALL Java_cn_xx_utils_YuShiNetDevSDKUtils_stopVoiceBroadcast
(JNIEnv* env, jclass) {
if (!flag) {
return;
}
//先让启动的广播退出,再执行网络清除命令。
flag = false;
//停止语音对讲
map<char*, LPVOID>::iterator iter2 = playHandleList.begin();
for (iter2 = playHandleList.begin(); iter2 != playHandleList.end(); iter2++) {
if (iter2->second != NULL) {
NETDEV_StopVoiceBroadcast(iter2->second);
}
}
playHandleList.clear();
//注销用户
map<char*, LPVOID>::iterator iter = userIdList.begin();
for (iter = userIdList.begin(); iter != userIdList.end(); iter++) {
if (iter->second != NULL) {
NETDEV_Logout(iter->second);
}
}
userIdList.clear();
/*
*释放SDK资源, 多摄像头如果在网络登录状态下,突然释放资源,程序会崩溃, 需要给登录的过程足够的时间。
*或者就不调用NETDEV_Cleanup(),让网络状态一直有效。程序退出的时候调用它。
*/
// NETDEV_Cleanup();
printf("broadcast close done\n");
}
JNIEXPORT void JNICALL Java_cn_xx_utils_YuShiNetDevSDKUtils_openSpeak
(JNIEnv* env, jclass, jstring ipaddress) {
//JNI调用此函数,只会调用单例模式下的函数。所以重复调用让它失败。
if (lUserID != NULL) {
return;
}
NETDEV_Init();
printf("system inited \n");
//设置连接时间
NETDEV_REV_TIMEOUT_S stRevTimeout = { 0 };
stRevTimeout.dwRevTimeOut = 5;
stRevTimeout.dwFileReportTimeOut = 30;
NETDEV_SetRevTimeOut(&stRevTimeout);
//登录参数,包括设备地址、登录用户、密码等
NETDEV_DEVICE_LOGIN_INFO_S stDevLoginInfo = { 0 };
strncpy_s(stDevLoginInfo.szIPAddr, Jstring2CStr(env, ipaddress), sizeof(stDevLoginInfo.szIPAddr)); //设备IP地址
strncpy_s(stDevLoginInfo.szUserName, "admin", sizeof(stDevLoginInfo.szUserName)); //设备登录用户名
strncpy_s(stDevLoginInfo.szPassword, "123456", sizeof(stDevLoginInfo.szPassword)); //设备登录密码
stDevLoginInfo.dwPort = 80; //设备服务端口
stDevLoginInfo.dwLoginProto = NETDEV_LOGIN_PROTO_ONVIF; //登录协议
//输出参数,仅私有协议登录有效
NETDEV_SELOG_INFO_S stSELogInfo = { 0 };
lUserID = NETDEV_Login_V30(&stDevLoginInfo, &stSELogInfo);
if (NULL == lUserID)
{
printf("Login failed, error code: %d\n", NETDEV_GetLastError());
//释放SDK资源
NETDEV_Cleanup();
return;
}
printf("Login sucessful, %d\n", stSELogInfo);
//通道查询
NETDEV_VIDEO_CHL_DETAIL_INFO_EX_S stVideoChlDetailInfoEx[128] = { 0 }; //分配个通道
INT32 dwCount = 128; //128个通道
BOOL bRet = NETDEV_QueryVideoChlDetailListEx(lUserID, &dwCount, stVideoChlDetailInfoEx);
if (FALSE == bRet && NETDEV_E_NEEDMOREDATA == NETDEV_GetLastError())
{
//默认分配数组大小小于实际通道数,重新分配内存获取
NETDEV_VIDEO_CHL_DETAIL_INFO_EX_S* pstVideoChlDetailInfoEx = new NETDEV_VIDEO_CHL_DETAIL_INFO_EX_S[dwCount];
memset(pstVideoChlDetailInfoEx, 0, sizeof(NETDEV_VIDEO_CHL_DETAIL_INFO_EX_S) * dwCount);
bRet = NETDEV_QueryVideoChlDetailListEx(lUserID, &dwCount, pstVideoChlDetailInfoEx);
//释放分配内存
delete[]pstVideoChlDetailInfoEx;
}
if (TRUE == bRet) {
printf("QueryVideoChlDetailList Success\n");
}
else {
printf("QueryVideoChlDetailList failed, error code: %d\n", NETDEV_GetLastError());
}
//开启语音对讲
LPVOID lpPlayHandle = NETDEV_StartVoiceCom(lUserID, 1, NETDEV_DECODE_AUDIO_DATA_CALLBACK, 0);
if (NULL == lpPlayHandle)
{
printf("StartVoiceCom failed, error code: %d\n", NETDEV_GetLastError());
}
else
{
Sleep(20000); //millisecond
//停止语音对讲
NETDEV_StopVoiceCom(lpPlayHandle);
}
//注销用户
NETDEV_Logout(lUserID);
//释放SDK资源
NETDEV_Cleanup();
lUserID = NULL;
printf("NETDEV_Init done\n");
}
错误及解决方法
1.UnsatisfiedLinkError java.library.path
Exception in thread "main" java.lang.UnsatisfiedLinkError: no YuShiNetDll in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1122)
at cn.xx.lt.jni.NetDEVSDK.<clinit>(NetDEVSDK.java:6)
解决方法:
将所有的dll文件拷贝到一个文件夹下
Java项目导入libs文件夹。
2.麦克风调整
3.UnsatisfiedLinkError V
Exception in thread "main" java.lang.UnsatisfiedLinkError: cn.xx.utils.YuShiNetDevSDKUtils.test(I)V
at cn.xx.utils.YuShiNetDevSDKUtils.test(Native Method)
at cn.xx.utils.YuShiNetDevSDKUtils.main(YuShiNetDevSDKUtils.java:27)
Dll没有正确部署,或者写的JNI不正确导致