大华摄像头使用外网接收数据

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方法

java调用大华摄像头,web端播放和云控制,谁研究过?谢谢……

大华摄像机怎样添加海康录像机?

大华的硬盘录像机,文件丢失了怎么办?

音视频开发:大华摄像头配置RTSP地址访问视频画面