java调用宇视摄像头,实现双向语音

宇视摄像头双向语音-第一部分

IPC672LR-ADUWKCF40-DT浙江宇视摄像头

IPC&NVR&VMS&显控—浙江宇视科技有限公司

他们官网的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++---常规---附加包含目录:加上头文件存放目录。

添加文件引用的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不正确导致

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,要使用Java OpenCV调用摄像头并进行文字识别,您需要遵循以下步骤: 1. 安装Tesseract OCR引擎 Tesseract OCR引擎是一个开源的OCR引擎,可以识别多种语言的文本。您可以从Tesseract OCR官方网站下载并安装Tesseract OCR引擎。 2. 导入Tesseract OCR库 在Java项目中,您需要导入Tesseract OCR库。您可以使用Maven和Gradle等构建工具来导入Tesseract OCR库。 3. 调用摄像头 您可以使用Java OpenCV中的VideoCapture类调用摄像头。以下是一个简单的示例代码: ``` import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.videoio.VideoCapture; public class CameraCapture { public static void main(String[] args) { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); VideoCapture camera = new VideoCapture(0); if(!camera.isOpened()){ System.out.println("Error"); } else { Mat frame = new Mat(); while(true){ if (camera.read(frame)){ System.out.println("Frame Obtained"); System.out.println("Captured Frame Width " + frame.width() + " Height " + frame.height()); Core.flip(frame, frame, 1); break; } } } camera.release(); } } ``` 此代码段将获取从摄像头获取的帧并将其翻转。 4. 文字识别 要进行文字识别,您可以使用Java OpenCV中的Imgcodecs类将帧转换为图像,然后使用Tesseract OCR库进行识别。以下是一个简单的示例代码: ``` import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.videoio.VideoCapture; import net.sourceforge.tess4j.*; public class TextRecognition { public static void main(String[] args) { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); VideoCapture camera = new VideoCapture(0); Mat frame = new Mat(); while (true){ if (camera.read(frame)){ Mat grayFrame = new Mat(); Imgproc.cvtColor(frame, grayFrame, Imgproc.COLOR_BGR2GRAY); File imageFile = new File("image.png"); Imgcodecs.imwrite(imageFile.getAbsolutePath(), grayFrame); ITesseract tess = new Tesseract(); tess.setDatapath("tessdata"); tess.setLanguage("eng"); String result = tess.doOCR(imageFile); System.out.println(result); HighGui.imshow("Text Recognition", frame); HighGui.waitKey(1); } } } } ``` 此代码段将在从摄像头获取的帧中识别文本。它首先将帧转换为灰度图像,然后将其保存到磁盘上的图像文件中。然后,它使用Tesseract OCR库对图像文件中的文本进行识别,并将结果打印到控制台上。您需要将Tesseract OCR库的数据路径设置为“tessdata”文件夹,其中包含识别语言的数据文件。 希望这可以帮助您开始使用Java OpenCV调用摄像头并进行文字识别。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值