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


    获取摄像头数据的方法

    方法有几种
    1 rtsp 获取后转发到外网
    2 直接配置大华摄像头发送到外网

    第一种方法有缺陷,不直接,需要转发服务,但是一种比较可靠的方法,如果网络中不能直接发出去,只能通过转发服务,那可以使用最为通用的方案,就是rtsp拉取后直接转发送到外网。

    第二种方法使用要必须内网直接访问到外网,也就是摄像头可以直接连接到外网。
    我们使用第二种方法,大华里面有一个配置是可以直接配置一个IP地址和端口,使用tcp方式直接推到外网的,不过,缺点就是,你得使用大华的sdk去接收,这样工作量少。

    程序下载在此

    建立数据结构推到外网

    #pragma once
    #include 
    #include 
    #include   
    #include 
    #include 
    #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 m_node_connect;
    	baseinfo * pWServer = NULL;
    	~devClass();
    	static devClass* GetInstance();
    	mutex mut; 
    	map<string, DH_DEVICE_INFO *> mymap;
    	//map _node_map;
    	list<NODE_SESSION *> node_list;
    	map<string, NODE_SESSION *> node_map;
    	//map 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 mymap;
    		//map _node_map;
    		//list 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++;
    			}
    		}
    	}
    		 
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348

    建立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::_1));
    	m_server.set_message_handler(bind(&broadcast_server::on_message, this, std::placeholders::_1, std::placeholders::_2));
    }
    
    void broadcast_server::run(uint16_t port) {
    	m_server.listen(port);
    	m_server.start_accept();
    	try {
    		OUTINFO_1_PARAM("***WS server Listen Success! port:%d ***\n", port);
    		m_server.run();
    	}
    	catch (const std::exception & e) {
    		OUTINFO_1_PARAM(" WS server Listen fail ! error:%s\n", e.what());
    	}
    }
    
    void broadcast_server::on_open(connection_hdl hdl) {
    		//lock_guard guard(m_action_lock);
    		OUTINFO_0_PARAM(" WS server on_open \n" );
    		//m_actions.push(action(SUBSCRIBE, hdl));
    		//m_action_cond.notify_one();
    }
    
    void broadcast_server::on_close(connection_hdl hdl) {
    	
    		//lock_guard guard(m_action_lock);
    		OUTINFO_0_PARAM(" WS server on_close \n");
    		devClass * pdevclass = devClass::GetInstance();
    		/*map clientHdl_map = pdevclass->clientHdl_map;
    		string id = clientHdl_map[(char*)&hdl] ;*/
    
    		//string id = pdevclass->clientHdl_map[hdl] ;
    		map<string, DH_DEVICE_INFO *>::iterator iter;
    		iter = pdevclass->mymap.begin();
    		for (; iter != pdevclass->mymap.end(); iter++) {
    			DH_DEVICE_INFO * pinfo = iter->second;
    			string id = iter->first;
    			if (pinfo !=NULL)
    			{
    				con_list &set = pinfo->connections;
    				if (set.find(hdl) != set.end()) {
    					OUTINFO_1_PARAM("this disconnect  id = %s \n",id.c_str());
    					pdevclass->removehd(id, hdl);
    				
    				}
    			}
    		}
    		//m_actions.push(action(UNSUBSCRIBE, hdl));
    		//m_action_cond.notify_one();
    }
    //通过该方法从web端获得摄像头的配置信息(链接句柄,配置信息)
    void broadcast_server::on_message(connection_hdl hdl, server::message_ptr msg) {
    
    	devClass * pdevclass = devClass::GetInstance();
    	
    	OUTINFO_0_PARAM("BEGIN WS server on_message resove \n");
    	
    	string  tempstring = msg->get_payload();
    
    	//安全判断
    	if (tempstring == "undifined" || tempstring == "null"  || tempstring == "[object Object]") {
    		OUTINFO_0_PARAM("WS server  recieve error = undifined OR null  \n");
    		std::string msg_str = "{\"type\":\"999\",\"info\":\"Bad Request,parameter error;\",\"code\":\"0\"}";
    		sendText(hdl, msg_str);
    		return;
    	}
       string type = m_type_number(tempstring);
       if (type == "0") {
    	   OUTINFO_1_PARAM("recieve node msg : %s \n", tempstring.c_str());
    	   pdevclass->addNodeSessionHeartTIme("node", hdl, getMilliTime());
    	   //给当前变量全局 ms 数进行赋值
    	   std::string msg_str = "{\"type\":\"0\",\"info\":\"u are node_client\"}";
    	   sendText(hdl, msg_str);
       }
       else if (type == "1"  || type == "2") //添加设备信息
       {
    	   device one_device = m_init_device_list(tempstring);
    	   list<device_init_add>::iterator it;
    	   list<device_init_add>  list = one_device.dev_list;
    	   it = list.begin();
    	   while (it != list.end())
    	   {
    	   pdevclass->addDevSession(it->dev_serial, it->user_name, it->passwd);
    	   it++;
    	   }
       }
    //++++++++++++++++++++直播代码段++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       else if(type == "4")  
       {
    	   OUTINFO_1_PARAM("recieve node msg : %s \n", tempstring.c_str());
    	   //printf("recieve node msg : %s \n", tempstring.c_str());
    	   string dev_serial = m_live_broadcast(tempstring);//浏览器将想要获得的摄像头的唯一序列号通过websocketpp(js_sion)传给服务器
    														//类似于申请获取那个摄像头的流
    	   string type = m_video_type(tempstring);//要获取的视频流类型
    	   if (dev_serial.empty())//没有连接到摄像头
    	   {
    		   OUTINFO_0_PARAM(" dev_serial = nullstr  \n");
    		   printf("dev_serial=nullstr");
    		   std::string msg_str = "{\"type\":\"4\",\"info\":\"Bad Request,parameter error; \",\"code\":\"0\"}";
    		   sendText(hdl, msg_str);
    		   return;
    	   }
    	   //将当前请求直播的 hd ———— id 存入到map 中
    	   //将当前请求直播的连接保存到connections属性中
           int ret = pdevclass->addDevSession(dev_serial,hdl);
    
    	   if (ret == -1) {//返回-1说明连接没有成功,没有找到设备
    		   std::string msg_str = "{\"type\":\"4\",\"info\":\"Not Found This Dev;\",\"code\":\"1\"}";
    		   sendText(hdl, msg_str);
    	   }
    	   else
    	   {
    		   //获得摄像头的状态
    		   // 设备状态,0:离线 1:排队登录 2:在线 3:停止预览  4 :当前设备正在播放中 5:注册失败 等待下次注册
    		   int loginStatus = pdevclass->getLoginStatus(dev_serial);
    		   if(loginStatus == -1){
    				std::string msg_str = "{\"type\":\"4\",\"info\":\"This Dev Offline\",\"code\":\"2\"}";
    				sendText(hdl,msg_str);
    
    		   }
    		   else
    		   {
    			   //开启获取设备的线程
    			   std::string msg_str = "{\"type\":\"4\",\"info\":\"Play It Right Now\",\"code\":\"3\"}";
    			   sendText(hdl, msg_str);
    			   dhServer dhserver;
    			   dhserver.thread_getH264ById(dev_serial,type);
    		   }
    	   }
       }
       else if (type == "8")  //截图
       { 
    	   OUTINFO_1_PARAM("recieve node msg : %s \n", tempstring.c_str());
    	   device_take_pic  pics = m_device_take_pic(tempstring);
    	   string dev_serial = pics.dev_serial;
    	   string pic_name = pics.pic_name;
    	   dhServer dhserver;
    	   dhserver.thread_getpicture(dev_serial, pic_name);
    	  
       }
       else if (type == "10")  //get cam isonline 
       {
    	   OUTINFO_1_PARAM("recieve node msg : %s \n", tempstring.c_str());
    	   char body [128] = "";
    	   std::string head = "{\"type\":\"10\",\"info\":{";
    	   device one_device = m_init_device_list(tempstring);
    	   list<device_init_add>::iterator it;
    	   list<device_init_add>  list = one_device.dev_list;
    	   it = list.begin();
    	   while (it != list.end())
    	   {
    		  int status =  pdevclass->getLoginStatus(it->dev_serial);
    		  _snprintf(body, sizeof(body) - 1, " \"%s\":{\"deviceid\":\"%s\" ,\"status\":\"%d\"} ,", it->dev_serial.c_str(), it->dev_serial.c_str(), status);
    		  string body1 = body;
    		  head +=  body1;
    		  *it++;
    	   }
    	   head.pop_back();
    	   head = head + "}}";
    	   sendText(hdl, head);
       }
       else if (type == "11")  //接受node 心跳
       {
    	   OUTINFO_1_PARAM("recieve node msg : %s \n", tempstring.c_str());
    	   //给当前变量全局 ms 数进行赋值
    	   std::string msg_str = "{\"type\":\"11\",\"info\":\"heart beatting\"}";
    	   sendText(hdl, msg_str);
    	   //设置当前连接的心跳
    	   pdevclass->setheartTime(hdl, getMilliTime());
    	 
    	 /*function sfunc = std::bind(&broadcast_server::timer_callback, this, std::placeholders::_1);
    	   m_server.set_timer(time, sfunc);*/
       }
      OUTINFO_0_PARAM("END WS server on_message resove\n");
    }
    
    void broadcast_server::timer_callback(error_code const &error) {
    	// printf("this is a test\n\n");
    }
    
    
    
    
    
    string broadcast_server::m_type_number(string json_string) {
    
    	std::stringstream str_stream(json_string);
    	boost::property_tree::ptree root;
    	boost::property_tree::read_json(str_stream, root);
    	//boost::property_tree::ptree::iterator root_it = root.BEGIN();
    	string type = root.get<string>("type");
    	return type;
    
    }
    
    
    device broadcast_server::m_init_device_list(string json_string) {
    	device one_device;
    	try{
    
    		std::stringstream str_stream(json_string);
    		boost::property_tree::ptree root;
    		boost::property_tree::read_json(str_stream, root);
    		boost::property_tree::ptree::iterator root_it = root.begin();
    		for (; root_it != root.end(); ++root_it)
    		{
    			string key = root_it->first;
    			if ("type" == key)
    			{
    				one_device.type = root.get<string>(key);
    
    			}
    			if ("info" == key)
    			{
    
    				boost::property_tree::ptree info_node = root.get_child(key);
    				boost::property_tree::ptree list_node = info_node.get_child("list");
    				boost::property_tree::ptree::iterator list_node_it = list_node.begin();
    				for (; list_node_it != list_node.end(); ++list_node_it)
    				{
    					device_init_add one_init_add;
    					boost::property_tree::ptree tkt = list_node_it->second;
    					boost::property_tree::ptree::iterator tkt_it = tkt.begin();
    					for (; tkt_it != tkt.end(); ++tkt_it)
    					{
    						string tkt_key = tkt_it->first;
    
    						string tkt_val = tkt.get<string>(tkt_key);
    						if (tkt_key == "deviceid")
    							one_init_add.dev_serial = tkt_val;
    						else if (tkt_key == "username")
    							one_init_add.user_name = tkt_val;
    						else if (tkt_key == "password")
    							one_init_add.passwd = tkt_val;
    
    						//	cout << tkt_key << ":" << tkt_val << endl;
    
    					}
    					/*struct device
    					{
    						string type;
    						std::list dev_list;
    					};*/
    					one_device.dev_list.push_back(one_init_add);//push设备的deviceid、usename、password 到list中
    				}
    
    			}
    
    			else
    			{
    				/*string val = root.get(key);
    				cout << key << ":" << val << endl;
    				*/
    			}
    
    		}
    	}
    	catch (const std::exception& e)
    	{
    		OUTINFO_1_PARAM("m_init_device_list   error = %s  \n", e.what());
    	}
    	return one_device;
    
    }
    
    //获取操作的deviceid
    string  broadcast_server::m_live_broadcast(string json_string )
     {
    	string  device_s;
    	try
    	{
    		std::stringstream str_stream(json_string);
    		boost::property_tree::ptree root;
    		boost::property_tree::read_json(str_stream, root);
    		boost::property_tree::ptree info_node = root.get_child("info");
    		device_s = info_node.get<string>("deviceid");
    	}
    	catch (const std::exception& e)
    	{
    		OUTINFO_1_PARAM("m_live_broadcast   error = %s  \n", e.what());
    	}
    	return device_s;
     }
    
    //获取device传输码流的类型
    string  broadcast_server::m_video_type(string json_string)
    {
    	string  type;
    	try
    	{
    		std::stringstream str_stream(json_string);
    		boost::property_tree::ptree root;
    		boost::property_tree::read_json(str_stream, root);
    		boost::property_tree::ptree info_node = root.get_child("info");
    		type = info_node.get<string>("video_type");
    		//printf(">>>>>video_type:%s<<<<<",type.c_str());
    	}
    	catch (const std::exception& e)
    	{
    		OUTINFO_1_PARAM("m_video_type   error = %s  \n", e.what());
    	}
    	return type;
    }
    
    
    //获取截图的 摄像头 序列号 和 截取图片的name
    device_take_pic  broadcast_server::m_device_take_pic(string json_string)
    {
    	device_take_pic  takes;
    	try
    	{
    		std::stringstream str_stream(json_string);
    		boost::property_tree::ptree root;
    		boost::property_tree::read_json(str_stream, root);
    		boost::property_tree::ptree info_node = root.get_child("info");
    		takes.dev_serial = info_node.get<string>("deviceid");
    		takes.pic_name = info_node.get<string>("time");
    	}
    	catch (const std::exception& e)
    	{
    
    		OUTINFO_1_PARAM("m_device_take_pic   error = %s  \n", e.what());
    	}
    	return takes;
    }
    //{"type":8, "info" : {"bim_id":"123456", "deviceid" : "3CEF8CFC7990", "time" : ""}}
    //{"type":4, "info" : {"bim_id":"123456", "deviceid": "3CEF8CFC7990"}}
    //void  broadcast_server::process_messages() {
    //
    //	while (1) {
    //
    //
    //		unique_lock lock(m_action_lock);
    //
    //
    //		while (m_actions.empty()) {
    //			m_action_cond.wait(lock);
    //		}
    //
    //
    //		action a = m_actions.front();
    //
    //
    //		m_actions.pop();
    //
    //		lock.unlock();
    //
    //
    //
    //
    //			if (a.type == SUBSCRIBE) {
    //				lock_guard guard(m_connection_lock);
    //				m_connections.insert(a.hdl);
    //				devClass * pdevClass = devClass::GetInstance();
    //				string key = "3CEF8CFC7990";
    //				string username = "admin";
    //				string pass = "ma11111111";
    //				pdevClass->addDevSession(key, username, pass);
    //				
    //			}
    //			else if (a.type == UNSUBSCRIBE) {
    //				lock_guard guard(m_connection_lock);
    //				printf("当前设备断开连接。。。。。。。。。。。。。。。。。。。。。。。。。");
    //				m_connections.erase(a.hdl);
    //			}
    //			else if (a.type == MESSAGE) {
    //				lock_guard guard(m_connection_lock);
    //				
    //				devClass * pdevClass = devClass::GetInstance();
    //				pdevClass->addDevSession("3CEF8CFC7990", a.hdl);
    //				dhServer dhserver;
    //				dhserver.thread_getH264ById("3CEF8CFC7990");
    //				//摄像头的信息在a.msg里面,组建结构,写到map里面去
    //				/*string payload = a.msg->get_payload();
    //				string DevSerial = analysePayload(payload);*/
    //				
    //
    //				//con_list::iterator it;
    //				/*for (it = m_connections.begin(); it != m_connections.end(); ++it) {
    //					m_server.send(*it, a.msg);
    //				}*/
    //			}
    //		}
    //		else {
    //			// undefined.
    //		}
    //
    //	}
    //}
    
    
    
    void broadcast_server::SendFrame(connection_hdl hd, char * p, int len)
    {
    
    
    	try {//将数据以二进制的形式发出去
    		m_server.send(hd, p, len, websocketpp::frame::opcode::binary);
    	}
    	catch (websocketpp::exception const & e) {
    
    		OUTINFO_1_PARAM("SendFrame_video   error = %s  \n", e.what());
    
    	}
    }
    
    void broadcast_server::SendFrame(connection_hdl hd, void * devSerial, int status)
    {
    	try {
    		string strSerial = (char*)devSerial;
    		char body[128]  = "";
    		_snprintf(body, sizeof(body) - 1, "{ \"type\":\"0\",\"info\":{ \"deviceid\":\"%s\" ,\"status\":\"%d\"}}", strSerial.c_str(), status);
    		sendText(hd, (string)body);
    	}
    	catch (websocketpp::exception const & e) {
    		OUTINFO_1_PARAM("SendFrame_sendText   error = %s  \n", e.what());
    	}
    }
    
    void broadcast_server::SendFrame(connection_hdl hd,string devSerial,string pic_name)
    {
    
    
    	try {
    
    	/*	string id_name = (char*)devSerial;
    		int flag = id_name.find("#");
    		string id = id_name.substr(0, flag);
    		string pic_name = id_name.substr(++flag, -1);*/
    		char body[128] = "";
    		_snprintf(body, sizeof(body) - 1, "{ \"type\":\"8\",\"info\":{ \"deviceid\":\"%s\",\"pic_name\":\"%s\"}}", devSerial.c_str(), pic_name.c_str());
    		sendText(hd, (string)body);
    	   /* char * p = (char *)devSerial;
    		delete[]p;*/
    	}
    	catch (websocketpp::exception const & e) {
    		OUTINFO_1_PARAM("SendFrame_pic   error = %s  \n", e.what());
    	}
    }
    
    void broadcast_server::CloseConnect(connection_hdl hd)
    {
    	try {
    		m_server.close(hd,0,"heartbeat close");
    		OUTINFO_0_PARAM("close connect ,becauser no recieve data...\n");
    	}
    	catch (websocketpp::exception const & e) {
    		OUTINFO_1_PARAM("CloseConnect   error = %s  \n", e.what());
    	}
    
    }
    
    int broadcast_server::GetUserNumberByDevName(const char * devname)
    {
    	return 0;
    }
    
    long long broadcast_server::getMilliTime()
    { 
    	struct timeb t1;
    	ftime(&t1);
    	return t1.time * 1000 + t1.millitm;
    }
    
    void broadcast_server::sendText(connection_hdl hdl,string & msg) {
    	OUTINFO_1_PARAM(" BEGIN sendText  msg = %s\n" , msg.c_str());
    	try {
    		int len = msg.size();
    		server::message_ptr m;
    		char *p = (char *)msg.c_str();
    		m_server.send(hdl, p, len, websocketpp::frame::opcode::text);
    		}
    	catch (websocketpp::exception const & e)
    		{
    		OUTINFO_1_PARAM(" sendText   error = %s  \n", e.what());
    		}
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402
    • 403
    • 404
    • 405
    • 406
    • 407
    • 408
    • 409
    • 410
    • 411
    • 412
    • 413
    • 414
    • 415
    • 416
    • 417
    • 418
    • 419
    • 420
    • 421
    • 422
    • 423
    • 424
    • 425
    • 426
    • 427
    • 428
    • 429
    • 430
    • 431
    • 432
    • 433
    • 434
    • 435
    • 436
    • 437
    • 438
    • 439
    • 440
    • 441
    • 442
    • 443
    • 444
    • 445
    • 446
    • 447
    • 448
    • 449
    • 450
    • 451
    • 452
    • 453
    • 454
    • 455
    • 456
    • 457
    • 458
    • 459
    • 460
    • 461
    • 462
    • 463
    • 464
    • 465
    • 466
    • 467
    • 468
    • 469
    • 470
    • 471
    • 472
    • 473
    • 474
    • 475
    • 476
    • 477
    • 478
    • 479
    • 480
    • 481
    • 482
    • 483
    • 484
    • 485
    • 486
    • 487

    接收程序

    html端使用h264 js解码,直接播放,这样的好处是可以让手机端使用html5也直接播放,当然,可以使用原生的程序直接播放,就可以避免一些限制。下面使用html5 解码,使用的decoder.js 等为开源程序,缺陷,只能解码baseline 的h264,各位要解码h264 和h265 请使用wasm的程序,网上有很多。

    DOCTYPE html>
    <html>
    <head>
        <meta name="viewport" content="width=320, initial-scale=1" />
        <title>h264 streamingtitle>
        <style type="text/css">
            body {
                background: #333;
                text-align: center;
                margin-top: 10%;
            }
    
            #videoCanvas {
                /* Always stretch the canvas to 640x480, regardless of its
                internal size. */
                width: 640px;
                height: 480px;
            }
        style>
    head>
    <body>
        
        
        <script type="text/javascript" src="Decoder.js">script>
        <script type="text/javascript" src="YUVCanvas.js">script>
        <script type="text/javascript" src="Player.js">script>
    
        <script type="text/javascript">
    
    		var player = new Player({size: {
            width: 640,
            height: 320
             }});
    
    		document.body.appendChild(player.canvas);
    
    		//var strhost = "ws://" + window.location.host ;
    		var strhost = "ws://192.168.3.245:9002" ;
    		// Setup the WebSocket connection and start the player
    		var client = new WebSocket( strhost );
    
    
       	client.binaryType = 'arraybuffer';
    
            client.onopen = function(evt) {
                onOpen(evt)
            };
            client.onclose = function(evt) {
                onClose(evt)
            };
            client.onmessage = function(evt) {
                onMessage(evt)
            };
            client.onerror = function(evt) {
                onError(evt)
            };
    
        function onOpen(evt) {
            //  document.getElementById('messages').innerHTML = 'Connection established';
            console.log("connection ");
          //  alert("open");
        }
    
        function onClose(evt) {
            alert("close");
        }
    
        function onMessage(evt) {
            //console.log(evt.data);
            //return;
            var messageData = new Uint8Array(evt.data);
            player.decode(messageData);
        }
    
        function onError(evt) {
            alert("error");
        }
    
        script>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
  • 相关阅读:
    java毕业设计房产交易系统Mybatis+系统+数据库+调试部署
    Qt 程序打包发布-windeployqt工具
    java计算机毕业设计科院垃圾分类系统源码+数据库+系统+lw文档+mybatis+运行部署
    堆叠、集群技术
    不学51直接学stm32可以吗?学stm32需要哪些基础?
    恒合仓库 - 用户管理、用户列表、为用户分配角色
    网络层学习常见问题及答案整理
    java排班算法-几班几倒
    使用并查集处理树的路径
    基于SSH的客户关系管理系统的设计与实现(JavaWeb开发的CRM管理系统)
  • 原文地址:https://blog.csdn.net/qianbo042311/article/details/127719320