# RTMP协议
# 理论知识介绍
# 简介
目前流媒体直播主要使用rtmp协议进行推流和拉流,推流使用一些软件(例如OBS、ffmpeg等)将采集到的视频以数据流的形式推送到后端服务器上,拉流是从服务器端将数据流拉取到客户端进行解码和播放。
整个网络视频直播简化框图如下所示
在以上过程中,推拉流是视频播放的核心部分,而在推拉流过程中使用的协议即流媒体传输协议对传输质量的影响最大。
RTMP,全称 Real Time Messaging Protocol,即实时消息传送协议,是一种设计用来进行实时数据通信的网络协议。由Adobe 公司开发,是一种多媒体的复用和分组的应用层协议,带有时间信息的视频、音频和数据消息流,通过通信端之间进行传输,主要用来在Flash/AIR平台和支持RTMP协议的流媒体/交互服务器之间进行音视频和数据通信,支持该协议的软件包括Adobe Media Server/Ultrant Media Server/red5等。
RTMP 是目前主流的流媒体传输协议,广泛用于直播领域,可以说市面上绝大多数的直播产品都采用了这个协议。
# 通信机制
RTMP 协议属于应用层协议,由底层的传输层协议 TCP 确保其稳定性和可靠性。在传输层协议 TCP 的链接建立完成后,基于应用层协议的Connection 链接,RTMP 协议需要客户端和服务器端通过握手完成后来建立,块尺寸、视频显示尺寸等控制信息会通过 Connection 链接来传输。
使用 RTMP 协议来传输流媒体数据的过程中,数据采集端会先把流媒体数据以消息的形式进行封装成消息,然后再把消息分割成更小的带有ID的消息块,最后将消息块通过TCP协议传输出去。
客户端通过TCP协议接收消息块数据,根据块中包含的信息 ID、信息的长度和数据的长度,把消息块重新组装成消息,然后再通过拆解封装对消息进行还原,这样就可以恢复出采集端发送的流媒体数据.
- 握手过程
RTMP 协议在使用时首先进行客户端与服务端的握手。客户端发出握手请求,服务端响应握手请求;握手完成之后建立网络连接;在建立了网络连接的基础上完成网络流的建立;只有在建立了网络流之后客户端才能进行文件的播放。
RTMP的握手通过互发消息块,其中客户端发送的消息块被指定为C0,C1,C2,服务端发送的消息块指定为S1,S2,S3,握手过程主要分为三个步骤,其握手过程如下所示:
第一步 Client -> Server,内容是 C0+C1
第二步 Server -> Client,内容是 S0+S1+S2
第三步 Client -> Server,内容是 C2
1)客户端主动发送C0,C1;客户端必须等待S1到达才能发送C2; 必须等待S2到达才能发送其他数据;
2)服务端必须等待C0到达才能发送S0和S1;必须等待C1到达才能发送S2; 必须等待C2到达才能发送其他数据
# RTMP分块
RTMP 协议是一个处于传输层 TCP/IP 协议之上的应用层协议,协议中的基本数据单元为 Message(消息)。在网络传输数据时,需要把消息再拆分成更小的单元Chunk(消息块),这样更有利于在不同的网络环境下顺利完成数据的传输。每个消息块有唯一的ID进行标识,这些块流通过 RTMP 协议进行传输,传输每个消息块必须等待上一消息块时发送完毕后才可以发送下一个块流,接收端将这些消息块按照块流ID又被重新合成了消息。
- 消息(Message)
Message 主要由 Message 的头部和 Message 的体构成,而头部的数据又是整个 Message 的重中之重。Message 的头部由 MessageType、PayLoad Length、 TimeStamp、StreamId 四个部分组成:
- MessageTypeID:主要用于标记消息的类型。
- PayLoadLength:用于标记消息的长度。
- TimeStamp:消息的时间戳。
- StreamID:标记该消息所属的流的 Id。
- MessageBody:剩下的部分为消息的有效负载,其中包括的就是用户要发 送或者接收的实际内容,例如,可以是音频数据或者是视频数据。
- 消息块(Chunk)
消息块的首部消息头由三部分组成:用于识别消息块的基本块头,用于识别消息块负载的消息块头,以及当时间戳出现溢出后,出现的扩展时间戳。
- Basic Header :基本块头,由 1 到 3 个字节组成,通过此字段对块流ID和块流类型进行编码。块流类型决定了消息头以什么格式进行编码。基本块头的长度是由块流 ID 来决定的,因为块流ID的长度是可变的。
- Message Header :消息块头,由 0、3、7、或者11个字节组成,消息块头是对正在发送的消息中的信息进行编码。块类型决定了消息块头的长度是由多少字节组成的。
Extended Timestamp:扩展时间戳,由0或4字节组成,是否有扩展时间戳取决于块消息头中的时间戳字段的增量。 - Chunk Data :块头数据,当前块头的有效载荷,通过块头数据来定义的最大块的大小。
# Nginx+RTMP视频直播环境搭建
# 下载安装包
- 安装相关的编译环境
sudo apt-get install build-essential libtool libpcre3 libpcre3-dev zlib1g-dev openssl libssl-dev
- 下载nginx安装包
# 下载安装包
sudo wget http://nginx.org/download/nginx-1.8.0.tar.gz
# 解压安装包
tar -zxvf nginx-1.8.0.tar.gz
- 下载nginx-rtmp-module安装包
# 直接从github拉取
sudo git clone https://github.com/arut/nginx-rtmp-module.git
将解压后的文件夹放到以下目录中
/usr/local/src
此时src文件夹中存在两个文件夹分别是
进入nginx-1.8.0文件夹中,运行
sudo ./configure --prefix=/usr/local/src/nginx --add-module=../nginx-rtmp-module --with-http_ssl_module
之后编译
sudo make && sudo make install
之后进入/usr/local/src文件夹下,会多出一个新生成的nginx文件夹,进入nginx文件夹中,开启nginx服务器进行测试
sudo ./sbin/nginx
打开浏览器,输入localhost,若显示nginx欢迎页面,则开启成功。
# 修改nginx配置文件
在nginx配置文件中添加rtmp配置信息
sudo nano /usr/local/src/nginx/conf/nginx.conf
添加以下代码
rtmp {
server {
listen 1935;#配置rtmp端口
chunk_size 4096;#配置信息块大小
application mylive {# mylive是自己定义的一个名字
live on;
}
}
}
以上代表配置rtmp协议端口是1935,信息块大小是4096,应用的名字是mylive。
# OBS推流
下载OBS软件
OBS安装包下载
在设置中,进行推流服务器配置
rtmp://192.168.1.100:1935/mylive
之后点击开始推流进行推流。
# 拉流直播
使用播放软件进行拉流播放视频,Windows系统下可以用VLC,MAC系统下可以用IINA,在此用IINA进行演示。
在IINA打开URL选项卡中进行服务器配置,
之后经过几秒缓冲后,即可看到输出流画面,如下所示。
# 完成
到此终于完成!!!! 🎉🎉🎉🎉🎉🎉🎉