searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

海康sdk录像回放实现方法

2024-09-09 09:48:01
73
0
 

在使用海康sdk进行开发所有流程都是

1、  初始化sdk

2、  登录设备

3、  执行具体操作(实时预览、录像回放、录像查询、PTZ控制等操作)

4、  退出设备

5、  销毁sdk

 

录像回放过程

特别说明由于sdk长期迭代,所以能看到很多类似的方法,后面跟着 "_Vxxx"例如登录方法有NET_DVR_Login、NET_DVR_Login_V30、NET_DVR_Login_V40一般我们选用数字更大的方法,支持功能更全面

1、初始化sdk

实际开发中,初始化完成之后一般都会初始化之后设置超时、重连、日志异常回调信息

用到的方法:

NET_DVR_API BOOL __stdcall NET_DVR_Init();
NET_DVR_API BOOL __stdcall NET_DVR_SetConnectTime(DWORD dwWaitTime = 3000, DWORD dwTryTimes = 3);
NET_DVR_API BOOL __stdcall NET_DVR_SetReconnect(DWORD dwInterval = 30000, BOOL bEnableRecon = TRUE);
NET_DVR_API BOOL __stdcall NET_DVR_SetLogToFile(DWORD nLogLevel = 0, char * strLogDir = NULL, BOOL bAutoDel = TRUE);
NET_DVR_API BOOL __stdcall NET_DVR_SetExceptionCallBack_V30(UINT reserved1, void* reserved2, void (CALLBACK* fExceptionCallBack)(DWORD dwType, LONG lUserID, LONG lHandle, void *pUser), void *pUser);

2、登录设备

登录用到方法NET_DVR_Login_V40需要提供登录设备地址端口用户密码端口一般情况8000。

返回值表示登录句柄,不小于0表示成功,句柄需要保存起来,后续所有的对设备的操作都要用到这个句柄。返回登录成功之后出参获取到一些设备信息。

以下是登录示例代码:

NET_DVR_USER_LOGIN_INFO loginInfo;
NET_DVR_DEVICEINFO_V40 deviceInfo;

loginInfo.wPort = 8000;
strcpy(loginInfo.sDeviceAddress, "192.168.1.100");
strcpy(loginInfo.sUserName, "admin");
strcpy(loginInfo.sPassword, "123456");

LONG lUserID = NET_DVR_Login_V40(&loginInfo, &deviceInfo);
if (lRet < 0) {
    printf("Login failed, error code: %s\n", NET_DVR_GetLastError());
}

3、录像查找

录像查找分三步

1、  使用NET_DVR_FindFile_V50方法执行查找操作成功返回查找句柄

2、  循环使用NET_DVR_FindNextFile_V50方法通过查找句柄获取查找结果。

NET_DVR_FindNextFile_V50返回值取值:

#define NET_DVR_FILE_SUCCESS       1000    //获得文件信息
#define NET_DVR_FILE_NOFIND        1001    //没有文件
#define NET_DVR_ISFINDING          1002    //正在查找文件
#define    NET_DVR_NOMOREFILE      1003    //查找文件时没有更多的文件
#define    NET_DVR_FILE_EXCEPTION  1004    //查找文件时异常
#define NET_DVR_FIND_TIMEOUT       1005    //查找文件超时

3、  查找结束使用NET_DVR_FindClose_V30关闭查找句柄。

示例:

//查找条件
NET_DVR_FILECOND_V50 struFileCond;
 
int lFindHandle = NET_DVR_FindFile_V50(lUserID, &struFileCond);
if (lFindHandle >= 0)
{
    //逐个获取查询文件结果
    NET_DVR_FINDDATA_V50 struFileData;
    while (true)
    {
        int result = NET_DVR_FindNextFile_V50(lFindHandle, &struFileData);
        if (result == NET_DVR_ISFINDING)
        {
            continue;
        }
        else if (result == NET_DVR_FILE_SUCCESS)
        {
            continue;
        }
        else if (result == NET_DVR_FILE_NOFIND || result == NET_DVR_NOMOREFILE)
        {
            break;
        }
        else
        {
            printf("find file fail for illegal get file state");
            break;
        }
    }

    //停止查找,释放资源
    NET_DVR_FindClose_V30(lFindHandle);
}

4、播放录像

需要用到方法

1、  时间回放NET_DVR_PlayBackByTime_V50

2、  设置码流回调

回调ESNET_DVR_SetPlayBackESCallBack

回调封装NET_DVR_SetPlayDataCallBack_V40

3、  回放控制NET_DVR_PlayBackControl_V40

示例:

NET_DVR_VOD_PARA_V50 vodPara;

// 按时间回放
int hPlayback  = NET_DVR_PlayBackByTime_V50(ptReq->lUserId, &vodPara);
if (hPlayback  < 0) {
    ErrorL << "NET_DVR_PlayBackByTime_V40 error, " << NET_DVR_GetLastError();
    return -1;
}

//(可选)设置ES码流回调,
NET_DVR_SetPlayBackESCallBack(
    hPlayback ,
    [](LONG lPlayHandle, NET_DVR_PACKET_INFO_EX *pstruPackInfo, void *pUserData) {},
    NULL);
    
//(可选)设置封装码流回调    
NET_DVR_SetPlayDataCallBack_V40(
    mSdkPlayHandle,
    [](LONG lPlayHandle, DWORD dwDataType, BYTE *pBuffer, DWORD dwBufSize, void *pUser) {},
    NULL);    

// 开始播放
NET_DVR_PlayBackControl_V40(hPlayback , NET_DVR_PLAYSTART);

特别说明:

调用完回放方法之后,一定需要调用回放控制方法传NET_DVR_PLAYSTART(开始播放命令)才会真正开始播放

4.1、码流回调

如果回放参数填了播放窗口句柄画面可以直接窗口播放否则需要设置码流回调自己处理码流

码流回调示例:

void dataCallback(LONG lPlayHandle, DWORD dwDataType, BYTE *pBuffer,DWORD dwBufSize,DWORD dwUser) {
    
    switch (dwDataType) {
    case NET_DVR_SYSHEAD: { //系统头数据
        
        }
        break;
    case NET_DVR_STREAMDATA: { //流数据(包括复合流或音视频分开的视频流数据)
        }
        break;
    case NET_DVR_AUDIOSTREAMDATA: { //音频数据
        }
        break;
    case NET_DVR_PRIVATE_DATA: { //私有数据,包括智能信息
        }
        break;
    default:
        break;
    }
}

ES流回调示例:

void esDataCallback(LONG lPlayHandle, NET_DVR_PACKET_INFO_EX *struPackInfo,  void* pUser) {

    // 0系统头; 1、2、3视频;10音频
    if (0 == pstruPackInfo->dwPacketType) {
        
    } else if (1 == pstruPackInfo->dwPacketType 
                || 2 == pstruPackInfo->dwPacketType 
                || 3 == pstruPackInfo->dwPacketType 
                || 10 == pstruPackInfo->dwPacketType) {
        
    }
}
 

遇到的问题:

当播放参数请求没有传递窗口句柄码流回调会以最大码率发送表现效果就是可能一分钟就把几十分钟录像全部回调播放

解决办法

1、  通过回放控制方法NET_DVR_SETSPEED(设置码率命令)回调码率设置成当前视频码率就行

2、  非常规办法,曾经遇到过设置码率没有效果情况,改成ES回调里面判断回调码流时间戳结合前后回调时间戳以及本地时间计算出时间之后通过sleep实现延缓码流回调

5、停止播放

停止播放用到的方法只有一个NET_DVR_StopPlayBack入参录像回放方法返回句柄

函数原型

NET_DVR_API BOOL __stdcall NET_DVR_StopPlayBack(LONG lPlayHandle);

6、登出设备

登出设备只需调用NET_DVR_Logout_V30方法参数登录获取到登录句柄

函数原型

NET_DVR_API BOOL __stdcall NET_DVR_Logout_V30(LONG lUserID);

7、销毁sdk

退出很简单,只需调用NET_DVR_Cleanup方法

函数原型

NET_DVR_API BOOL __stdcall NET_DVR_Cleanup();

0条评论
0 / 1000
c****n
4文章数
0粉丝数
c****n
4 文章 | 0 粉丝
原创

海康sdk录像回放实现方法

2024-09-09 09:48:01
73
0
 

在使用海康sdk进行开发所有流程都是

1、  初始化sdk

2、  登录设备

3、  执行具体操作(实时预览、录像回放、录像查询、PTZ控制等操作)

4、  退出设备

5、  销毁sdk

 

录像回放过程

特别说明由于sdk长期迭代,所以能看到很多类似的方法,后面跟着 "_Vxxx"例如登录方法有NET_DVR_Login、NET_DVR_Login_V30、NET_DVR_Login_V40一般我们选用数字更大的方法,支持功能更全面

1、初始化sdk

实际开发中,初始化完成之后一般都会初始化之后设置超时、重连、日志异常回调信息

用到的方法:

NET_DVR_API BOOL __stdcall NET_DVR_Init();
NET_DVR_API BOOL __stdcall NET_DVR_SetConnectTime(DWORD dwWaitTime = 3000, DWORD dwTryTimes = 3);
NET_DVR_API BOOL __stdcall NET_DVR_SetReconnect(DWORD dwInterval = 30000, BOOL bEnableRecon = TRUE);
NET_DVR_API BOOL __stdcall NET_DVR_SetLogToFile(DWORD nLogLevel = 0, char * strLogDir = NULL, BOOL bAutoDel = TRUE);
NET_DVR_API BOOL __stdcall NET_DVR_SetExceptionCallBack_V30(UINT reserved1, void* reserved2, void (CALLBACK* fExceptionCallBack)(DWORD dwType, LONG lUserID, LONG lHandle, void *pUser), void *pUser);

2、登录设备

登录用到方法NET_DVR_Login_V40需要提供登录设备地址端口用户密码端口一般情况8000。

返回值表示登录句柄,不小于0表示成功,句柄需要保存起来,后续所有的对设备的操作都要用到这个句柄。返回登录成功之后出参获取到一些设备信息。

以下是登录示例代码:

NET_DVR_USER_LOGIN_INFO loginInfo;
NET_DVR_DEVICEINFO_V40 deviceInfo;

loginInfo.wPort = 8000;
strcpy(loginInfo.sDeviceAddress, "192.168.1.100");
strcpy(loginInfo.sUserName, "admin");
strcpy(loginInfo.sPassword, "123456");

LONG lUserID = NET_DVR_Login_V40(&loginInfo, &deviceInfo);
if (lRet < 0) {
    printf("Login failed, error code: %s\n", NET_DVR_GetLastError());
}

3、录像查找

录像查找分三步

1、  使用NET_DVR_FindFile_V50方法执行查找操作成功返回查找句柄

2、  循环使用NET_DVR_FindNextFile_V50方法通过查找句柄获取查找结果。

NET_DVR_FindNextFile_V50返回值取值:

#define NET_DVR_FILE_SUCCESS       1000    //获得文件信息
#define NET_DVR_FILE_NOFIND        1001    //没有文件
#define NET_DVR_ISFINDING          1002    //正在查找文件
#define    NET_DVR_NOMOREFILE      1003    //查找文件时没有更多的文件
#define    NET_DVR_FILE_EXCEPTION  1004    //查找文件时异常
#define NET_DVR_FIND_TIMEOUT       1005    //查找文件超时

3、  查找结束使用NET_DVR_FindClose_V30关闭查找句柄。

示例:

//查找条件
NET_DVR_FILECOND_V50 struFileCond;
 
int lFindHandle = NET_DVR_FindFile_V50(lUserID, &struFileCond);
if (lFindHandle >= 0)
{
    //逐个获取查询文件结果
    NET_DVR_FINDDATA_V50 struFileData;
    while (true)
    {
        int result = NET_DVR_FindNextFile_V50(lFindHandle, &struFileData);
        if (result == NET_DVR_ISFINDING)
        {
            continue;
        }
        else if (result == NET_DVR_FILE_SUCCESS)
        {
            continue;
        }
        else if (result == NET_DVR_FILE_NOFIND || result == NET_DVR_NOMOREFILE)
        {
            break;
        }
        else
        {
            printf("find file fail for illegal get file state");
            break;
        }
    }

    //停止查找,释放资源
    NET_DVR_FindClose_V30(lFindHandle);
}

4、播放录像

需要用到方法

1、  时间回放NET_DVR_PlayBackByTime_V50

2、  设置码流回调

回调ESNET_DVR_SetPlayBackESCallBack

回调封装NET_DVR_SetPlayDataCallBack_V40

3、  回放控制NET_DVR_PlayBackControl_V40

示例:

NET_DVR_VOD_PARA_V50 vodPara;

// 按时间回放
int hPlayback  = NET_DVR_PlayBackByTime_V50(ptReq->lUserId, &vodPara);
if (hPlayback  < 0) {
    ErrorL << "NET_DVR_PlayBackByTime_V40 error, " << NET_DVR_GetLastError();
    return -1;
}

//(可选)设置ES码流回调,
NET_DVR_SetPlayBackESCallBack(
    hPlayback ,
    [](LONG lPlayHandle, NET_DVR_PACKET_INFO_EX *pstruPackInfo, void *pUserData) {},
    NULL);
    
//(可选)设置封装码流回调    
NET_DVR_SetPlayDataCallBack_V40(
    mSdkPlayHandle,
    [](LONG lPlayHandle, DWORD dwDataType, BYTE *pBuffer, DWORD dwBufSize, void *pUser) {},
    NULL);    

// 开始播放
NET_DVR_PlayBackControl_V40(hPlayback , NET_DVR_PLAYSTART);

特别说明:

调用完回放方法之后,一定需要调用回放控制方法传NET_DVR_PLAYSTART(开始播放命令)才会真正开始播放

4.1、码流回调

如果回放参数填了播放窗口句柄画面可以直接窗口播放否则需要设置码流回调自己处理码流

码流回调示例:

void dataCallback(LONG lPlayHandle, DWORD dwDataType, BYTE *pBuffer,DWORD dwBufSize,DWORD dwUser) {
    
    switch (dwDataType) {
    case NET_DVR_SYSHEAD: { //系统头数据
        
        }
        break;
    case NET_DVR_STREAMDATA: { //流数据(包括复合流或音视频分开的视频流数据)
        }
        break;
    case NET_DVR_AUDIOSTREAMDATA: { //音频数据
        }
        break;
    case NET_DVR_PRIVATE_DATA: { //私有数据,包括智能信息
        }
        break;
    default:
        break;
    }
}

ES流回调示例:

void esDataCallback(LONG lPlayHandle, NET_DVR_PACKET_INFO_EX *struPackInfo,  void* pUser) {

    // 0系统头; 1、2、3视频;10音频
    if (0 == pstruPackInfo->dwPacketType) {
        
    } else if (1 == pstruPackInfo->dwPacketType 
                || 2 == pstruPackInfo->dwPacketType 
                || 3 == pstruPackInfo->dwPacketType 
                || 10 == pstruPackInfo->dwPacketType) {
        
    }
}
 

遇到的问题:

当播放参数请求没有传递窗口句柄码流回调会以最大码率发送表现效果就是可能一分钟就把几十分钟录像全部回调播放

解决办法

1、  通过回放控制方法NET_DVR_SETSPEED(设置码率命令)回调码率设置成当前视频码率就行

2、  非常规办法,曾经遇到过设置码率没有效果情况,改成ES回调里面判断回调码流时间戳结合前后回调时间戳以及本地时间计算出时间之后通过sleep实现延缓码流回调

5、停止播放

停止播放用到的方法只有一个NET_DVR_StopPlayBack入参录像回放方法返回句柄

函数原型

NET_DVR_API BOOL __stdcall NET_DVR_StopPlayBack(LONG lPlayHandle);

6、登出设备

登出设备只需调用NET_DVR_Logout_V30方法参数登录获取到登录句柄

函数原型

NET_DVR_API BOOL __stdcall NET_DVR_Logout_V30(LONG lUserID);

7、销毁sdk

退出很简单,只需调用NET_DVR_Cleanup方法

函数原型

NET_DVR_API BOOL __stdcall NET_DVR_Cleanup();

文章来自个人专栏
sdk对接
1 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
1
0