大华摄像头使用外网接收数据
Posted qianbo_insist
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了大华摄像头使用外网接收数据相关的知识,希望对你有一定的参考价值。
获取摄像头数据的方法
方法有几种
1 rtsp 获取后转发到外网
2 直接配置大华摄像头发送到外网
第一种方法有缺陷,不直接,需要转发服务,但是一种比较可靠的方法,如果网络中不能直接发出去,只能通过转发服务,那可以使用最为通用的方案,就是rtsp拉取后直接转发送到外网。
第二种方法使用要必须内网直接访问到外网,也就是摄像头可以直接连接到外网。
我们使用第二种方法,大华里面有一个配置是可以直接配置一个IP地址和端口,使用tcp方式直接推到外网的,不过,缺点就是,你得使用大华的sdk去接收,这样工作量少。
建立数据结构推到外网
#pragma once
#include <mutex>
#include <string>
#include <map>
#include <set>
#include <list>
#include "websocketpp_server.h"
#include "dhnetsdk.h"
#include "dhplay.h"
#include "../RTMPPusher/H264AACRtmp.h"
#include "../RTMPPusher/TPacket.h"
#include "..\\RecordAudio\\audioRecord.h"
#include "web_send.h"
#pragma comment( lib, "dhnetsdk.lib")
#pragma comment( lib, "dhplay.lib")
using namespace std;
typedef struct tagDH_DEVICE_INFO
string szDevSerial;
string szDevName;
string videofile_name;
string szIP;
int nPort;
string szUseName;
string szPassWord;
int nLoginType; // 0:IP登录1:主动注册登录
int nLoginStatus; // 设备状态,0:离线 1:排队登录 2:在线 3:停止预览 4 :当前设备正在播放中 5:注册失败 等待下次注册
int nLoginTimes; // 尝试登录次数
long long lLoginID; // 登录句柄
long long lRealHandle; //播放句柄
baseinfo * baseserver = NULL;
con_list connections; //摄像头连接链表
uint32_t frist_timestamp=0;
uint32_t current_timestamp=0;
LONG lRealPort ; //设备的播放库port号 一个设备一个 不能重复
//H264AACRtmp hr; //推送给RTMP的连接对象
TQPacket *packet=NULL;
telemetry_client web_client;//视频发送通道
string audio_url="";
string video_url = "";
telemetry_client send_aac;//发送音频通道
audioRecord gater_aac;//录音对象
DH_DEVICE_INFO;
typedef struct tagNODE_SESSION
baseinfo * baseserver = NULL;
con_list connections;
long long heartTime = 0;
NODE_SESSION;
class devClass
private:
devClass();
//node_list m_node_list;
public:
//set<NODE_SESSION*> m_node_connect;
baseinfo * pWServer = NULL;
~devClass();
static devClass* GetInstance();
mutex mut;
map<string, DH_DEVICE_INFO *> mymap;
//map<connection_hdl, NODE_SESSION *> _node_map;
list<NODE_SESSION *> node_list;
map<string, NODE_SESSION *> node_map;
//map<char *, string> clientHdl_map;
void setBaseServer(baseinfo * info);
baseinfo * getBaseServer();
void addDevSession(string dev_serial, string username, string pass)
std::lock_guard<std::mutex> guard(mut);
DH_DEVICE_INFO * pinfo = NULL;
auto map = mymap.find(dev_serial); //通过key确认设备是否注册
if (map != mymap.end()) //不等于end说明设备已经注册
pinfo = map->second;//将设备信息给pinfo
if (pinfo != NULL) //更新mymap中key对应的设备信息
pinfo->baseserver = pWServer;//
pinfo->szDevSerial = dev_serial;
pinfo->szUseName = username;
pinfo->szPassWord = pass;
OUTINFO_3_PARAM("set info repate success id = %s , username = %s ,pwd = %s \\n", dev_serial.c_str(),username.c_str(),pass.c_str());
else
DH_DEVICE_INFO * pinfo = new DH_DEVICE_INFO();
pinfo->baseserver = pWServer;
pinfo->nLoginStatus = 0;
pinfo->szDevSerial = dev_serial;
pinfo->szUseName = username;
pinfo->szPassWord = pass;
mymap[dev_serial] = pinfo;
OUTINFO_3_PARAM("set info scuuess id = %s , username = %s ,pwd = %s \\n", dev_serial.c_str(), username.c_str(), pass.c_str());
int addDevSession(string dev_serial, connection_hdl hd)
std::lock_guard<std::mutex> guard(mut);
//char * p = (char*)&hd;
auto iter = mymap.find(dev_serial);
if (iter != mymap.end())
DH_DEVICE_INFO * pinfo = iter->second;
pinfo->connections.insert(hd);
int size = pinfo->connections.size();
OUTINFO_1_PARAM("set connections scuuess size = %d \\n", size);
return 0;
OUTINFO_0_PARAM("set connections error = no this dev \\n");
return -1;
void addNodeSession(string key, connection_hdl hd)
OUTINFO_0_PARAM("BEGIN addNodeSession\\n");
std::lock_guard<std::mutex> guard(mut);
NODE_SESSION * pnode = new NODE_SESSION();
pnode->connections.clear();
pnode->connections.insert(hd);
pnode->baseserver = pWServer;
//pnode->connections.clear();
node_map[key] = pnode;
int size = pnode->connections.size();
OUTINFO_1_PARAM("set node_hdl=%s scuuess\\n", key.c_str());
OUTINFO_1_PARAM("this nodeconnect size = %d \\n" , size );
OUTINFO_0_PARAM("END addNodeSession\\n");
void addNodeSessionHeartTIme(string key, connection_hdl hd, long long heartTime)
OUTINFO_0_PARAM("BEGIN addNodeSession\\n");
std::lock_guard<std::mutex> guard(mut);
auto iter = node_list.begin();
int size;
while (iter != node_list.end())
NODE_SESSION * pnode = *iter;
con_list &set = pnode->connections;
if (set.find(hd) != set.end()) //找到当前句柄
size = node_list.size();
OUTINFO_0_PARAM("have been addNodeSession\\n");
OUTINFO_1_PARAM("this nodeconnect size = %d \\n", size);
OUTINFO_0_PARAM("END addNodeSession\\n");
return;
iter++;
NODE_SESSION * pnode = new NODE_SESSION();
pnode->connections.insert(hd);
pnode->baseserver = pWServer;
pnode->heartTime = heartTime;
node_list.push_back(pnode);
size = node_list.size();
OUTINFO_1_PARAM("set node_hdl=%s scuuess\\n", key.c_str());
OUTINFO_1_PARAM("this nodeconnect size = %d \\n", size);
OUTINFO_0_PARAM("END addNodeSession\\n");
int removehd(string key, connection_hdl hd)
std::lock_guard<std::mutex> guard(mut);
auto map = mymap.find(key);
DH_DEVICE_INFO * pinfo = NULL;
if (map != mymap.end())
pinfo = map->second;
pinfo->connections.erase(hd);
int size = pinfo->connections.size();
OUTINFO_1_PARAM(" connect size = %d \\n", size);
if (pinfo != NULL && pinfo->nLoginStatus ==4 && pinfo->connections.size() == 0)
OUTINFO_0_PARAM(" stop playing \\n");
//当前没有浏览器请求流
devClass * pdevClass = devClass::GetInstance();
// 根据当前播放的 句柄断开连接
//关闭预览
//关闭预览
//启动一个线程关闭播放 不影响webscoket 通信
stopPlay(pinfo);
//注销用户
//CLIENT_Logout(pinfo->lLoginID);
return 0;
void stopPlay(DH_DEVICE_INFO * pinfo);
int set(string key, const char *pIp, WORD wPort, int status,LONG lRealPort);
void setheartTime(connection_hdl hdl,long long heartTime)
auto iter = node_list.begin();
while (iter != node_list.end())
NODE_SESSION * pnode = *iter;
con_list &set = pnode->connections;
if (set.find(hdl) != set.end()) //找到当前句柄
pnode->heartTime = heartTime;
OUTINFO_1_PARAM("set heart time = %lld \\n", heartTime);
break;
iter++;
int setlLoginID(string key, long long lLoginID)
std::lock_guard<std::mutex> guard(mut);
DH_DEVICE_INFO * pinfo = NULL;
auto map = mymap.find(key);
if (map != mymap.end() )
pinfo = map->second;
if (pinfo != NULL)
pinfo->lLoginID = lLoginID;
else
return -1;
return 0;
;
int setlRealHandle(string key, long long lRealHandle)
OUTINFO_0_PARAM(" BEGIN setlRealHandle \\n");
std::lock_guard<std::mutex> guard(mut);
auto map = mymap.find(key);
DH_DEVICE_INFO * pinfo = NULL;
if (map != mymap.end())
pinfo = map->second;
if (pinfo != NULL)
pinfo->lRealHandle = lRealHandle;
OUTINFO_1_PARAM(" END setlRealHandle handeleid = %lld \\n" , lRealHandle);
return 0;
else
OUTINFO_0_PARAM(" END setlRealHandle error = -1 \\n");
return -1;
int setLoginStatus(string key, int status);
int getLoginStatus(string key);
int getDevSession(string key, DH_DEVICE_INFO * dhInfo);
void delDevSession(string key);
void Send(char * p, int len, string key)
std::lock_guard<std::mutex> guard(mut);
try
DH_DEVICE_INFO * pinfo = NULL;
auto map = mymap.find(key);
if (map != mymap.end())
pinfo = map->second;
con_list &set = pinfo->connections;
con_list::iterator it;
for (it = set.begin(); it != set.end(); ++it)
pinfo->baseserver->SendFrame(*it, p, len);
catch (string const & e)
OUTINFO_1_PARAM("Send error = %s \\n", e.c_str());
void Send(void * devSerial, int status)
OUTINFO_0_PARAM("BEGIN SEND_DEV_STA\\n");
std::lock_guard<std::mutex> guard(mut);
try
auto iter = node_list.begin();
while (iter != node_list.end())
NODE_SESSION * pnode = *iter;
if (pnode != NULL)
con_list &set = pnode->connections;
con_list::iterator it;
for (it = set.begin(); it != set.end(); ++it)
pnode->baseserver->SendFrame(*it, devSerial, status);
iter++;
catch (string const & e)
//std::cout << e.c_str() << std::endl;
OUTINFO_1_PARAM("SEND_DEV_STA error = %s \\n", e.c_str());
OUTINFO_0_PARAM("END SEND_DEV_STA\\n");
void Send(string devSerial,string pic_name)
std::lock_guard<std::mutex> guard(mut);
try
auto iter = node_list.begin();
while (iter != node_list.end())
NODE_SESSION * pnode = *iter;
if (pnode != NULL)
con_list &set = pnode->connections;
con_list::iterator it;
for (it = set.begin(); it != set.end(); ++it)
pnode->baseserver->SendFrame(*it, devSerial, pic_name);
iter++;
catch (string const & e)
OUTINFO_1_PARAM("SEND_DEV_STA error = %s \\n", e.c_str());
void delete_mem()
//lock
//map<string, DH_DEVICE_INFO *> mymap;
//map<connection_hdl, NODE_SESSION *> _node_map;
//list<NODE_SESSION *> node_map;
auto iter = mymap.begin();
while (iter != mymap.end())
DH_DEVICE_INFO *item = iter->second;
delete item;
iter++;
auto iter1 = node_list.begin();
while (iter1 != node_list.end())
NODE_SESSION * s = *iter1;
delete s;
iter1++;
;
建立websocket 服务
为了使得数据能够被浏览器访问,建立一个websocket服务,直接转发h264,也可以转发到rtmp server,两种方式都可以,程序里面有。主要程序如下所示
#define _CRT_SECURE_NO_WARNINGS
#include "websocketpp_server.h"
#include "devClass.h"
#include "dhServer.h"
broadcast_server::broadcast_server()
m_server.init_asio();
m_server.set_open_handler(bind(&broadcast_server::on_open, this, std::placeholders::_1));
m_server.set_close_handler(bind(&broadcast_server::on_close, this, std::placeholders::以上是关于大华摄像头使用外网接收数据的主要内容,如果未能解决你的问题,请参考以下文章
大华硬盘录像机网络摄像机 网络硬盘录像机外网远程设置DDNS方法