RTSP学习笔记(2)live555
为什么80%的码农都做不了架构师?>>>
RTSPClient
RTSPClient 是RTSP协议的客户端实现,用于发送RTSP请求命令
类接口:
static RTSPClient* createNew()
用于外部创建RTSPClient实例的方法,将构造方法进行了隐藏(protect);
unsigned sendXXXXCommand()
发送RTSP请求,会传入回调函数responseHandler;
responseHandler是类内部定义的一个函数指针,统一回调的格式
typedef void (responseHandler)(RTSPClient* rtspClient, int resultCode, char* resultString);
int socketNum() const
返回用于连接的socket;
staticBoolean lookupByName(UsageEnvironment& env,char const* sourceName,
RTSPClient*& resultClient)
查找sourceName指定的RTSPClient
staticBoolean parseRTSPURL(UsageEnvironment& env, char const* url,
char*& username, char*& password,NetAddress& address, portNumBits& portNum, char const** urlSuffix =NULL)
解析输入的RTSPURL,主要用于获取服务器地址NetAddress& address和端口号portNumBits& portNum,还会返回urlSuffix的指针,标识媒体名等信息;
voidsetUserAgentString(char const* userAgentName)
指定RTSP回应消息中的"User-Agent: %s\r\n"字段,类内部保存了fUserAgentHeaderStr,会将其内容替换为userAgentName;
charconst* url() const
返回初始请求服务器的url信息,即rtsp://…//...;就是parseRTSPURL中的URL,保存在fBaseURL中;
保护方法:
voidreset()
重置RTSPClient,1、关闭socket;2、重置responseBuffer的指示变量;3、清除分BaseURL等
voidsetBaseURL(char const* url)
设置请求的URL信息fBaseURL;
virtualunsigned sendRequest(RequestRecord* request)
发送请求,请求统一封装在RequestRecord;
------------------------------------------------------------------------------------------------------------------------------------------------------
内部类
RequestRecord 公开
该类封装了请求命令,只用来保存请求的信息,如命令名称、回调函数等;
RequestRecord(unsignedcseq, char const* commandName, responseHandler* handler,
MediaSession*session = NULL, MediaSubsession* subsession = NULL,
u_int32_t booleanFlags = 0,
doublestart = 0.0f, double end = -1.0f, float scale = 1.0f,
charconst* contentStr = NULL);
所有信息都在初始化时传入,之后类为每一个信息都提供了访问方法
RequestQueue 私有
该类定义了RequestRecord的队列,可以保存请求信息,还提供了一些工具方法如下
voidputAtHead(RequestRecord* request); // "request" must not be NULL
RequestRecord*findByCSeq(unsigned cseq);
---------------------------------------------------------------------------------------------------------------------------------------------------------
成员变量:
——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
ServerMediaSession
ServerMediaSession是RTSPServer中用于表示一个媒体信息的类,内部会包含该媒体需要的子媒体ServerMediaSubsession,例如一个MP4文件既有视频也有音频,那这个ServerMediaSession就需要包含表示视频的subSession和音频的subSession。
类接口:
staticServerMediaSession* createNew(UsageEnvironment& env,
char const* streamName = NULL,
char const* info = NULL,
char const* description = NULL,
Boolean isSSM = False,
char const* miscSDPLines = NULL);
外部创建ServerMediaSession实例的方法,在Live555中对类的实例化大多采用了这种方式,在方法内部调用类的构造函数,还不知道这么做有什么用意,为什么不直接用构造函数?
staticBoolean lookupByName(UsageEnvironment& env,
char const*mediumName,
ServerMediaSession*& resultSession);
查找mediaName对应的serverMediaSession,内部是通过Medium::lookupByName(env, mediumName, medium)这个静态方法实现的,什么时候添加的?
char*generateSDPDescription();
生成媒体的SDP信息,分配的字符串内存由调用者负责释放;
关键部分
for each serverMediaSubSession {subSesssion->sdpLines()};// 产生各个子媒体的sdp描述
char const* streamName() const;
返回fStreamName,媒体名
BooleanaddSubsession(ServerMediaSubsession* subsession);
添加subSession,在ServerMediaSession内有头尾subSession的指针,可以形成单列表,
fSubsessionsTail= subsession;
subsession->fParentSession= this;
subsession->fTrackNumber =++fSubsessionCounter; // 增加count数,并将其设置为subSession的trackNameber
unsignednumSubsessions() const
返回fSubsessionCounter,在该ServerMediaSession总subSession的数目
unsignedreferenceCount() const { return fReferenceCount; }
voidincrementReferenceCount() { ++fReferenceCount; }
voiddecrementReferenceCount() { if (fReferenceCount > 0) --fReferenceCount; }
Boolean& deleteWhenUnreferenced() {return fDeleteWhenUnreferenced; } // 指示是否已经没有了引用而可以析构了
void deleteAllSubsessions(); //移除所有subSession
保护方法:
ServerMediaSession(UsageEnvironment&env, char const* streamName,
char const* info, char const* description,
Boolean isSSM, char const* miscSDPLines);
构造方法,主要初始化一些sdp需要的描述信息:fStreamName,fInfoSDPString,fDescriptionSDPString,fMiscSDPLines,fCreationTime
成员变量:
ServerMediaSubSession
ServerMediaSubSession是一个媒体流中表示子媒体的结构
类接口:
unsignedtrackNumber() const
返回表示该subSession的ID:fTrackNumber,这个值会在ServerMediaSession添加subSession时赋予;
charconst* trackId();
返回trackID字符串fTrackId:("track%d",fTrackNumber)
virtualchar const* sdpLines() = 0;
纯虚函数,需子类具体实现,返回sdp描述中的媒体信息,如
/*
m=video 0 RTP/AVP 96
c=IN IP4 0.0.0.0
b=AS:500
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1;profile-level-id=4D4033;
sprop-parameter-sets=Z01AM5p0FidCAAADAAIAAAMAZR4wZUA=,aO48gA==
a=control:track1
*/
virtualvoid getStreamParameters(unsigned clientSessionId, // in
netAddressBits clientAddress, // in
Port const& clientRTPPort, // in
Port const& clientRTCPPort, // in
int tcpSocketNum, // in (-1 means use UDP,not TCP)
unsigned char rtpChannelId, // in (used ifTCP)
unsigned char rtcpChannelId, // in (used ifTCP)
netAddressBits& destinationAddress, //in out
u_int8_t& destinationTTL, // in out
Boolean& isMulticast, // out
Port& serverRTPPort, // out
Port& serverRTCPPort, // out
void*& streamToken // out
) = 0;
纯虚函数,返回各种流参数;
virtualvoid startStream(unsigned clientSessionId, void* streamToken,
TaskFunc* rtcpRRHandler,
void* rtcpRRHandlerClientData,
unsigned short& rtpSeqNum,
unsigned& rtpTimestamp,
ServerRequestAlternativeByteHandler*serverRequestAlternativeByteHandler,
void*serverRequestAlternativeByteHandlerClientData) = 0;
纯虚函数,启动流传输,即开始播放;
///
下面这些函数都只定义了接口,没有做具体实现,子类可以根据情况完成
virtualvoid pauseStream(unsigned clientSessionId, void* streamToken);
virtual void seekStream(unsigned clientSessionId, void* streamToken,double& seekNPT, double streamDuration,u_int64_t& numBytes);
// This routine is used to seek byrelative (i.e., NPT) time.
// "streamDuration", if >0.0,specifies how much data to stream, past "seekNPT". (If <=0.0, all remaining data isstreamed.)
// "numBytes" returns the size(in bytes) of the data to be streamed, or 0 if unknown or unlimited.
virtualvoid seekStream(unsigned clientSessionId, void* streamToken, char*&absStart, char*& absEnd);
// This routine is used to seek by'absolute' time.
// "absStart" should be a stringof the form "YYYYMMDDTHHMMSSZ" or"YYYYMMDDTHHMMSS.<frac>Z".
// "absEnd" should be eitherNULL (for no end time), or a string of the same form as "absStart".
// These strings may be modified in-place,or can be reassigned to a newly-allocated value (after delete[]ing theoriginal).
virtualvoid setStreamScale(unsigned clientSessionId, void* streamToken, float scale);
virtualFramedSource* getStreamSource(void* streamToken);
virtualvoid deleteStream(unsigned clientSessionId, void*& streamToken);
virtualvoid testScaleFactor(float& scale); // sets "scale" to the actualsupported scale
virtualfloat duration() const;
// returns 0 for an unbounded session (thedefault)
// returns > 0 for a bounded session
virtualvoid getAbsoluteTimeRange(char*& absStartTime, char*& absEndTime)const;
/
转载于:https://my.oschina.net/seanx/blog/619623
RTSP学习笔记(2)live555相关推荐
- live555 学习笔记-建立RTSP连接的过程(RTSP服务器端)
live555 学习笔记-建立RTSP连接的过程(RTSP服务器端) 监听 创建rtsp server,rtspserver的构造函数中,创建监听socket,添加到调度管理器BasicTaskSch ...
- FFmpeg基础到工程-多路H265监控录放开发学习笔记
多路H265监控录放开发学习笔记 课程涉及:FFmpeg,WebRTC,SRS,Nginx,Darwin,Live555,等.包括:音视频.流媒体.直播.Android.视频监控28181.等. 具体 ...
- 目标检测——YOLOv5的学习笔记
目录 1 前言 2 Tricks一览表 3 配置文件说明 模型参数: 模块参数 Conv:卷积模块 2 数据载入 2.1 数据预处理 3 模型加载 4 Inference--前向推理 5 Train- ...
- 我的Android进阶之旅------gt;Android中编解码学习笔记
编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放license收费等等 ...
- 网络协议学习笔记 · 22
IPv6 · 流媒体 · 即时通讯 · 缓存 · 网络爬虫 VPN 作用 VPN与代理的区别 实现原理(隧道协议) 网络爬虫 简易实例 robots.txt 无线网络 缓存(Cache) 响应头 请求 ...
- (转)DHTML学习笔记
DHTML学习笔记(转) 目录: 1.网页技术的三方面 2.DHTML的组成 3.rgb颜色表示 4.js删除提示 5.前进.后退.返回某页.刷新.关闭 7.定时关闭网页 8.背景音乐 9.浏览器显示 ...
- Protocol - Exploits学习笔记
Protocol - Exploits 注:本分类里内容并非全是协议的 bug,部分 "基于.使用" 这个协议的应用所存在的漏洞也算在其中,例如 dns 域传送漏洞,其并非 dns ...
- curl 命令的学习笔记
curl 命令的学习笔记 curl 官网:https://curl.haxx.se/ curl 全称 CommmandLine URL 或 CommandLine Uniform Resource L ...
- 编解码学习笔记(基础)
编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放license收费等等 ...
最新文章
- BoW模型用于图像检索的一般化流程
- java以逗号截取字符串_使用java流获取逗号分隔的字符串
- Google排名第一的编程语言,死磕它这两点,小白也能学的会!不信你看!
- EasyUI权限系列(一星权限)
- Go语言 -- PostgreSQL数据库
- MATLAB小技巧(28)模糊综合评价
- oracle常用函数汇总(1)
- 企业微信异常java.security.InvalidKeyException:illegal Key Size的解决方案,提供jce_policy-8下载
- shuipFCMS的开发记录
- 关于windows10在学习爬虫是用到appium配置java的jdk出现了,javac不是内部命令的解决方法(¥57)
- markdown: 欢迎使用马克飞象
- ffmpeg音视频转单声道16位16K赫兹小端点pcm音频
- 类型转换及类型转换函数
- 酒店在线订房小程序开发解决方案
- 计算机网络-9-局域网交换与VLAN
- 使用容联云通讯实现电话云呼叫功能
- SQL Server 2016的安装
- 开源案例:Spring Boot + Vue 的音乐网站
- matlab小球图像纹理分割,17.6 使用纹理滤波器分割图像(1) - 51CTO.COM
- python 四足机器人运动学_【基础知识】四足机器人的站立姿态控制原理
热门文章
- Python双版本下No module named 'requests'
- 谈谈java并发锁(重入锁、读写锁、公平锁)
- 八、二分查找(Binary Search)
- 7-28作业直接刷一下
- python3框架的rf_pythonRF框架
- php gd 行间距设置,PHP动态修改GD库扩展问题
- 绘制多个折线图_学习笔记第一页 | 常用统计图绘制及描述规范
- 喜报丨神策数据荣获“2021 年度金屏奖大屏应用创新奖”
- 深度干货 | 多维分析中的 UV 与 PV
- 【spring boot】spring boot @ConditionalOnxxx相关注解总结