1. 程式人生 > >使用配置檔案打造可配置的視訊伺服器轉發平臺

使用配置檔案打造可配置的視訊伺服器轉發平臺

Car-eye 開源團隊在做JT/T視訊轉發平臺的時候需要配置視訊伺服器的引數。用到TinyXML2,感覺非常好用,能快速完成自己的配置專案。

主要功能:實現對伺服器的IP,埠,音視訊引數的配置。可以採用一層節點完成設計。配置完成後達到如下效果:

  <?xml version="1.0" encoding="UTF-8" standalone="no" ?>

- <configures>

  <Server_ip>XXX.XXX.XXX.XXX</Server_ip>

  <Server_Port>10085</Server_Port>

  <Linsten_Port>9100</Linsten_Port>

  <Http_Port>8090</Http_Port>

  <Send_Port>1008</Send_Port>

  <Protocol>rtmp</Protocol>

  <Application>live</Application>

  <Audio_channel>1</Audio_channel>

  <Audio_SampleRate>8000</Audio_SampleRate>

  </configures>

實現程式碼如下:

#ifndef __CONFIGURE_H__
#define __CONFIGURE_H__
 
 
 
#include <string.h>
#include<iostream>
#include"XML\tinyxml2.h"  
using namespace std;
 
using namespace tinyxml2;
class Configure
{
public:
	Configure();
	virtual ~Configure();
	string	m_Server_IP;
	int		m_Server_Port;
	int		m_Listen_Port;
	int		m_Http_port;
	int		m_SendPort;
	string  m_protocol;
	string  m_app;
	int		m_audio_channels;
	int		m_audio_Rate;
private:
	int insertXMLNode(const char* xmlPath, const char* node, const char* value);
	int Configure::createXML(const char* xmlPath);
	XMLElement* queryUserNodeByName(XMLElement* root, const string& userName);
public:
	unsigned char queryConfigureByName(const char* xmlPath, const string& userName, char* result);
	unsigned char deleteUserByName(const char* xmlPath, const string& userName);
	void WriteDefConfig(const char* xmlPath);
	void LoadConfig(const char* xmlPath);
};
 
 
#endif
 
#include "Configure.h"
 
/*
* Car eye 車輛管理平臺: www.car-eye.cn
* Car eye 開源網址: https://github.com/Car-eye-team
*
* Copyright (c) 2018  All rights reserved.
*
*/
 
 
//function:create a xml file
//param:xmlPath:xml檔案路徑
//return:0,成功,非0,失敗
int Configure::createXML(const char* xmlPath)
{
	const char* declaration = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>";
	XMLDocument doc;
	doc.Parse(declaration);//會覆蓋xml所有內容
 
						   //新增申明可以使用如下兩行
						   //XMLDeclaration* declaration=doc.NewDeclaration();
						   //doc.InsertFirstChild(declaration);
 
	XMLElement* root = doc.NewElement("configures");
	doc.InsertEndChild(root);
 
	return doc.SaveFile(xmlPath);
}
 
int Configure:: insertXMLNode(const char* xmlPath, const char* node, const char* value)
{
	XMLDocument doc;
	int res = doc.LoadFile(xmlPath);
	if (res != 0)
	{
		printf("File is not existed");
		return res;
	}
	XMLElement* root = doc.RootElement();
 
	XMLElement* userNode = doc.NewElement(node);
	userNode->SetText(value);
	root->InsertEndChild(userNode);
	return doc.SaveFile(xmlPath);
}
 
XMLElement* Configure::queryUserNodeByName(XMLElement* root, const string& userName)
{
	XMLElement* userNode = root->FirstChildElement();
	while (userNode != NULL)
	{
		if (userNode->Name() == userName)
			break;
		userNode = userNode->NextSiblingElement();//下一個兄弟節點
	}
	return userNode;
}
 
unsigned char Configure::queryConfigureByName(const char* xmlPath, const string& userName, char* result)
{
	XMLDocument doc;
	if (doc.LoadFile(xmlPath) != 0)
	{
		cout << "load xml file failed" << endl;
		return NULL;
	}
	XMLElement* root = doc.RootElement();
	XMLElement* userNode = 	queryUserNodeByName(root, userName);
	if (userNode != NULL)  //searched successfully
	{
		strcpy(result, userNode->GetText());		
		return 1;
	}
	return 0;
}
 
//function:刪除指定節點內容
//param:xmlPath:xml檔案路徑;userName:使用者名稱稱
//return:bool
unsigned char Configure::deleteUserByName(const char* xmlPath, const string& userName)
{
	XMLDocument doc;
	if (doc.LoadFile(xmlPath) != 0)
	{
		cout << "load xml file failed" << endl;
		return false;
	}
	XMLElement* root = doc.RootElement();
	//doc.DeleteNode(root);//刪除xml所有節點
	
	XMLElement* userNode1 = root->FirstChildElement("configures");
	XMLElement* userNode = queryUserNodeByName(root, userName);
	if (userNode != NULL)
	{
		userNode1->DeleteChild(userNode);
		if (doc.SaveFile(xmlPath) == 0)
			return 1;
	}
	return 0;
}
Configure::Configure()
{
 
}
Configure::~Configure()
{
 
}
 
string& trim(string &s)
{
	if (s.empty())
	{
		return s;
	}
	s.erase(0, s.find_first_not_of(" "));
	s.erase(s.find_last_not_of(" ") + 1);	
	return s;
}
void Configure::LoadConfig(const char* xmlPath)
{
	XMLDocument doc;
	char value[100];
	if (doc.LoadFile(xmlPath) != 0)
	{
		createXML(xmlPath);
		WriteDefConfig(xmlPath);
	}
	if (queryConfigureByName(xmlPath, "Server_ip", value))
	{
		m_Server_IP = value;
		m_Server_IP = trim(m_Server_IP);
	}
	else
	{
		m_Server_IP = "www.car-eye.cn";
	}
	if (queryConfigureByName(xmlPath, "Server_Port", value))
	{
		m_Server_Port = atoi(value);		
	}
	else
	{
		m_Server_Port = 10085;
	}
	if (queryConfigureByName(xmlPath, "Linsten_Port", value))
	{
		m_Listen_Port = atoi(value);
	}
	else
	{
		m_Listen_Port = 9100;
	}
	if (queryConfigureByName(xmlPath, "Http_Port", value))
	{
		m_Http_port = atoi(value);
	}
	else
	{
		m_Http_port = 8090;
	}
	if (queryConfigureByName(xmlPath, "Send_Port", value))
	{
		m_SendPort = atoi(value);
	}
	else
	{
		m_SendPort = 1008;
	}
	if (queryConfigureByName(xmlPath, "Protocol", value))
	{
		m_protocol = value;
		m_protocol = trim(m_protocol);
	}
	else
	{
		m_protocol = "rtmp";
	}
	if (queryConfigureByName(xmlPath, "Application", value))
	{
		m_app = value;
		m_app = trim(m_app);
	}
	else
	{
		m_app = "live";
	}
	if (queryConfigureByName(xmlPath, "Audio_channel", value))
	{
		m_audio_channels = atoi(value);
	}
	else
	{
		m_audio_channels = 1;
	}
	if (queryConfigureByName(xmlPath, "Audio_SampleRate", value))
	{
		m_audio_Rate = atoi(value);
	}
	else
	{
		m_audio_Rate = 8000;
	}	
}
 
void Configure::WriteDefConfig(const char* xmlPath)
{	
	insertXMLNode(xmlPath,"Server_ip","XXX.XXX.XXX.XXX");
	insertXMLNode(xmlPath, "Server_Port", "XXXX");
	insertXMLNode(xmlPath, "Linsten_Port", "9100");
	insertXMLNode(xmlPath, "Http_Port", "8090");
	insertXMLNode(xmlPath, "Send_Port", "1008");
	insertXMLNode(xmlPath, "Protocol", "rtmp");
	insertXMLNode(xmlPath, "Application", "live");
	insertXMLNode(xmlPath, "Audio_channel", "1");
	insertXMLNode(xmlPath, "Audio_SampleRate", "8000");
}
 
 
 
 

car-eye開源官方網址:www.car-eye.cn   

car-eye 流媒體平臺網址:www.liveoss.com