学习雷博士的文章
环境:Ubuntu 16.04.7
ffmpeg-6.1
简介
librtmp是一个开源的基于C语言的库,提供了一个连接RTMP服务器,发送和接收RTMP流的API。
它可以用来开发流媒体播放器,网络直播等应用。它的主要特点是快速、稳定和低延迟。
librtmp支持RTMP,RTMPS,RTMPE和RTMPTE加密协议等多种协议。除此之外,它还支持
PProxy,PPlayer和appspot的代理服务器协议。在Linux下,使用librtmp开发的应用可以支持
Windows,Android等多种系统平台。
librtmp的核心代码是基于ffmpeg中的libavformat库实现的。它依赖于libz, libssl, libcrypto等第三方
库,需要自行编译安装。
1、学习rtmp协议
2、下载librtmp
git clone git://git.ffmpeg.org/rtmpdump
3、编译librtmp
依赖 zlib和openssl库,如果没有apt-get install 装下
指定librtmp安装目录,修改Makefile
vi rtmpdump/Makefile
默认 prefix=/usr/local 改为指定目录,笔者目录 prefix=../rtmpdump_dir
vi rtmpdump/librtmp/Makefile
默认 prefix=/usr/local 改为指定目录,笔者目录 prefix=../../rtmpdump_dir
在rtmpdump 目录 make install
4、librtmp API
RTMP_Alloc()
分配一个RTMP句柄
RTMP_Init()
初始化RTMP句柄
RTMP_SetupURL()
设置RTMP服务器地址
RTMP_EnableWrite()
启动写入流的模式,发布流的时候必须要使用,如果不使用则代表接收流
RTMP_Connect()
连接服务器,创建一个RTMP协议规范中的NetConnection
RTMP_ConnectStream()
连接流,创建一个RTMP协议规范中的NetStream
RTMP_IsConnected
RTMP是否处于连接状态
RTMP_SendPacket()
发送一个RTMP数据RTMPPacket
RTMP_Read()
从服务器读取数据
RTMP_Close()
关闭RTMP连接
RTMP_Free()
释放RTMP句柄
5、下载雷博士测试代码
https://github.com/leixiaohua1020/simplest_librtmp_example
git clone https://gitcode.com/leixiaohua1020/simplest_librtmp_example.git
6、测试
6.1 FLV封装
补充点FLV封装知识,有助于更好的理解代码
FLV 由文件头(file header)和(file body)组成,其中 FLV body 由一对对的 Tag 和 Previous Tag Size(占用4个字节,记录前一个 Tag 的大小,用于逆向读取处理,FLV header 后的第一个 Previous Tag Size 为 0)组成。而 Tag 一般分为三种类型:script data、视频数据、音频数据,有 Tag header 和 Tag Data 组成。FLV 数据以大端序进行存储,在解析时需要注意。一个标准 FLV 文件结构如下图:
FLV 文件的详细内容结构如下:
Audio Tag Data
如果SoundFormat=10,那么音频数据就是AACAUDIODATA
AACAUDIODATA格式如下:
Video Tag Data
对于H.264数据来说,CodecID = 7
当CodecID = 7时,视频数据就是AVCVIDEOPACKET格式
AVCVIDEOPACKET格式如下:
如果 AVCPacketType = 0,那么Data就是AVCDecoderConfigurationRecord格式
AVCDecoderConfigurationRecord格式如下:
如果 AVCPacketType = 1,那么Data结构就简单多了
Script Tag Data
该类型Tag又通常被称为MetadataTag,会放一些关于FLV视频和音频的元数据信息如:duration、width、height等。通常该类型Tag会跟在FileHeader后面作为第一个Tag出现,而且只有一个。
结构如下图所示:
AMF包:第一个字节表示AMF包的类型
第一个AMF包:
第一个字节一般为0x02,表示字符串,第2-3个字节表示字符串的长度,一般为0x000A,后面跟的就是字符串,一般为"onMetaData"。
第二AMF包:
第一个字节为0x08,表示数组,第2-5个字节表示数组元素个数,后面跟着就是数组的元素,格式为:元素名长度(UI16)+ 元素名(UI8[n])+ 元素的值(double),最后以“009”结尾。
常见的数组元素:
6.2 测试 simplest_librtmp_sendflv.cpp
linux环境下简单修改
url改为自己的rtmp服务器
编译
gcc simplest_librtmp_sendflv.cpp -o simplest_librtmp_sendflv.out -I ../rtmpdump_dir/include/ -L ../rtmpdump_dir/lib/ -lrtmp
运行
./simplest_librtmp_sendflv.out
6.3 测试 simplest_librtmp_send264.cpp
linux环境简单修改
url改为自己的rtmp服务器
H264封装FLV时有个地方需要注意:SPS和PPS封装在一个Tag中
编译,测试代码用了c++,用g++编译
g++ simplest_librtmp_send264.cpp librtmp_send264.cpp -o simplest_librtmp_send264.out -I ../rtmpdump_dir/include/ -L ../rtmpdump_dir/lib/ -lrtmp
运行
./simplest_librtmp_send264.out
7、mark
rtmpdump函数调用框图