一、协议分层

  RTMP包是以Message的结构封装的,结构如下所示:

  

  

  1)Message Type ID在1-7的消息用于协议控制,这些消息一般是RTMP协议自身管理要使用的消息,用户一般情况下无需操作其中的数据。

    Message Type ID为8,9的消息分别用于传输音频和视频数据。Message Type ID为15-20的消息用于发送AMF编码的命令,负责用户与服务器之间的交互,比如播放,暂停等等。

  2)StreamID是音视频流的唯一ID, 一路流如果既有音频包又有视频包,那么这路流音频包的StreamID和他视频包的StreamID相同。

  

  一个Message大小不一,音频视频的Message往往差异较大,为了充分利用网络,需要将一个大的Message中的Body部分拆分到一个或者多个Chunk中

  Chunk结构:

  

  在拆分到多个Chunk中的时候,第一个Chunk携带完整的Message Header信息

  因为一个流当中可以传输多个Chunk,那么多个Chunk怎么标记同属于一个Message的呢?

  是通过Chunk Stream ID区分的,同一个Chunk Stream ID必然属于同一个Message

  

  SRS中的Chunk接收和拼接成Message的代码可以证明:

  

int SrsProtocol::recv_interlaced_message(SrsCommonMessage** pmsg)
{
int ret = ERROR_SUCCESS; // chunk stream basic header.
char fmt = 0;
int cid = 0;
if ((ret = read_basic_header(fmt, cid)) != ERROR_SUCCESS) {
if (ret != ERROR_SOCKET_TIMEOUT && !srs_is_client_gracefully_close(ret)) {
srs_error("read basic header failed. ret=%d", ret);
}
return ret;
}
srs_verbose("read basic header success. fmt=%d, cid=%d", fmt, cid); // the cid must not negative.
srs_assert(cid >= 0); // get the cached chunk stream.
SrsChunkStream* chunk = NULL; // use chunk stream cache to get the chunk info.
// @see https://github.com/ossrs/srs/issues/249
if (cid < SRS_PERF_CHUNK_STREAM_CACHE) {
// chunk stream cache hit.
srs_verbose("cs-cache hit, cid=%d", cid);
// already init, use it direclty
chunk = cs_cache[cid];
srs_verbose("cached chunk stream: fmt=%d, cid=%d, size=%d, message(type=%d, size=%d, time=%"PRId64", sid=%d)",
chunk->fmt, chunk->cid, (chunk->msg? chunk->msg->size : 0), chunk->header.message_type, chunk->header.payload_length,
chunk->header.timestamp, chunk->header.stream_id);
} else {
// chunk stream cache miss, use map.
if (chunk_streams.find(cid) == chunk_streams.end()) {
chunk = chunk_streams[cid] = new SrsChunkStream(cid);
// set the perfer cid of chunk,
// which will copy to the message received.
chunk->header.perfer_cid = cid;
srs_verbose("cache new chunk stream: fmt=%d, cid=%d", fmt, cid);
} else {
chunk = chunk_streams[cid];
srs_verbose("cached chunk stream: fmt=%d, cid=%d, size=%d, message(type=%d, size=%d, time=%"PRId64", sid=%d)",
chunk->fmt, chunk->cid, (chunk->msg? chunk->msg->size : 0), chunk->header.message_type, chunk->header.payload_length,
chunk->header.timestamp, chunk->header.stream_id);
}
}

  

红色的是以CID为key的一个Map,每次的第一个Chunk过来的时候,都缓存起来,下一个Chunk来了之后进行追加。

因为TCP的有序,所以同一个Message中不同的Chunk会先后抵达。

 

RTMP协议中的Chunk Stream ID (CID)的作用的更多相关文章

  1. (转载)RTMP协议中的AMF数据 http://blog.csdn.net/yeyumin89/article/details/7932585

    为梦飞翔   (转载)RTMP协议中的AMF数据 http://blog.csdn.net/yeyumin89/article/details/7932585 这里有一个连接,amf0和amf3的库, ...

  2. 视频直播源码开发中的流媒体协议:rtmp协议

    一.概念与摘要 视频直播源码的RTMP协议从属于应用层,被设计用来在适合的传输协议(如TCP)上复用和打包多媒体传输流(如音频.视频和互动内容).RTMP提供了一套全双工的可靠的多路复用消息服务,类似 ...

  3. RTMP协议中文翻译(首发)(转)

    Adobe公司的实时消息传输协议 摘要 此备忘录描述了 Adobe公司的实时消息传输协议(RTMP),此协议从属于应用层,被设计用来在适合的传输协议(如TCP)上复用和打包多媒体传输流(如音频.视频和 ...

  4. RTMP协议详解(转)

    转自<RTMP协议详解(一) (二) (三) > Real Time Messaging Protocol(实时消息传送协议协议)是Adobe Systems公司为Flash播放器和服务器 ...

  5. rtmp协议介绍

    概述: •tcp建立连接. •rtmp握手. •客户端与服务器对建立rtmp连接达成一致. •创建rtmp流 •客户端与服务器对play或者Publish达成一致. •客户端开始传送数据到服务器. • ...

  6. RTMP协议中文翻译(首发)

    翻译:阿宝 更新:2016-09-11 来源:彩色世界(https://blog.hz601.org/2016/07/03/real-time-messaging-protocol/index.htm ...

  7. (转)rtmp协议简单解析以及用其发送h264的flv文件

    Adobe公司太坑人了,官方文档公布的信息根本就不全,如果只按照他上面的写的话,是没法用的.按照文档上面的流程,server和client连接之后首先要进行握手,握手成功之后进行一些交互,其实就是交互 ...

  8. 直播推流实现RTMP协议的一些注意事项

    —— 2017-2-12 更新RTMP 协议整理了一下,包括rtmp 消息类型,rtmp 如何分块,rtmp分块例子. 用脑图整理了一下,使用Xmind 打开,URL: https://github. ...

  9. (转)RTMP协议从入门到放弃

    转载自:  http://blog.csdn.net/shangmingyang/article/details/50837852 RTMP协议是Real Time Message Protocol( ...

  10. RTMP协议分析及推流过程

    1.RTMP(实时消息传输协议)是Adobe 公司开发的一个基于TCP的应用层协议. 2.RTMP协议中基本的数据单元称为消息(Message). 3.当RTMP协议在互联网中传输数据的时候,消息会被 ...

随机推荐

  1. Java进行excel的导入导出操作

    excel表格的导出导入在业务中经常会遇到,下面介绍hutool和easyExcel两种操作excel的工具 测试的实体类 通过mybatis-plus生成的,用于导出数据的实体类 @Getter @ ...

  2. 《C# in depth》第6章C#6.0中的更改(十四)——表达式体

    表达式体成员是一种在C# 6及以上版本中引入的语法.它允许开发人员使用Lambda表达式来简化方法或属性的定义. 在使用表达式体成员时,可以将方法或属性的实现写在一个Lambda表达式中,然后直接返回 ...

  3. Python 潮流周刊#47:当你的老师希望你去做开源

    本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...

  4. 即学即会 Serverless | 初识 Serverless

    简介:Serverless 架构被越来越多的业务所采纳,成为其技术选型,大多数开发者已经跨越对 Serverless 概念了解,切实向落地实践出发.本文带大家一探究竟,为什么说 Serverless ...

  5. Go语言入门分享

    ​简介: Go语言出自Ken Thompson.Rob Pike和Robert Griesemer之手,起源于2007年,并在2009年正式对外发布.Go的主要目标是"兼具Python等动态 ...

  6. [FAQ] uni-app 如何让页面不展示返回箭头图标

    默认情况是,有历史上一页的 页面会在左上角展示返回图标. 比如登录页不想展示返回,在跳转进来时可以使用 uni.redirectTo({}),它能够关闭其它页面,这样当前页就不会有返回箭头了. Ref ...

  7. [Docker] 镜像源配置 for Linux

    $ vi /etc/docker/daemon.json { "registry-mirrors": [ "https://docker.mirrors.ustc.edu ...

  8. JS代码优化小技巧

    下面介绍一种JS代码优化的一个小技巧,通过动态加载引入js外部文件来提高网页加载速度 [基本优化] 将所有需要的<script>标签都放在</body>之前,确保脚本执行之前完 ...

  9. 解放双手!这个插件只要一张表就能生成CRUD代码

    大家好,我是 Java陈序员. 问君能有几多愁,代码一行又一行! 作为码农,代码是写不完的,而偷懒又是人的天性,能少干一点就少干一点. 今天,给大家介绍一个 IDEA 插件,帮助你快速生成出 CRUD ...

  10. 七、Doris Colocation Join

    Colocation Join 是在 Doris 0.9 版本中引入的新功能.旨在为某些 Join 查询提供本地性优化,来减少数据在节点间的传输耗时,加速查询. 1.基本理论 Join 的常见连接类型 ...