This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
完成的任务
- 阅读device.go代码,并将device的所有代码都进行了相应的注释,后续将会阅读项目的全部代码。扩展视野。
- 把OTA升级中的size通过head获取,然后重构了部分代码。
学习内容
-
观看了SDK文章中的架构设计,使我知道这块代码是做什么的,例如,系统架构主要分为三部分,平台、赛达SDK、设备厂商主程序。通过平台调用Grpc,将命令传递到SDK模块,SDK模块将命令下发到厂厂商,厂商将结果返回SDK,SDK将消息内容通过Grpc协议传递给平台(回调函数)。
-
RTMP: RTMP是基于TCP协议的实时消息传输协议(应用层协议)初步目的是为了解决FLash播放器中实时音视频传输问题,虽然目前Flash被逐渐淘汰,RTMP备受挑战,但是在很多的应用场景中RTMP依然是首选,例如实时互动场景等,即视频直播、视频会议、网络广播等。具体的流程为:在通过TCP建立链接后,RTMP协议也要客户端和服务端通过“HandShake”(握手)来建立基于传输层链接之上的RTMP Connection链接,在建立连接之后可以传输一些控制信息,例如SetChunkSize,SetACKWindowSize等。其中的CreateStream命令会创建一个Steam链接,用于具体音视频数据和控制命令。在进行数据传输时会进行格式化(RTMP Message),在传输的过程中为了更好的实现多路复用,分包和信息的公平性,发送端会将Message消息划分为带有Message ID的Chunk,每个Chunk可以是单独的一个Message,也可以是Message中的一部分。在接收端会根据Chunk中包含的Data的长度、id把chunk还原成完成的Message,从而实现消息的发送和接受,最后关闭链接释放内存。下面是RTMP的优势和特点。
-
低延时 RTMP提供了稳定的连接和较低的延迟,RTMP基于TCP协议,TCP能保证数据包的顺序和错误校正,即RTMP传输的音视频能够保持高质量不被丢包、
-
支持多种媒体类型 RTMP不仅支持音视频数据的传输,还可以传输其他类型的数据,包括文本,图像脚本数据等。
-
可扩展性和灵活性 RTMP可以在本身的基础上添加自定义的消息类型和控制命令来实现多种命令场景,它也有很强的灵活性,例如RTMP提供了一系列的控制命令,例如开始、停止流,发布、订阅流等,使得RTMP具有亏扩展性和灵活性。
2.1 RTMP数据单元(Message) 数据单元是RTMP传输以下信息的基本单位,用于封装音频、视频、命令和数据。每个数据单元都有独特的头部信息,用于描述数据的属性和格式。一个数据单元包含一下几个部分。
-
类型 主要分为·:音频数据,用于传输音频数据。视频数据,用于传输视频数据。数据消息,用于传输数据。控制消息,用于传输连接,发布,订阅,播放,停止等消息。
-
消息长度 数据单元的有效负载长度,以字节为单位。
-
时间戳 数据单元产生的时间,一般用来同步音视频播放和计算延迟。
-
流ID 标识数据单元所属的流,一个RTMP可以有多个并发的流
2.2 RTMP数据块(Chunk) 数据块是RTMP协议传输的基本单位,用与客户端和服务端之间传递数据单元。在传输的过程中·数据单元会被分成多个数据块,以便有效的利用网络带宽减少网络延迟,提高实时性,每个RTMP数据块包含下面的部分。
-
块头 块头包含了块类型、块长度、时间戳、流ID等信息。块头的长度块类型和所包含的字段
-
负载 实际的音视频数据片段或者控制信息。
根据格式类型,可分为四种格式,分别为:
-
类型0,包含了完整的块头信息,用于传输一个新的数据单元。(适用于新消息)
-
类型1,相比类型0省略了消息流ID(适用于同一流的后续消息)
-
类型2,相比类型1省略了消息长度和消息类型ID(适用同一流的同类型消息)
-
类型3,没有块头,表示与上一个数据块完全相同,仅负载部分内容不同
2.3 RTMP流控制和命令消息 RTMP支持多种流控制和命令消息,用于实现流媒体播放、暂停、拖动等功能,流控制消息用于控制数据流的传输,包括数据流的处理,调节流传输速度和同步视频等。下面是常见的命令消息。
-
connect:客户端想服务端发起请求,参数应包含应用名称、版本、支持的功能等等
-
createStream:客户端创建一个新的流
-
deleteStream:客户端删除一个流
-
closeStream:客户端关闭一个流
-
play:客户端请求播放流,参数应包含流名称、开始时间、结束时间、是否本地播放等。
-
pause::客户端请求暂停或者恢复播放
-
seek:客户端请求跳转到特定时间点
-
publish:客户端向服务端发布一个流,用于直播,参数一般包含流名称
-
onStatus:服务端向客户端发送状态信息,如播放开始、播放结束等。 流控制和命令消息通过RTMP的控制流(默认为流ID为0的流)进行传输,确保此消息的优先级高于音视频数据。
2.4 握手
一个RTMP的connection由握手开始,RTMP的握手是由三个固定长度的块组成,而不是向其他协议一样带有报文的可变长度块。首先客户端会向发送C0、C1、C2(按序发送)的三个Chunk,服务端向客户端发送S0、S1、S2(按序发送)的三个Chunk,才能握手成功。以下是握手顺序
-
客户端要等收到S1之后才能发送C2
-
客户端要等收到S2之后才能发送其他信息,例如命令消息和音视频数据
-
服务端要等到收到C0之后发送S1
-
服务端必须等到收到C1之后才能发送S2
-
服务端必须等到收到C2之后才能发送其他信息,例如命令消息和音视频数据
2.5 建立连接 (NetConnection)和从参数交换 在进行上诉的握手之后,客户端和服务端还要建立一个连接,用于音视频数据的传输和播放,以下是建立连接的主要流程
-
发送Connect命令,其中参数参数应包含应用名称、版本、支持的功能等等。
-
服务端响应,当服务端接受到Connect命令之后,会进行验证并返回一个“result”or“error”的响应消息。响应消息会包含一个事务ID,用于客户端和服务端之间的消息匹配,还会包含服务器的相关信息。
-
交换控制消息,在成功的建立连接之后,客户端和服务端可以相互发送控制消息,如Window Acknowledgement Size(窗口大小),设置Set Peer Bandwidth(对等带宽)等,
-
创建流:客户端在、建立连接后需要创建一个或者多个流,用于传输音频、视频或者数据。
在经过以上的步骤客户端和服务器可以开始进行音视频数据的传输和播放,目前只是初步了解RTMP的流程,后续会对每一快内容进行深入,以填补RTMP知识体系!
未完成的任务
还没有完全的观看SDserver项目的代码,没有对项目有一个非常清楚的认知,目前就知道SDK相关的内容。