首页 > 其他分享 >ZLMediaKit学习记录--RTMP

ZLMediaKit学习记录--RTMP

时间:2023-07-24 14:44:21浏览次数:79  
标签:ZLMediaKit -- inputFrame MSG RtmpSession RTMP onCmd size

第二次看ZLMediaKit部分的记录,有许多理解错误的地方,将进一步整理。

cd /opt/ZLMediaKit

mkdir build

cd build

cmake .. -DENABLE_WEBRTC=true -DOPENSSL_ROOT_DIR=/opt/openssl -DOPENSSL_LIBRARIES=/opt/openssl/lib

cmake --build . --target MediaServer

cd /opt/ZLMediaKit/release/linux/Debug

./MediaServer

e:

cd e:\Demo\CGAvioRead\Debug

ffmpeg -re -stream_loop -1 -i d:/H264_AAC_2021-02-10_1080P.mp4 -vcodec copy -acodec copy -f flv -y rtmp://10.10.14.103:1935/live/Camera_00002

ffmpeg -re -stream_loop -1 -i d:/H264_AAC_2021-02-10_1080P.mp4 -vcodec copy -acodec copy -f flv -y rtmp://192.168.0.107:1935/live/Camera_00002

ffmpeg -re -stream_loop -1 -i e:/H264_AAC_2021-02-10_1080P.mp4 -vcodec copy -acodec copy -f rtsp -rtsp_transport tcp rtsp://10.10.15.30:554/live/Camera_00001

1. RtmpSession::onRecv

onParseRtmp

2. RtmpProtocol::onParseRtmp

input(data, size)

3. HttpRequestSplitter::input

(index = onSearchPacketTail(ptr,_remain_data_size)) != nullptr)

4. RtmpProtocol::onSearchPacketTail

构造函数:

_next_step_func = [this](const char *data, size_t len) {

return handle_C0C1(data, len);

};

auto ret = next_step_func(data, len);

5. RtmpProtocol::handle_C0C1

if (data[0] != HANDSHAKE_PLAINTEXT)

对C0的判断,为0x03

handle_C1_complex(data);

编译时ENABLE_OPENSSL打开。

6. RtmpProtocol::handle_C1_complex

C1的方式为schema1:

c1s1 schema0

time: 4bytes

version: 4bytes

digest: 764bytes

key: 764bytes

RtmpProtocol::get_C1_digest() //skip c0,time,version

得到digest,764bytes digest结构:

offset: 4bytes

random-data: (offset)bytes

digest-data: 32bytes

random-data: (764-4-offset-32)bytes

check_C1_Digest:验证digest.

Send_complex_S0S1S2(1, digest);

7. RtmpProtocol::send_complex_S0S1S2

(1)//发送S0

char handshake_head = HANDSHAKE_PLAINTEXT;

onSendRawData(obtainBuffer(&handshake_head, 1));

(2)//发送S1

memcpy(s1.zero, "\x04\x05\x00\x01", 4);为版本号

c1s1 schema1

time: 4bytes

version: 4bytes

digest: 764bytes

key: 764bytes

get_C1_digest(s1.random, &digestPos);

//将digest加入,并发送

memcpy(digestPos, s1_digest.data(), s1_digest.size());

onSendRawData(obtainBuffer((char *) &s1, sizeof(s1)));

(3)//发送S2

生成key和digest,然后发送。

(4)等待C2

handle_C2(data, len)

8. RtmpProtocol::handle_C2

未过多进行处理。握手结束,进入命令模。

9. RtmpProtocol::handle_rtmp

(1)static constexpr size_t HEADER_LENGTH[] = {12, 8, 4, 1};

auto header_len = HEADER_LENGTH[header->fmt];

得到RTMP header的长度。

(2) switch (_now_chunk_id)

对编码块流进一步处理。ID 0、1、2作为保留。0,两个字节表示,第一个字节+64;1,三个字节表示,(第三个字节) * 256 + 第二个字节 + 64);2表示低层协议消息。3-63,表示完整的流ID。这个switch一般不会走到。

(3)handle_chunk(std::move(now_packet));

10. RtmpProtocol::handle_chunk

(1)RtmpPacket中的变量

bool is_abs_stamp;

uint8_t type_id;

uint32_t time_stamp;

uint32_t ts_field;

uint32_t stream_index;

uint32_t chunk_id;

size_t body_size;

toolkit::BufferLikeString buffer;

bool is_abs_stamp;

uint8_t type_id;

uint32_t time_stamp;

uint32_t ts_field;

uint32_t stream_index;

uint32_t chunk_id;

size_t body_size;

toolkit::BufferLikeString buffer;

(2)MSG_SET_CHUNK

type_id:1,body_size:4

来表示chunk_size的长度,如ea 60:60000

(3) MSG_WIN_SIZE

type_id:5,body_size:4

这个在播放时为发送。这个值应在32 * 1024U-1280 * 1024U之间。客户端收到大于这个字节的数据,要向服务器发送ACK消息。

(4) MSG_SET_PEER_BW

type_id:6,body_size:5

4个字节的字节的大小,1个字节的类型。未调试到。

(5)MSG_AGGREGAT

将包含子包的进行拆分。未调试到。

(6)MSG_USER_CONTROL

未调试到。包含有多一个事件信息,从代码来看,一般前2个字节是事件的类型,接着的4个字节是内容。

(7)MSG_ACK

Acknowledgement。确认信息。未进行过多的处理。

(8)其他的消息

  • 收到设定的字节,回复确认信息。
  • 基他的交由onRtmpChunk处理。

11. RtmpSession::onRtmpChunk

分为三种类型处理:

  1. MSG_CMD、MSG_CMD3由onProcessCmd(12)处理。
  2. MSG_DATA、MSG_DATA3由(13)解析。
  3. MSG_AUDIO、MSG_VIDEO由(14)解析。

12. RtmpSession::onProcessCmd

与RTSP的实现方法一样。处理下列命令:

  1. RtmpSession::onCmd_connect--15
  2. RtmpSession::onCmd_createStream--16
  3. RtmpSession::onCmd_publish--17
  4. RtmpSession::onCmd_deleteStream--18
  5. RtmpSession::onCmd_play--19
  6. RtmpSession::onCmd_play2--20
  7. RtmpSession::onCmd_seek--21
  8. RtmpSession::onCmd_pause--22
  9. RtmpSession::onCmd_playCtrl--23

13. MSG_DATA、MSG_DATA3

推流时会处理。执行setMetaData(dec);得到推流源的metadata数据。

标签:ZLMediaKit,--,inputFrame,MSG,RtmpSession,RTMP,onCmd,size
From: https://www.cnblogs.com/zeliangzhang/p/17577206.html

相关文章

  • zookeeper部署
    下载官网路径:https://dlcdn.apache.org/zookeeper/单机部署#解压tar-zxfapache-zookeeper-3.8.1.tar.gz#进入配置文件目录cdapache-zookeeper-3.8.1/conf#拷贝模板文件cp-azoo_sample.cfgzoo.cfg#编辑文件vimzoo.cfg    tickTime=2000    initL......
  • php运算符
    1、松散比较和严格比较松散比较:使用两个等号 == 比较,只比较值,不比较类型。严格比较:用三个等号 === 比较,除了比较值,也比较类型。2、类型转换(1)字符串参与比较时,自动转为数值类型,比如'12'==12.03、php支持++和--4、运算符对数值运算的处理5、支持三元运算符6、逻辑运......
  • AT_abc218_d 题解
    洛谷链接&Atcoder本篇题解为此题较简单做法及较少码量,并且码风优良,请放心阅读。题目简述给定一个平面内的\(N\)个点的坐标,求这\(N\)个点中选\(4\)个点可构成正方形的方案数。注:构成的正方形的边需平行于\(x\)轴或\(y\)轴。例如下图就不符合要求,则不考虑这种情况:......
  • php控制结构
    1、if结构if(条件){if条件成立时执行的代码;}elseif(条件){elseif条件成立时执行的代码;}else{条件不成立时执行的代码;}2、switch<?phpswitch(n){caselabel1:如果n=label1,此处代码将执行;break;caselabel2:如果n=label2,此......
  • 560. 和为 K 的子数组(前缀和解决子串问题)
    给你一个整数数组nums和一个整数k,请你统计并返回该数组中和为k的连续子数组的个数。示例1:输入:nums=[1,1,1],k=2输出:2>思路每个元素对应一个“前缀和”遍历数组,根据当前“前缀和”,在map中寻找「与之相减==k」的历史前缀和当前“前缀和”与历史前缀和......
  • Linux系列---【CentOS 7通过MSTSC连接远程桌面】
    安装对应的yum源yumlistlightdmxorgxrdpxrdp可以看到这些软件都在epel中,如果没有的话,请先安装对应的yum源。命令如下:yuminstall-yepel-release确认yum源没有问题之后,我们就可以进行安装了。安装lightdmxorgxrdpxrdplightdm提供了图形登录界面和用户会话管理......
  • AT_abc215_d 题解
    洛谷链接&Atcoder链接本篇题解为此题较简单做法及较少码量,并且码风优良,请放心阅读。题目简述给定\(N\),\(M\)及含有\(N\)个整数的序列\(A\)。求\(1\simM\)中与所有\(a_i\)均互质的整数及个数。思路首先说一下最开始的想法。直接暴力枚举\(1\simM\)的数,再分......
  • 直播系统搭建,波浪文字效果
    直播系统搭建,波浪文字效果 <template><view:style="{background:loadingType==='font'?'#fff':''}"v-if="show"><view:style="{'margin-top':loadingType==='font'?'-......
  • 通信猫 共享MQTT服务器 在线客户端连接失败
    解决方法使用官方mqtt链接工具(只支持TCP协议)需要有vs2013的dll文件支持,下载连接__官方下载链接,引用自http://www.tongxinmao.com/txm/webmqtt.php正常使用ws协议端口18832连接,控制台输出如下:使用WS协议连接ws协议端口18832,链接失败使用页面客户端工具连接TCP,查看控......
  • 传奇架设时传奇出现黑屏、卡屏不动是怎么回事?
    在写这篇文章之前,先给给大家说一下,这篇文章写的是出现黑屏、卡屏不动是我们玩传奇的时候出现的,而不是在架设传奇时候出现的,所以要特别是注意一下,架设和玩出现黑屏是完全不一样的,所以解决方案也不一样。有关架设传奇出现黑屏的问题,这个我会在之后的文章会告诉大家怎么解决。在告诉提......