流媒体:RTMP 命令消息与流管理

at 10个月前  ca 网络协议  pv 302  by touch  

  • 背景

上文中我们详细介绍了 RTMP(Real Time Messaging Protocol) 的规格及关键组成部分,这一章我们来讲解 RTMP 怎样通过命令消息,来进行实际的C-S交互控制。需要注意的是,命令消息的格式依然和上文中的统一格式一致。这里的区别主要是指携带数据(即消息体)的不同。

一、命令消息

C-S端用AMF编码后的命令消息,来进行对整个 RTMP 流程的控制。命令消息是链接成功建立后,推拉流及相关操作的关键控制手段。因此,通常会根据所处理业务,携带相应的关键数据。同时由于是对流程的管理手段,相应命令往往也需要对端对结果进行回应。这类回应消息,通过 Transaction ID 来标记被回应的方法,并通过固定的命名格式来进行约束:

[ 命令消息 ] + _result 或者 [ 命令消息 ] + _error

Transaction ID 被称为 事务ID,用来标记响应所指向的命令。这个用法类似于 IMAP 和其他类型协议中的应答标识位用法。

命令消息主要分为两种类型:

  1. NetConnection:网络连接命令,用来管理 C-S 间双向链接,并提供远程方法异步调用。

  2. NetStream:数据流命令,被用来管理 音视频流 和 数据通道 相关的管理和业务操作。

接下来我们来分别看一下这两者。

二、网络连接命令 NetConnection

网络连接命令,主要有方法如下:

流媒体:RTMP 命令消息与流管理 网络协议 第1张

connect 指令

connect 指令是由客户端发给服务器端,用来获取一个可用于建立对端通信的服务端应用实例的一个指令。指令分为请求指令 connect 和 应答指令 connect_result。

请求指令主要由4部分数据组成:

流媒体:RTMP 命令消息与流管理 网络协议 第2张

应答指令主要由4部分数据组成:

流媒体:RTMP 命令消息与流管理 网络协议 第3张

对于 connect 请求/应答指令,可用于连接配置的参数如下:

流媒体:RTMP 命令消息与流管理 网络协议 第4张

显而易见,可配置参数里,音视频编解码格式及一些规格化的属性,是由 RTMP 规范了配置标准的。主要是对 audioCodecs、videoCodecs、videoFunction、objectionEncoding进行了规范。我们依次来看一下:

流媒体:RTMP 命令消息与流管理 网络协议 第5张
流媒体:RTMP 命令消息与流管理 网络协议 第6张
流媒体:RTMP 命令消息与流管理 网络协议 第7张
流媒体:RTMP 命令消息与流管理 网络协议 第8张

这些规定好的类型能够覆盖大部分使用情况。但是如果发现没有,例如我打算使用 H.265 进行视频编码,那么就需要双端在原有协议上进行扩展实现了。

call 指令

指令发送端通过call 指令,来调用对端的 Remote Procedure Calls(即远程程序调用 RPC),来执行对端指定的方法或处理过程,获取结果返回。具体程序需要独立实现。指令分为请求指令 call 和 应答指令 call_result。

请求指令主要由4部分数据组成:

流媒体:RTMP 命令消息与流管理 网络协议 第9张

应答指令主要由4部分数据组成:

流媒体:RTMP 命令消息与流管理 网络协议 第10张

close 指令

close 指令在官方的 RTMP 规格说明文档中并未公开,如用到需要双端协定。(这个指令貌似是专门针对 Flash Media Player 流媒体处理上的一则资源协同释放的指令,如果不用 Flash Media Player 的话,貌似并不需要用到)

createStream 指令

createStream 指令是由C端发送给S端,来通知服务端建立一个能够进行音视频数据及相关元数据传输的流媒体信道。服务端在收到客户端的 createStream 请求,会在信道创建成功后,向客户端发送应答指令,告知客户端当前用来做数据传输的 ms_id ( Message Stream ID)。指令分为请求指令 createStream 和 应答指令 createStream_result。

通过 createStream 拿到的 ms_id 代表着一个成功建立的 NetConnection 对象的实例。具体 id 由双端协定,默认为 0。同一时间,我们可以开启多个信道来分别传输不同的数据。

请求指令主要由3部分数据组成:

流媒体:RTMP 命令消息与流管理 网络协议 第11张

应答指令主要由4部分数据组成:

流媒体:RTMP 命令消息与流管理 网络协议 第12张

releaseStream 指令

releaseStream 指令是由C端发送给S端,在C端作为推流方,用来在推流结束时通知服务端销毁当前数据信道分配的资源的命令。分请求指令 releaseStream 和 应答指令 releaseStream_result。

请求指令主要由4部分数据组成:

流媒体:RTMP 命令消息与流管理 网络协议 第13张

应答指令主要由3部分数据组成:

流媒体:RTMP 命令消息与流管理 网络协议 第14张

三、数据流命令 NetStream

数据流命令是在数据信道建立完毕后,用来对音视频数据流进行直接控制的命令类型。这些命令作用于当前信道对应数据的操控行为。常用的命令有一下几个:

流媒体:RTMP 命令消息与流管理 网络协议 第15张

数据流命令的请求命令所对应的应答命令,被统一命名为 “onStatus” 以描述数据所处的状态发生变更,因此具有统一的格式:

流媒体:RTMP 命令消息与流管理 网络协议 第16张

因此,我们通过处理 NetStream 的应答指令的 ‘level’ 和 ’code’ 字段,就可以知道相应的请求指令是否有成功执行了。进而判断当前状态,并确认是否需要执行后续的操作流程。

这一部分的命令就很明显存在制式化。因此就直接列出参数说明了。

当 error 发生时,除了 onStatus 异常外,还会返回 [方法名]_error 消息返回,这个也是一致的。

play 指令

流媒体:RTMP 命令消息与流管理 网络协议 第17张

play2 指令

流媒体:RTMP 命令消息与流管理 网络协议 第18张

deleteStream 指令

流媒体:RTMP 命令消息与流管理 网络协议 第19张

注意:这个消息只用来通知服务器,没有统一应答返回。

closeStream 指令

流媒体:RTMP 命令消息与流管理 网络协议 第20张

receiveAudio 指令

流媒体:RTMP 命令消息与流管理 网络协议 第21张

注意:
如果,Bool Flag = false 这个消息只用来通知服务器,没有统一应答返回。
如果,Bool Flag = true则应答消息’code’为 NetStream.Seek.Notify 或 NetStream.Play.Start

receiveVideo 指令

流媒体:RTMP 命令消息与流管理 网络协议 第22张

注意:
如果,Bool Flag = false 这个消息只用来通知服务器,没有统一应答返回。
如果,Bool Flag = true则应答消息’code’为 NetStream.Seek.Notify 或 NetStream.Play.Start

publish 指令

流媒体:RTMP 命令消息与流管理 网络协议 第23张

注意:
publish 的返回状态 NetStream.Publish.Start,这个消息不止由 onStatus 统一应答携带,也会由 onFCPublish 返回。

其实RTMP 是有 unpublish 方法的,相应触发状态为 NetStream.Unpublish.Success,同样也会由除 onStatus 外的 onFCUnpublish 返回。不过这个方法通常都被我们以 releaseStream 直接涵盖过去了。且 RTMP 公开的规格文档里并没有描述,因此一般不用。

seek 指令

流媒体:RTMP 命令消息与流管理 网络协议 第24张

注意:seek 成功后,会有 ’code’ 为 NetStream.Seek.Notify 消息返回。

pause 指令

流媒体:RTMP 命令消息与流管理 网络协议 第25张

注意:
pause 成功后,会有 ’code’ 为 NetStream.Pause.Notify 消息返回。
unpause 成功后,会有 ’code’ 为 NetStream.Unpause.Notify 消息返回。

四、总结

至此,RTMP 命令消息的详细规格说明,以及 RTMP 连接过程的命令控制,就讲解完毕了。结合上一篇:《流媒体:RTMP 协议全面解析》,我们基本上梳理了整个 RTMP 的全部关键节点。剩下的就需要实操实践啦~

希望能对你有所帮助~

参考文献:
[1] RTMP 官方规范(https://www.adobe.com/devnet/rtmp.html

转载: https://zhuanlan.zhihu.com/p/196743129

版权声明

本文仅代表作者观点,不代表码农殇立场。
本文系作者授权码农殇发表,未经许可,不得转载。

 

扫一扫在手机阅读、分享本文

已有0条评论