基于EasyDarwin框架实现EasyNVR H5无插件直播流媒体服务器方案

本文主要是介绍基于EasyDarwin框架实现EasyNVR H5无插件直播流媒体服务器方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在之前的一篇博客《web无插件播放RTSP摄像机方案,拒绝插件,拥抱H5!》中,描述了实现一套H5无插件直播方案的各个组件的参考建议,又在博客《EasyNVR H5流媒体服务器方案架构设计之视频能力平台》中对整体的架构设计思路做了总结,做高内聚、低耦合的视频能力平台,不涉足业务部分!那么今天,我们来公开一下EasyNVR到底是如何实现这些功能的;

一、程序框架

熟悉EasyDarwin的同学都知道,EasyDarwin作为老牌的功能框架,在很多领域是非常能够满足开发者需求的,尤其是在安防领域,综合其架构和性能,性价比极高,尤其是在网络、多线程线程池、模块化设计等方面,熟悉之后,可以衍生出很多功能类型的服务,这里将要描述的EasyNVR就是其框架产物之一:EasyNVR based on EasyDarwin,底层网络事件模型完全沿用EasyDarwin,只对其HTTPSession、Module部分做二次开发,包括HTTP协议、Json的协议栈都完全复用EasyDarwin的HTTPProtocol类和EasyProtocol框架,非常方便;

EasyDarwin

二、模块设计

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,对外的对接方法根据协议而定,这里就不多描述了;

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能够通过简单的网络摄像机通道配置,将传统监控行业里面的高清网络摄像机IP Camera、NVR等具有RTSP协议输出的设备接入到EasyNVR,EasyNVR能够将这些视频源的音视频数据进行拉取,转换为RTMP/HLS,进行全平台终端H5直播(Web、Android、iOS),并且EasyNVR能够将视频源的直播数据对接到第三方CDN网络,实现互联网级别的直播分发;

详细说明:http://www.easydarwin.org/easynvr/

获取更多信息

邮件:support@easydarwin.org

WEB:www.EasyDarwin.org

Copyright © EasyDarwin.org 2012-2017

EasyDarwin

转载于:https://www.cnblogs.com/babosa/p/7518017.html

这篇关于基于EasyDarwin框架实现EasyNVR H5无插件直播流媒体服务器方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/722217

相关文章

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

ElasticSearch+Kibana通过Docker部署到Linux服务器中操作方法

《ElasticSearch+Kibana通过Docker部署到Linux服务器中操作方法》本文介绍了Elasticsearch的基本概念,包括文档和字段、索引和映射,还详细描述了如何通过Docker... 目录1、ElasticSearch概念2、ElasticSearch、Kibana和IK分词器部署

部署Vue项目到服务器后404错误的原因及解决方案

《部署Vue项目到服务器后404错误的原因及解决方案》文章介绍了Vue项目部署步骤以及404错误的解决方案,部署步骤包括构建项目、上传文件、配置Web服务器、重启Nginx和访问域名,404错误通常是... 目录一、vue项目部署步骤二、404错误原因及解决方案错误场景原因分析解决方案一、Vue项目部署步骤

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

Linux流媒体服务器部署流程

《Linux流媒体服务器部署流程》文章详细介绍了流媒体服务器的部署步骤,包括更新系统、安装依赖组件、编译安装Nginx和RTMP模块、配置Nginx和FFmpeg,以及测试流媒体服务器的搭建... 目录流媒体服务器部署部署安装1.更新系统2.安装依赖组件3.解压4.编译安装(添加RTMP和openssl模块

如何通过Python实现一个消息队列

《如何通过Python实现一个消息队列》这篇文章主要为大家详细介绍了如何通过Python实现一个简单的消息队列,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录如何通过 python 实现消息队列如何把 http 请求放在队列中执行1. 使用 queue.Queue 和 reque

Python如何实现PDF隐私信息检测

《Python如何实现PDF隐私信息检测》随着越来越多的个人信息以电子形式存储和传输,确保这些信息的安全至关重要,本文将介绍如何使用Python检测PDF文件中的隐私信息,需要的可以参考下... 目录项目背景技术栈代码解析功能说明运行结php果在当今,数据隐私保护变得尤为重要。随着越来越多的个人信息以电子形