高复用率的RTSPClient组件EasyRTSPClient设计流程概述
EasyRTSPClient 设计过程
概述
EasyRTSPClient 基于live555构建而成. 今天讲讲EasyRTSPClient的设计过程
EasyRTSPClient,主要包括以下部分:
1. 创建live555对象, 连接相机和收流
2. 解析收到的视频分辨率
3. 将SDP、音视频流、分辨率及其它相关信息通过回调函数进行回调
4. 回调连接、断线状态
5. 根据参数执行是否重连
创建live555对象,连接相机和收流
网上很多介绍的都是使用testRTSPClient来做客户端, 这个是没有问题的,但有一点需要注意的是demo中的代码,都是阻塞式的,如下:
env->taskScheduler().doEventLoop(&eventLoopWatchVariable);
这样就在主线程中阻塞了, 如果我需要它退出,该怎样实现呢?
有两种方法,目的是相同的,实现方式略有不同罢了:
1. 外部改变eventLoopWatchVariable的值为1
2. 通过BasicTaskScheduler0::doEventLoop(char* watchVariable)的实现可以看出, 这里实际上是进行一个无限循环. 当 watchVariable的值不为0时就退出. 所以我们可以自己创建一个线程,在线程内部实现调用 pTaskScheduler0->SingleStep(0), 即可实现对该线程的自由控制; 相当于1个线程对应1路到摄像机的取流;
解析视频分辨率
解析分辨率主要是sps_pps.h .c实现,是从VLC中提取出来的相关代码, 可正常解析H264,H265的分辨率;
回调SDP, 音视频流,分辨率及其它相关信息
在Live555的continueAfterDESCRIBE的回调函数中, 解析出SDP信息进行回调
void continueAfterDESCRIBE(RTSPClient* rtspClient, int resultCode, char* resultString)
if (NULL != sdpDescription)
{
if (NULL != pClient) pClient->SetSDP(sdpDescription, (int)strlen(sdpDescription));
char *sprop_parameter_sets = strstr(sdpDescription, "sprop-parameter-sets=");
if (NULL != sprop_parameter_sets)
{
AnalysisH264SPSPPS(pClient, sprop_parameter_sets+21);
}
else
{
sprop_parameter_sets = strstr(sdpDescription, "sprop-sps=");
if (NULL != sprop_parameter_sets)
{
AnalysisH265SPSPPS(pClient, sprop_parameter_sets);
}
}
//回调出媒体信息
MediaSubsessionIterator iter(*scs.session);
MediaSubsession* subsession;
while ((subsession = iter.next()) != NULL)
{
if (strcmp(subsession->mediumName(), "video") == 0)
{
if (strcmp(subsession->codecName(), "H264") == 0)
{
mediainfo.videoCodec = VIDEO_CODEC_H264;
}
else if (strcmp(subsession->codecName(), "H265") == 0)
{
mediainfo.videoCodec = VIDEO_CODEC_H265;
}
else if (strcmp(subsession->codecName(), "MP4V-ES") == 0)
{
mediainfo.videoCodec = VIDEO_CODEC_MPEG4;
}
else if (strcmp(subsession->codecName(), "JPEG") == 0)
{
mediainfo.videoCodec = VIDEO_CODEC_MJPEG;
}
mediainfo.videoFps = (float)subsession->videoFPS();
mediainfo.videoWidth = pClient->params.width;
mediainfo.videoHeight = pClient->params.height;
}
if (strcmp(subsession->mediumName(), "audio") == 0)
{
}
}
if (NULL != clientObj && NULL !=clientObj->callback)
{
RTSPClientCallBack pRtspCallback = (RTSPClientCallBack )clientObj->callback;
if (NULL != pRtspCallback)
{
pRtspCallback(clientObj->channelInfo.id, (int *)clientObj->userPtr, MEDIA_TYPE_CODEC_INFO, (char*)&mediainfo, NULL);
}
}
}
回调连接、断线状态
断线状态的检测, 这里使用了一个时间对比的方式. 即用当前时间减去上一次获取到音视频流的时间,如果大于指定时长,则认为断线;
根据参数执行是否重连
检查重连参数,如果需要重连,则销毁当前的所有对象,再创建新的对象, 继续开始新的循环
if (NULL != pClient->rtspClient)
{
Medium::close(pClient->rtspClient);
pClient->rtspClient = NULL;
}
if (NULL != pClient->env)
{
pClient->env->reclaim();
pClient->env = NULL;
}
if (NULL != pClient->scheduler)
{
delete pClient->scheduler;
pClient->scheduler = NULL;
}
if (NULL != pClient->auth)
{
delete pClient->auth;
pClient->auth = NULL;
}
if (NULL == pClient->scheduler) pClient->scheduler = BasicTaskScheduler::createNew();
if (NULL == pClient->scheduler) break;
if (NULL == pClient->env) pClient->env = BasicUsageEnvironment::createNew(*pClient->scheduler);
if (NULL == pClient->env) break;
if (NULL == pClient->rtspClient) pClient->rtspClient = LiveRTSPClient::createNew(*pClient->env, pClient->channelInfo.url, RTSP_CLIENT_VERBOSITY_LEVEL, RTSP_CLIENT_NAME, 0, (void *)pClient);
if (NULL == pClient->rtspClient) break;
今天主要概述了EasyRTSPClient的设计流程, 下一篇将开始着重讲解具体实现细节;
以下是我写的基于live555的两个应用:
关于EasyRTSPClient
EasyRTSPClient是一套非常稳定、易用、支持重连的RTSPClient工具,SDK形式提供,接口调用非常简单,再也不用像调用live555那样处理整个RTSP OPTIONS/DESCRIBE/SETUP/PLAY的复杂流程,担心内存释放的问题了,全平台支持(包括Windows/Linux 32&64,ARM各平台,Android,iOS),支持RTP Over TCP/UDP,支持断线重连,连续维护与迭代超过5年,能够接入市面上99%以上的IPC,调用简单且成熟稳定!
关于EasyIPCamera
EasyIPCamera是一套非常稳定、易用、支持多种平台(包括Windows/Linux 32&64,Android,ARM hisiv100/hisiv200/hisiv400等平台)的RTSP Server组件,适用于IPCamera、内网RTSP服务等小型RTSP流媒体服务器,接口调用非常简单成熟,无需关注RTSPServer中关于客户端监听接入、音视频多路复用、RTSP具体流程、RTP打包与发送等相关问题,支持多种音视频格式,再也不用像调用live555 RTSPServer那样处理整个RTSP OPTIONS/DESCRIBE/SETUP/PLAY/RTP/RTCP的复杂流程和担心内存释放的问题了!
获取更多信息
Copyright © EasyDarwin.org 2012-2017

高复用率的RTSPClient组件EasyRTSPClient设计流程概述的更多相关文章
- 高复用率的RTSPClient组件EasyRTSPClient调用说明
EasyRTSPClient 调用说明 概述 EasyRtspClient是EasyDarwin家族中针对RTSP协议的拉流组件 EasyRtspClient视频支持H264.H265.MJPEG格式 ...
- IC设计流程概述
芯片设计分为前端设计和后端设计,前端设计(也称逻辑设计)和后端设计(也称物理设计)并没有统一严格的界限,涉及到与工艺有关的设计就是后端设计. Front-end design flow 1. 规格制定 ...
- 通用异步 Windows Socket TCP 客户端组件的设计与实现
编写 Windows Socket TCP 客户端其实并不困难,Windows 提供了6种 I/O 通信模型供大家选择.但本座看过很多客户端程序都把 Socket 通信和业务逻辑混在一起,剪不断理还乱 ...
- 基于 IOCP 的通用异步 Windows Socket TCP 高性能服务端组件的设计与实现
设计概述 服务端通信组件的设计是一项非常严谨的工作,其中性能.伸缩性和稳定性是必须考虑的硬性质量指标,若要把组件设计为通用组件提供给多种已知或未知的上层应用使用,则设计的难度更会大大增加,通用性.可用 ...
- 微服务架构案例(05):SpringCloud 基础组件应用设计
本文源码:GitHub·点这里 || GitEE·点这里 更新进度(共6节): 01:项目技术选型简介,架构图解说明 02:业务架构设计,系统分层管理 03:数据库选型,业务数据设计规划 04:中间件 ...
- Steps 组件的设计与实现
NutUI 组件源码揭秘 前言 本文的主题是 Steps 组件的设计与实现.Steps 组件是 Steps 步骤和 Timeline 组件结合的组件,在此之前他们是两个不同的组件,在 NutUI 最近 ...
- ASP.NET通用权限组件思路设计
开篇 做任何系统都离不开和绕不过权限的控制,尤其是B/S系统工作原理的特殊性使得权限控制起来更为繁琐,所以就在想是否可以利用IIS的工作原理,在IIS处理客户端请求的某个入口或出口通过判断URL来达到 ...
- Unity3d&C#分布式游戏服务器ET框架介绍-组件式设计
前几天写了<开源分享 Unity3d客户端与C#分布式服务端游戏框架>,受到很多人关注,QQ群几天就加了80多个人.开源这个框架的主要目的也是分享自己设计ET的一些想法,所以我准备写一系列 ...
- Java高并发 -- J.U.C.组件扩展
Java高并发 -- J.U.C.组件扩展 主要是学习慕课网实战视频<Java并发编程入门与高并发面试>的笔记 FutureTask Future模式,核心思想是异步调用.和同步调用的区别 ...
随机推荐
- android日期时间选择器
android原生的日期时间控件,因为是原生的总有其满足不了我们需求的时候,Android 手机版本那么多,用户弹出来的控件五花八门.因为项目需要,在网上找了一 些demo看了看,感觉有些写的很好,很 ...
- Django ModelChoiceField前台下拉菜单显示object的解决方法
在网上找了好半天都没找到,在model中添加即可,不加的话显示就是object def __str__(self): return self.name
- HDU 1223 还是畅通过程【最小生成树模板】
还是畅通工程 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- path.join 与 path.resolve 的区别
1. 对于以/开始的路径片段,path.join只是简单的将该路径片段进行拼接,而path.resolve将以/开始的路径片段作为根目录,在此之前的路径将会被丢弃,就像是在terminal中使用cd命 ...
- Delphi中@,^,#,$分别表示什么?
@:取址运算符; var int:integer; p:^integer; new(P); int:=24; p:=@int; dispose(P); ^:指针的引用解析操作符; var pint:^ ...
- mysql二进制安装,升级,多实例部署
目标 理解线上部署考虑的因素 学会编译安装以及二进制安装mysql 学会升级mysql 学会多实例部署mysql数据库 学会合理部署mysql线上库 考虑因素: 版本选择,5.1,5.5还是5.6 ...
- UIView的任意圆角
今天在做项目的时候,遇到一个问题,grouped类型的tableview 怎么样才能让他们的一个view 其中一个角圆角? 如上图所示,其实我是用UILabel,但是箭头的位置总是尖的不太好看.设置l ...
- python核心编程学习(第三版)之字符串匹配
表示择一匹配的管道符号|,表示一个“从多个模式中选中其一”,有时候也称作并或者逻辑或 点号或者句号.符号匹配出了换行符\n以外的任何字符.如果要匹配句号,只需要使用反斜线转移句号符号的功能. ^匹配字 ...
- 【GLSL教程】(四)shder的简单示例 【转】
http://blog.csdn.net/racehorse/article/details/6638455 GLSL的Hello World 这一节中包含一个最基本的shader,它提供如下功能:顶 ...
- git工程迁移(修改提交服务器地址)方法
git remote set-url [--push] <name> <newurl> [<oldurl>]git remote set-url --add [-- ...