一个RtspServer的设计与实现和RTSP2.0简介

  前段时间着手实现了一个RTSP Server,能够正常实现多路RTSP流的直播播放,因项目需要,只做了对H.264和AAC编码的支持,但是相信其他编码的实现基本逻辑也是想通的。这里我把主要设计和思考过程,以及实现框架分享一下。因为关注的是直播,这里只讨论RTSP直播协议。

RTSP协议概述与RTSP2.0

  众所周知,RTSP协议是一个流媒体协议,可以实现直播和点播形式的音频与视频流的播放。RTSP协议定义了多种服务器-客户端之间交互的接口,主要有OPTIONS,DESCRIBE,SETUP,PLAY,TEARDOWN,RECORD,ANNOUNCE。网络上已经有很多针对RTSP协议的文章,我这里不准备进行过多介绍,详细的协议定义,可以参见RFC2326。RTSP并不包括具体数据的传输,该功能一般由RTP与RTCP协议来实现,并可以通过TCP或UDP两种底层传输方式进行。

  下图是典型的RTSP直播过程中服务端-客户端主要交互过程:

  当然,直播过程中也可能在服务器与客户端之间调用GET_PARAMETER等其他接口,上图偷懒省略了。上图绿色部分表示的是数据传输。之前说过,流媒体数据传输不是RTSP协议的内容,由RTP包来做。但是具体在实现上,RTP包可以通过UDP或TCP的方式来进行,而且这两种传输方式,区别其实还不小,下面具体说下。

RTSP 数据传输流程

1. RTSP over UDP

  对于udp模式,客户端在发送PLAY以后,就开始建立udp端口,以接收服务器发来的RTP包,同样,服务器也会建立udp端口,并向客户端发送RTP包。这是网上大部分程序所采用的方式,优点是逻辑清晰,实现方便,不过缺点也很明显,就是udp所固有的,容易丢包,尤其是在高分辨率高码率下。

  

2. RTSP over TCP

  对tcp模式,通过SETUP接口来指定传输方式,服务器返回同样数据以确定双方通过tcp方式来传输数据。不过跟udp最大的不同是,rtsp over tcp的形式,不再创建单独的tcp通道,而是直接使用之前rtsp通信所使用的tcp通道,流程如下所示:

  

  由于跟rtsp消息使用同一个tcp端口,为了区分,rtp以及rtcp包,增加了4个字节额外的字段,并通过特殊的标识'$',与正常的rtsp消息进行了区分。

RTSP Live Server 设计与实现

1. 程序框架

  我这次所实现的RTSP Server,主要功能是采集摄像头和麦克风数据,进行h.264编码以及aac编码,并对外提供RTSP直播流服务。我在实际写代码中,也是首先实现了rtsp over udp的模式,然而,通过实际测试,我发现在高分辨率高码率情况下,由于h.264 NAL单元过大,会拆分成很多的rtp包,而udp不可靠的传输方式,总是难免丢包,在低码率的时候还不明显,高码率情况下,丢包导致的花屏会频繁出现,这样体验特别差。于是我重新实现了一份rtsp over tcp模式的代码,顺利解决了这个问题。

  

2. 关于h264在sdp中的描述

  h264在sdp中的媒体信息,大多都是可以直接填写的,但是有两项数据需要根据编码后的数据来提取,就是profile-level-id和sprop-parameter-sets。这两项字符串数据的计算公式

  • profile-level-id = "Base16(sps[1])" + "Base16(sps[2])" + "Base16(sps[3])"
  • sprop-parameter-sets = "Base64(sps)" + "," + "Base64(pps)"

3. 主要代码

3.1 Rtsp服务接口

3.2 RtspSession在TCP通道里处理RTSP消息与RTP报文

4. 运行效果

  同时用vlc和ffplay进行多路播放,以tcp请求的方式,效果如下,延迟极低。

关于RTSP 2.0

  2016年IETF发布了新的RTSP标准,这就是就是RTSP2.0协议(RFC7826),新标准还是有不少修改的,除了完善一些原协议的中的定义,还有一些我觉得比较重要的是,对接口method进行了修改,比如删除了RECORDANNOUNCE方法,新增了PLAY_NOTIFY方法。

  • 删除了RECORD,这表示你不能再通过这个接口来控制服务器进行数据的录制了,可以选择在PLAY方法中,添加一些参数,来实现服务器对直播数据进行录制,还可以分隔录制。
  • 删除了ANNOUNCE,这意味着,不能像RTMP一样,客户端通过向服务器推送数据,来实现本机数据对外直播了,这可能需要其他的推送途径来进行替代了。
  • 至于PLAY_NOTIFY,它替代来原来Server向Client端发送ANNOUNCE方法,所实现的功能,也就是告诉客户端,需要根据新参数来调整直播播放状态。
  • 删除通过UDP传输RTSP消息的形式
  • 删除通过发PLAY消息来keep alive的方式(用SET_PARAMETER来做)
  • RTSP Server也可向Client发TEARDOWN消息
  • 支持IPV6
  • RTSP请求,支持pipelining的形式,也就是聚合Request。比如可以不等服务器返回,把SETUP和PLAY一起发送,这样可以提高至少一个RTT的启动时间。当然需要在消息里加上相关字段。
  • 重写了状态机,完善了服务器对客户端来说在各个状态之间的转换和行为
  • RTSP消息内支持URI了
  • 扩展了REDIRECT方法,等,等等。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

haibindev.cnblogs.com,合作请联系QQ。(转载请注明作者和出处~)

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

一个RtspServer的设计与实现和RTSP2.0简介的更多相关文章

  1. .Net开发笔记(十九) 创建一个可以可视化设计的对象

    阅读本篇博客之前需要了解VS窗体设计器的工作原理,详细可参见本系列博客(十).(十一).(十二).必须需要知道的一条结论就是:处于窗体设计器(Form Designer)中的任何组件(包含控件,下同) ...

  2. Swing 是一个为Java设计的GUI工具包

    Swing 是一个为Java设计的GUI工具包. Swing是JAVA基础类的一部分. Swing包括了图形用户界面(GUI)器件如:文本框,按钮,分隔窗格和表. Swing提供许多比AWT更好的屏幕 ...

  3. App 图标设计 - 圆角透明效果(0 基础使用 PS)

    App 图标设计 - 圆角透明效果(0 基础使用 PS) 方法: 如果你有些基础,就不必看图文教程了: 1.使用圆角矩形工具选中,设置圆角尺寸[例如:1024*1024 px(圆角:160 px)] ...

  4. CS5263替代PS176|设计DP1.4转HDMI2.0音视频转换线方案|PS176方案

    PS176是一个显示端口 (DP)至HDMI 2.0视频接口转换器适用于需要视频协议转换的电缆适配器.电视接收器.监视器和其他应用.它将接受任何显示端口输入格式,包括DP 1.1a.dp1.2a.dp ...

  5. 庆祝下,提交了第一个ceph pull request。实现了从0到1的突破

    庆祝一下!经过社区老司机的带路,昨天提交了第一个ceph pull request.实现了从0到1的突破,希望再接再厉提交更多代码到社区,为社区发展贡献一点自己力量. 提交的第一个被社区fix的bug ...

  6. JavaScript语言里判断一个整数,属于哪个范围:大于0;小于0;等于0

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. 如何提交代码到CEPH Repo。 顺便庆祝下,提交了第一个ceph pull request。实现了从0到1的突破

    庆祝一下!经过社区老司机的带路,昨天提交了第一个ceph pull request.实现了从0到1的突破,希望再接再厉提交更多代码到社区,为社区发展贡献一点自己力量. 提交的第一个被社区fix的bug ...

  8. 公司新来了一个质量工程师,说团队要保证 0 error,0 warning

    摘要:静态代码检查又称为静态程序分析,是指在不运行计算机程序的条件下,进行程序分析的方法. 本文分享自华为云社区<公司新来了一个质量工程师,说团队要保证 0 error,0 warning> ...

  9. 优化一个奇葩表设计上的全表扫描SQL

    之前在一个比较繁忙的系统抓到的耗时长.消耗CPU多的一条SQL,如下:SELECT * FROM Z_VISU_DATA_ALARM_LOG TWHERE TO_DATE(T.T_TIMESTR, ' ...

随机推荐

  1. jfinal使用配置文件注意事情

    使用Popkit @Override public void configConstant(Constants me) { me.setViewType(ViewType.JSP); PropKit. ...

  2. PyCharm 2017 官网 下载 安装 设置 配置 (主题 字体 字号) 使用 入门 教程

    一.安装 Python 3.6 首先,要安装好 Python 3.6.如果你还没有安装,可以参考咪博士之前的教程 Python 3.6.3 官网 下载 安装 测试 入门教程 (windows) 二.官 ...

  3. 使用速卖通开放平台云API调用菜鸟组件实现云打印

    公司是跨境电商,使用速卖通平台卖玩具,我们自己研发的ERP是基于速卖通开放平台API,实现订单的发货提交,打印面单等功能 近期公司要求使用菜鸟组件云打印,去平台里看下,有这个API,如下图所示 实现也 ...

  4. maven中jetty插件配置

    maven中jetty插件的配置,可用于项目在内置jetty服务器中的部署. <plugin> <groupId>org.mortbay.jetty</groupId&g ...

  5. Python之qq邮件

    用python发送电子邮件验证这个功能,可以说花费了我很久时间,这也是为什么我重头敲了之前的两遍代码.不要说我傻,仅仅是笨了一点而已 ^.- . 之前我所参考是如何发送 GMail. 但是我并不想这么 ...

  6. 微信小程序之bindtap事件绑定传参

    wxml代码: <view class='fen'> <text bindtap='prev' data-page="{{pageDang}}">上一页&l ...

  7. 上传图文{"errcode":40007,"errmsg":"invalid media_id"}解决方案

    {"errcode":40007,"errmsg":"invalid media_id"}解决方案 网上关于这个问题的解决一般是把thumb ...

  8. Linux中main是如何执行的

    Linux中main是如何执行的 这是一个看似简单的问题,但是要从Linux底层一点点研究问题比较多.找到了一遍研究这个问题的文章,但可能比较老了,还是在x86机器上进行的测试. 原文链接 开始 问题 ...

  9. 关于C#开发中那些编码问题

    最近一直在搞各种编码问题,略有心得,与大家分享一番. System.Text提供了Encoding的抽象类,这个类提供字符串编码的方法.常用的编码方式主要有ASCII,Unicode,UTF8(Uni ...

  10. linux学习(十一)用户和用户组管理

    一.用户文件 文件:/etc/passwd 这个文件记录了用户了用户名,用户id,所属组,家目录,shell信息: [root@iZ25lzba47vZ ~]# tail -n3 /etc/passw ...