从零开始写一个RTSP服务器(一)RTSP协议讲解

news2025/6/8 16:00:14

目录

  • 前言
  • 一、什么是RTSP协议?
  • 二、RTSP协议详解
    • 2.1 RTSP数据格式
    • 2.2 RTSP请求的常用方法
    • 2.3 RTSP交互过程
    • 2.4 sdp格式
  • 三、RTP协议
    • 3.1 RTP包格式
    • 3.2 RTP OVER TCP
  • 四、RTCP

前言

为什么要写这个系列?

因为我自己在学习rtsp协议想自己从零写一个rtsp服务器的时候,由于rtsp比较复杂,所以觉得这个过程非常的困难,网上许多相关文章或模棱两可,或是复制粘贴。所以想写这样一个系列,来帮助想要学习rtsp协议或者想要从零写一个rtsp服务器的初学者

本系列的文章特点

并系列文章实现追求精简,能够让人明白rtsp协议的实现过程,不追求复杂和完美

如果想要实现一个比较完善的rtsp服务器,可以参考我的开源项目-RtspServer

言归正传,下面开始本系列的文章

一、什么是RTSP协议?

RTSP是一个实时传输流协议,是一个应用层的协议

通常说的RTSP包括RTSP协议、RTP协议、RTCP协议

对于这些协议的作用简单的理解如下

RTSP协议:负责服务器与客户端之间的请求与响应

RTP协议:负责传输媒体数据

RTCP协议:在RTP传输过程中提供传输信息

rtsp承载与rtp和rtcp之上,rtsp并不会发送媒体数据,而是使用rtp协议传输

rtp并没有规定发送方式,可以选择udp发送或者tcp发送

二、RTSP协议详解

rtsp的交互过程就是客户端请求,服务器响应,下面看一看请求和响应的数据格式

2.1 RTSP数据格式

RTSP协议格式与HTTP协议格式类似

RTSP客户端的请求格式

method url vesion\r\n
CSeq: x\r\n
xxx\r\n
...
\r\n

method:方法,表明这次请求的方法,rtsp定义了很多方法,稍后介绍

url:格式一般为rtsp://ip:port/session,ip表主机ip,port表端口好,如果不写那么就是默认端口,rtsp的默认端口为554,session表明请求哪一个会话

version:表示rtsp的版本,现在为RTSP/1.0

CSeq:序列号,每个RTSP请求和响应都对应一个序列号,序列号是递增的

RTSP服务端的响应格式

vesion 200 OK\r\n
CSeq: x\r\n
xxx\r\n
...
\r\n

version:表示rtsp的版本,现在为RTSP/1.0

CSeq:序列号,这个必须与对应请求的序列号相同

2.2 RTSP请求的常用方法

方法		描述
OPTIONS		获取服务端提供的可用方法
DESCRIBE	向服务端获取对应会话的媒体描述信息
SETUP		向服务端发起建立请求,建立连接会话
PLAY		向服务端发起播放请求
TEARDOWN	向服务端发起关闭连接会话请求

2.3 RTSP交互过程

有了上述的知识,我们下面来讲解一个RTSP的交互过程

OPTIONS

C–>S

OPTIONS rtsp://192.168.31.115:8554/live RTSP/1.0\r\n
CSeq: 2\r\n
\r\n

客户端向服务器请求可用方法

S–>C

RTSP/1.0 200 OK\r\n
CSeq: 2\r\n
Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY\r\n
\r\n

服务端回复客户端,当前可用方法OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY

DESCRIBE

C–>S

DESCRIBE rtsp://192.168.31.115:8554/live RTSP/1.0\r\n
CSeq: 3\r\n
Accept: application/sdp\r\n
\r\n

客户端向服务器请求媒体描述文件,格式为sdp

S–>C

RTSP/1.0 200 OK\r\n
CSeq: 3\r\n
Content-length: 146\r\n
Content-type: application/sdp\r\n
\r\n

v=0\r\n
o=- 91565340853 1 in IP4 192.168.31.115\r\n
t=0 0\r\n
a=contol:*\r\n
m=video 0 RTP/AVP 96\r\n
a=rtpmap:96 H264/90000\r\n
a=framerate:25\r\n
a=control:track0\r\n

服务器回复了sdp文件,这个文件告诉客户端当前服务器有哪些音视频流,有什么属性,具体稍后再讲解

这里只需要直到客户端可以根据这些信息得知有哪些音视频流可以发送

SETUP

C–>S

SETUP rtsp://192.168.31.115:8554/live/track0 RTSP/1.0\r\n
CSeq: 4\r\n
Transport: RTP/AVP;unicast;client_port=54492-54493\r\n
\r\n

客户端发送建立请求,请求建立连接会话,准备接收音视频数据

解析一下Transport: RTP/AVP;unicast;client_port=54492-54493\r\n

RTP/AVP:表示RTP通过UDP发送,如果是RTP/AVP/TCP则表示RTP通过TCP发送

unicast:表示单播,如果是multicast则表示多播

client_port=54492-54493:由于这里希望采用的是RTP OVER UDP,所以客户端发送了两个用于传输数据的端口,客户端已经将这两个端口绑定到两个udp套接字上,54492表示是RTP端口,54493表示RTCP端口(RTP端口为某个偶数,RTCP端口为RTP端口+1)

S–>C

RTSP/1.0 200 OK\r\n
CSeq: 4\r\n
Transport: RTP/AVP;unicast;client_port=54492-54493;server_port=56400-56401\r\n
Session: 66334873\r\n
\r\n

服务端接收到请求之后,得知客户端要求采用RTP OVER UDP发送数据,单播,客户端用于传输RTP数据的端口为54492,RTCP的端口为54493

服务器也有两个udp套接字,绑定好两个端口,一个用于传输RTP,一个用于传输RTCP,这里的端口号为56400-56401

之后客户端会使用54492-54493这两端口和服务器通过udp传输数据,服务器会使用56400-56401这两端口和这个客户端传输数据

PLAY

C–>S

PLAY rtsp://192.168.31.115:8554/live RTSP/1.0\r\n
CSeq: 5\r\n
Session: 66334873\r\n
Range: npt=0.000-\r\n
\r\n

客户端请求播放媒体

S–>C

RTSP/1.0 200 OK\r\n
CSeq: 5\r\n
Range: npt=0.000-\r\n
Session: 66334873; timeout=60\r\n
\r\n

服务器回复之后,会开始使用RTP通过udp向客户端的54492端口发送数据

TEARDOWN

C–>S

TEARDOWN rtsp://192.168.31.115:8554/live RTSP/1.0\r\n
CSeq: 6\r\n
Session: 66334873\r\n
\r\n

S–>C

RTSP/1.0 200 OK\r\n
CSeq: 6\r\n
\r\n

2.4 sdp格式

我们上面避开没有讲sdp文件,这里来好好补一补

sdp格式由多行的type=value组成

sdp会话描述由一个会话级描述和多个媒体级描述组成。会话级描述的作用域是整个会话,媒体级描述描述的是一个视频流或者音频流

会话级描述由v=开始到第一个媒体级描述结束

媒体级描述由m=开始到下一个媒体级描述结束

下面是上面示例的sdp文件,我们就来好好分析一下这个sdp文件

v=0\r\n
o=- 91565340853 1 in IP4 192.168.31.115\r\n
t=0 0\r\n
a=contol:*\r\n
m=video 0 RTP/AVP 96\r\n
a=rtpmap:96 H264/90000\r\n
a=framerate:25\r\n
a=control:track0\r\n

这个示例的sdp文件包含一个会话级描述和一个媒体级描述,分别如下

会话级描述

v=0\r\n
o=- 91565340853 1 IN IP4 192.168.31.115\r\n
t=0 0\r\n
a=contol:*\r\n

v=0

表示sdp的版本
o=- 91565340853 1 IN IP4 192.168.31.115
格式为 o=<用户名> <会话id> <会话版本> <网络类型><地址类型> <地址>
用户名:-
会话id:91565340853,表示rtsp://192.168.31.115:8554/live请求中的live这个会话
会话版本:1
网络类型:IN,表示internet
地址类型:IP4,表示ipv4
地址:192.168.31.115,表示服务器的地址

媒体级描述

m=video 0 RTP/AVP 96\r\n
a=rtpmap:96 H264/90000\r\n
a=framerate:25\r\n
a=control:track0\r\n

m=video 0 RTP/AVP 96\r\n

格式为 m=<媒体类型> <端口号> <传输协议> <媒体格式 >
媒体类型:video

端口号:0,为什么是0?因为上面在SETUP过程会告知端口号,所以这里就不需要了

传输协议:RTP/AVP,表示RTP OVER UDP,如果是RTP/AVP/TCP,表示RTP OVER TCP

媒体格式:表示负载类型(payload type),一般使用96表示H.264

a=rtpmap:96 H264/90000

格式为a=rtpmap:<媒体格式><编码格式>/<时钟频率>

a=framerate:25

表示帧率

a=control:track0

表示这路视频流在这个会话中的编号

三、RTP协议

3.1 RTP包格式

rtp包由rtp头部和rtp荷载构成

RTP头部
在这里插入图片描述
​ 版本号(V):2Bit,用来标志使用RTP版本

​ 填充位§:1Bit,如果该位置位,则该RTP包的尾部就包含填充的附加字节

​ 扩展位(X):1Bit,如果该位置位,则该RTP包的固定头部后面就跟着一个扩展头部

​ CSRC技术器(CC):4Bit,含有固定头部后面跟着的CSRC的数据

​ 标记位(M):1Bit,该位的解释由配置文档来承担

​ 载荷类型(PT):7Bit,标识了RTP载荷的类型

​ 序列号(SN):16Bit,发送方在每发送完一个RTP包后就将该域的值增加1,可以由该域检测包的丢失及恢复

​ 包的序列。序列号的初始值是随机的

​ 时间戳:32比特,记录了该包中数据的第一个字节的采样时刻

​ 同步源标识符(SSRC):32比特,同步源就是RTP包源的来源。在同一个RTP会话中不能有两个相同的SSRC值

​ 贡献源列表(CSRC List):0-15项,每项32比特,这个不常用

rtp荷载

rtp载荷为音频或者视频数据

3.2 RTP OVER TCP

RTP默认是采用UDP发送的,格式为RTP头+RTP载荷,如果是使用TCP,那么需要在RTP头之前再加上四个字节

第一个字节:$,辨识符

第二个字节:通道,在SETUP的过程中获取

第三第四个字节: RTP包的大小,最多只能12位,第三个字节保存高4位,第四个字节保存低8位

四、RTCP

RTCP用于在RTP传输过程中提供传输信息,可以报道RTP传输情况,还可以用来音视频同步,这里就不详细讲解了

本文是转载,目的是为了方便再后续的篇章中添加自己的实验操作部分。
原文链接:http://t.csdnimg.cn/8Johd

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1592610.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pytorch车牌识别

目录 使用pytorch库中CNN模型进行图像识别收集数据集定义CNN模型卷积层池化层全连接层 CNN模型代码使用模型 使用pytorch库中CNN模型进行图像识别 收集数据集 可以去找开源的数据集或者自己手做一个 最终整合成 类别分类的图片文件 定义CNN模型 卷积层 功能&#xff1a;提…

R:普通分组柱状图

输入文件实例&#xff08;存为csv格式&#xff09; library(ggplot2) library(ggbreak)# 从CSV文件中读取数据 setwd("C:/Users/fordata/Desktop/研究生/第二个想法(16s肠型&#xff0b;宏基因组功能)/第二篇病毒组/result/otherDB") data <- read.csv("feta…

【软件设计师知识点】一、计算机系统基础知识

文章目录 冯诺依曼计算机CPUCPU 的功能CPU 的组成 数据表示进制转换单位换算定点数浮点小数IEEE 754标准浮点数的运算 校验码奇偶校验码海明码循环冗余校验码&#xff08;CRC&#xff09; 指令系统指令格式寻址方式指令集指令流水线 存储系统存储器的层次化结构存储器的分类相联…

前端vue: 使用ElementUI适配国际化

i18n介绍 i18n&#xff08;其来源是英文单词 internationalization的首末字符i和n&#xff0c;18为中间的字符数&#xff09;是“国际化”的简称。 前端国际化步骤 1、安装i18n插件 安装插件时候&#xff0c;注意必须指定版本号&#xff0c;不然安装会报错。 npm i vue-i1…

【opencv】示例-points_classifier.cpp 使用不同机器学习算法在二维空间中对点集进行分类...

#include "opencv2/core.hpp" // 包含OpenCV核心功能的文件 #include "opencv2/imgproc.hpp" // 包含OpenCV图像处理功能的文件 #include "opencv2/ml.hpp" // 包含OpenCV机器学习模块的文件 #include "opencv2/highgui.hpp" // 包含O…

docker部署Prometheus+AlertManager实现邮件告警

文章目录 一、环境准备1、硬件准备&#xff08;虚拟机&#xff09;2、关闭防火墙&#xff0c;selinux3、所有主机安装docker 二、配置Prometheus1、docker启动Prometheus 三、添加监控节点1、docker启动node-exporter 四、Prometheus配置node-exporter1、修改prometheus.yml配置…

使用Python实现自动化网页答题功能-模拟考试篇

介绍 在驾驶员考试网站上进行模拟考试python自动答题 自动化原理 该脚本使用了自动化模块 DrissionPage 中的 ChromiumPage 类来实现网页的自动化操作。通过定位网页元素和模拟点击操作&#xff0c;完成了选择答案和提交答卷的过程。 用途与注意事项 用途&#xff1a;该脚本…

kafka学习笔记03

SpringBoot2.X项目搭建整合Kafka客户端依赖配置 用自己对应的jdk版本。 先加上我们的web依赖。 添加kafka依赖: SpringBoot2.x整合Kafka客户端adminApi单元测试 设置端口号。 新建一个kafka测试类&#xff1a; 创建一个初始化的Kafka服务。 设置kafka的名称。 测试创建kafka。…

在vue中配置样式 max-width:100px时,发现和width:100px一样没有对应的递增到最大宽度的效果?怎么回事?怎么解决?

原因&#xff1a; 可能时vue的样式大部分和display相关&#xff0c;有很多的联系&#xff0c;导致不生效 解决&#xff1a; 对设置max-width样式的元素设置display:inline-block;属性&#xff0c;即可生效&#xff0c;实现随着子元素的扩展而扩展并增加固定到最大的宽度

使用Postman发送跨域请求实验

使用Postman发送跨域请求 1 跨域是什么&#xff1f;2 何为同源呢?3 跨域请求是如何被检测到的&#xff1f;4 Postman跨域请求测试4.1 后端准备4.2 测试用例4.2.1 后端未配置跨域请求(1) 前端不跨域&#xff08;2&#xff09;前端跨域 4.2.2 后端配置跨域信息&#xff08;1&…

Springboot整合mybatis_plus + redis(使用原生的方式)

首次&#xff0c;创建一个springboot项目&#xff0c;勾选相应的依赖Lombok、Web 添加依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>…

基于Python的深度学习的中文情感分析系统(V2.0),附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

13 Php学习:面向对象

PHP 面向对象 面向对象&#xff08;Object-Oriented&#xff0c;简称 OO&#xff09;是一种编程思想和方法&#xff0c;它将程序中的数据和操作数据的方法封装在一起&#xff0c;形成"对象"&#xff0c;并通过对象之间的交互和消息传递来完成程序的功能。面向对象编…

理想大模型实习面试题6道|含解析

节前&#xff0c;我们星球组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、参加社招和校招面试的同学&#xff0c;针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。 汇总…

在 Google Cloud 上轻松部署开放大语言模型

今天&#xff0c;“在 Google Cloud 上部署”功能正式上线&#xff01; 这是 Hugging Face Hub 上的一个新功能&#xff0c;让开发者可以轻松地将数千个基础模型使用 Vertex AI 或 Google Kubernetes Engine (GKE) 部署到 Google Cloud。 Model Garden (模型库) 是 Google Clou…

Qt | 视频播放器(multimedia、multimediawidgets)

QT +=multimedia 通俗解释: 此代码行告诉编译器在构建应用程序时包含多媒体库。这意味着您的应用程序将能够播放和显示音频和视频文件。 使用分步说明构建模型: 创建一个新的 Qt 项目。 在 .pro 文件中添加以下行: QT += multimedia 导入必要的多媒体头文件: #include &l…

Android 加密之 打包为arr 项目依赖或者为jar

Android 加密之 打包为arr 项目依赖或者为jar 1. 修改build.gradle plugins {//id com.android.application// 1. 修改为libraryid com.android.library }android {namespace com.dzq.iccid2compileSdk 33defaultConfig {//applicationId "com.dzq.iccid2"// 2. 注…

嵌入式驱动学习第七周——I2C子系统

前言 I2C子系统详解&#xff0c;本篇博客从内核源码的角度来看I2C子系统。 嵌入式驱动学习专栏将详细记录博主学习驱动的详细过程&#xff0c;未来预计四个月将高强度更新本专栏&#xff0c;喜欢的可以关注本博主并订阅本专栏&#xff0c;一起讨论一起学习。现在关注就是老粉啦…

爱奇艺APP Android低端机性能优化

01 背景介绍 在智能手机市场上&#xff0c;高端机型经常备受瞩目&#xff0c;但低端机型亦占据了不可忽视的份额。众多厂商为满足低端市场的需求&#xff0c;不断推出低配系列手机。另外过去几年的中高端机型&#xff0c;随着系统硬件的快速迭代&#xff0c;现已经被归类为低端…

学习Rust的第4天:常见编程概念

欢迎来到学习Rust的第四天&#xff0c;基于Steve Klabnik的《The Rust Programming Language》一书。昨天我们做了一个 猜谜游戏 &#xff0c;今天我们将探讨常见的编程概念&#xff0c;例如&#xff1a; Variables 变量Constants 常数Shadowing 阴影Data Types 数据类型Functi…