天天看點

基于EasyDarwin開源流媒體伺服器架構實作EasyNVR H5無插件直播流媒體伺服器方案關于EasyNVR

背景分析

在之前的一篇部落格《web無插件播放RTSP錄影機方案,拒絕插件,擁抱H5!》中,描述了實作一套H5無插件直播方案的各個元件的參考建議,又在部落格《EasyNVR H5流媒體伺服器方案架構設計之視訊能力平台》中對整體的架構設計思路做了總結,做高内聚、低耦合的視訊能力平台,不涉足業務部分!那麼今天,我們來公開一下EasyNVR到底是如何實作這些功能的;

一、程式架構

熟悉EasyDarwin的同學都知道,EasyDarwin作為老牌的流媒體功能架構,在很多領域是完全能夠滿足開發者需求的,尤其是在安防領域,綜合其架構和性能,成本效益極高,尤其是在網絡、多線程線程池、子產品化設計等方面,熟悉之後,可以衍生出很多功能類型的服務,這裡将要描述的EasyNVR就是其架構産物之一:EasyNVR based on EasyDarwin,底層網絡事件模型完全沿用EasyDarwin,隻對其HTTPSession、Module部分做二次開發,包括HTTP協定、Json的協定棧都完全複用EasyDarwin的HTTPProtocol類和EasyProtocol架構,非常友善;

基于EasyDarwin開源流媒體伺服器架構實作EasyNVR H5無插件直播流媒體伺服器方案關于EasyNVR

二、子產品設計

EasyNVR一共設計了兩個Module:EasyNVRModule和EasyCMSModule:

  • EasyNVRModule的主要工作就是做EasyNVR通道管理的功能,進行錄影機源與推流的銜接,EasyNVRModule總管理多個EasyNVRChannel,一路EasyNVRChannel就是一個裝置源,EasyNVRChannel繼承自Darwin架構的Task類,這樣每一個EasyNVRChannel就可以獨立進行Task、Timeout、Event等多種功能了,這樣就能非常友善地實作:裝置線上監測、裝置定時快照、裝置直播流擷取等多種功能,每一個EasyNVRChannel的所有輸出都共享一個RTSPSource源,這樣就能保證一路流媒體資料輸入,多種協定(JPEG、RTMP、HLS)輸出了!
  • EasyCMSModule是EasyNVR為了擴充雲平台對接功能擴充的,與具體平台進行協定互動用到的,這個部分可以完全參考EasyDarwin的EasyCMSModule:https://github.com/EasyDarwin/EasyDarwin/tree/master/EasyDarwin/APIModules,對外的對接方法根據協定而定,這裡就不多描述了;
基于EasyDarwin開源流媒體伺服器架構實作EasyNVR H5無插件直播流媒體伺服器方案關于EasyNVR

三、接口調用

在部落格《基于EasyNVR二次開發實作自己的錄影機IPC/NVR無插件化直播解決方案》中,我們大概描述了EasyNVR是如何進行接口設計的,在代碼實作上,我們直接複用了EasyDarwin的HTTPSession功能,實作基于http+json的接口協定,例如擷取廣場視訊清單部分,我們在讀取到請求後,直接從EasyNVRModule擷取清單清單,回報給用戶端:

QTSS_Error HTTPSession::execNetMsgCSGetChannelsRESTful(const char* queryString)
{
if(QTSServerInterface::GetServer()->GetPrefs()->liveStreamingAuth())
{
	if (!isAuthenticate()) 
		return EASY_ERROR_CLIENT_UNAUTHORIZED;
}

QTSS_Error theErr;

QTSS_RoleParams params;
params.easyNVRChannelsParams.inChannels = NULL;

theErr = EasyNVRUtil::CallDispatch(Easy_NVRGetChannels_Role, QTSSModule::kGetChannelsRole, params);

EasyProtocolACK rsp(MSG_SC_SERVER_GET_CHANNELS_ACK);
EasyJsonValue header, body;

header[EASY_TAG_VERSION] = EASY_PROTOCOL_VERSION;
header[EASY_TAG_CSEQ] = 1;
header[EASY_TAG_ERROR_NUM] = EASY_ERROR_SUCCESS_OK;
header[EASY_TAG_ERROR_STRING] = EasyProtocol::GetErrorString(EASY_ERROR_SUCCESS_OK);

if (theErr == QTSS_NoErr)
{
	std::map<int, EasyNVRChannel*>* pChannels = static_cast<std::map<int, EasyNVRChannel*>*>(params.easyNVRChannelsParams.inChannels);
	if (!pChannels)		return QTSS_BadArgument;

	Json::Value* proot = rsp.GetRoot();
	int i = 0;
	std::map<int, EasyNVRChannel*>::iterator it = (*pChannels).begin();
	while (it != (*pChannels).end())
	{
		CameraInfo* item = it->second->GetChannelInfo();
		if (item->enable != 0)
		{
			Json::Value value;
			value[EASY_TAG_CHANNEL] = item->id;
			//value[EASY_TAG_ENABLE] = item->enable;
			value[EASY_TAG_ONLINE] = item->online;
			value[EASY_TAG_NAME] = item->name;
			value[EASY_TAG_SNAP_URL] = item->snap.empty() ? "" : item->snap;
			value[EASY_TAG_ERROR_STRING] = item->lasterror.empty() ? "" : item->lasterror;

			(*proot)[EASY_TAG_ROOT][EASY_TAG_BODY][EASY_TAG_CHANNELS].append(value);
			++i;
		}
		++it;
	}

	body[EASY_TAG_CHANNEL_COUNT] = EasyUtil::Int2String(i);
}

rsp.SetHead(header);
rsp.SetBody(body);

string msg = rsp.GetMsg();
this->SendHTTPPacket(msg, false, false);

return QTSS_NoErr;
 }
           

諸如此類,按照這種方式實作每一個http接口功能即可實作完整一套的http接口功能,對外進行能力輸出!

四、配套元件

在《web無插件播放RTSP錄影機方案,拒絕插件,擁抱H5!》中描述了很多元件:live555、ffmpeg、librtmp、faac等等,基于這些元件可以非常好地幫助您實作這些功能,但是這些元件都會存在不成熟或者不易使用的問題,EasyDarwin社群的開發者也實作了一系列此類功能的功能元件,例如:

  • EasyRTSPClient:類似于live555的RTSPClient功能元件,進行RTSP拉流;
  • EasyAACEncoder:AAC轉碼,将各種類型的安防音頻格式轉碼成标準H5需要的AAC格式,開源項目位址:https://github.com/EasyDarwin/EasyAACEncoder
  • EasyRTMP:RTMP推流工具,能非常好地實作推流,重連,資料緩沖,過濾等等功能;

五、細節亮點

- 按需直播

EasyNVR獨特設計了一套按需直播的方案,也就是可以配置EasyNVR的通道隻有在有人看的時候,才會從錄影機裝置源取流到EasyNVR流媒體伺服器進行直播,當沒有用戶端觀看的時候,直接切斷與源的連接配接,隻做常态的裝置狀态監測和快照功能,降低帶寬和伺服器的壓力;

具體實作:用戶端頁面需要不斷向EasyNVR發送心跳包,保持具體某一個通道的流狀态,當逾時時間内某通道沒有獲得心跳包,那麼就認為該通道無人觀看,即停止從裝置拉流!

- token認證

EasyNVR實作了一套authToken驗證機制,用戶端調用登陸接口後,用戶端會擷取到一個token,在本次操作的過程中,隻要在http cookies中攜帶token,即可操作EasyNVR其餘接口,如果不攜帶token或者攜帶的token已經過期,EasyNVR會傳回401,這樣用戶端需要重新調用EasyNVR登陸接口擷取新的token!

- 占位設計

我們經常在做伺服器時會遇到内外網映射的問題,當外網用戶端請求一個通過端口映射出來的内網伺服器時,内網伺服器往往不知道其所在的公網的IP位址,如果每次都是通過配置IP的方式,一方面是很麻煩,另一方面,很多網絡路由規則會限制内網的用戶端不能請求該内網所在的公網的IP,也就是内網的用戶端不能請求自己的公網IP的對外服務,内網的隻能通過内網路由,而且内網請求内網IP就擷取到的是内網的直播流位址也是很合理的需求,于是,我們設計了一套占位方案,比如用戶端請求一個RTMP的直播位址,我們傳回給用戶端的位址是:rtmp://{host}:10935/hls/channel_1,那麼用戶端再根據自己請求到EasyNVR的host IP,替換{host}占位符,就實作了,内網用内網的IP,公網用公網的IP了!

EasyNVR應用場景

  • 把傳統分散的校園監控彙總到EasyNVR系統,實作把傳統的本地監控提升到随時随地的遠端監控,把傳統的純粹的監控上升到管理,使視訊監控成為學校教學管理的有力工具。更重要的是讓家長一起參與,提升教學的主動性,提升學校聲譽和學校品牌。
    基于EasyDarwin開源流媒體伺服器架構實作EasyNVR H5無插件直播流媒體伺服器方案關于EasyNVR

平安校園

  • 将工地的攝像頭通過平台對施工方、監理方和監管部門開放,友善實時了解工程進度,工地人員安全以及财産情況,自成力能平台,專為工地建構的視訊監控平台。
    基于EasyDarwin開源流媒體伺服器架構實作EasyNVR H5無插件直播流媒體伺服器方案關于EasyNVR

平安工地

  • 随着網際網路和移動網際網路被廣大消費者接受,“社會共治”将是是明廚亮竈目前的核心理念。采用社會共治方式,将各餐飲企業的後廚視訊通過EasyNVR系統讓老百姓通過手機可實時看到後廚的情況,既起到全社會監督的效果也是對餐飲企業的宣傳。
    基于EasyDarwin開源流媒體伺服器架構實作EasyNVR H5無插件直播流媒體伺服器方案關于EasyNVR

明廚亮竈

  • 企業直播是以将企業内的環境、産品制作流程和産品等以直播的方式呈現出來,讓客戶看到企業的環境和透明化的生産,通過直播可以清清楚楚地看到所購買的産品生産過程。
    基于EasyDarwin開源流媒體伺服器架構實作EasyNVR H5無插件直播流媒體伺服器方案關于EasyNVR

企業直播

關于EasyNVR

EasyNVR是一款擁有完整、自主、可控知識産權,同時又能夠具備軟硬一體功能的安防網際網路化流媒體伺服器,能夠通過簡單的網絡錄影機通道配置,将傳統監控行業裡面的高清網絡錄影機IP Camera、NVR等具有RTSP、Onvif協定輸出的裝置接入到EasyNVR,EasyNVR能夠将這些視訊源的音視訊資料進行拉取,轉換為RTMP/HLS,進行全平台終端H5直播(Web、Android、iOS),并且EasyNVR能夠将視訊源的直播資料對接到第三方CDN網絡,實作網際網路級别的直播分發。詳情可通路EasyNVR官網:http://www.easynvr.com

基于EasyDarwin開源流媒體伺服器架構實作EasyNVR H5無插件直播流媒體伺服器方案關于EasyNVR

繼續閱讀